1use crate::track::Track;
2use std::{
3 cell::UnsafeCell,
4 collections::HashMap,
5 fmt,
6 marker::PhantomData,
7 ops::{Deref, DerefMut},
8 sync::Arc,
9};
10
11pub type TrackHandle = Arc<Track>;
12pub type StateSlot = arc_swap::ArcSwap<StateSnapshot>;
13
14pub struct State {
15 inner: UnsafeCell<StateData>,
16}
17
18#[derive(Default, Debug)]
19pub struct StateData {
20 pub tracks: HashMap<String, TrackHandle>,
21}
22
23pub struct StateGuard<'a> {
24 ptr: *mut StateData,
25 _marker: PhantomData<&'a mut StateData>,
26}
27
28unsafe impl Send for StateGuard<'_> {}
29
30unsafe impl Sync for State {}
35
36impl Default for State {
37 fn default() -> Self {
38 Self {
39 inner: UnsafeCell::new(StateData::default()),
40 }
41 }
42}
43
44impl fmt::Debug for State {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 f.debug_struct("State")
47 .field("tracks", &self.tracks)
48 .finish()
49 }
50}
51
52impl Deref for State {
53 type Target = StateData;
54
55 fn deref(&self) -> &Self::Target {
56 unsafe { &*self.inner.get() }
57 }
58}
59
60impl DerefMut for State {
61 fn deref_mut(&mut self) -> &mut Self::Target {
62 self.inner.get_mut()
63 }
64}
65
66impl StateData {
67 pub fn snapshot(&self) -> StateSnapshot {
68 StateSnapshot {
69 tracks: self.tracks.clone(),
70 }
71 }
72}
73
74impl Deref for StateGuard<'_> {
75 type Target = StateData;
76
77 fn deref(&self) -> &Self::Target {
78 unsafe { &*self.ptr }
79 }
80}
81
82impl DerefMut for StateGuard<'_> {
83 fn deref_mut(&mut self) -> &mut Self::Target {
84 unsafe { &mut *self.ptr }
85 }
86}
87
88#[derive(Clone, Default, Debug)]
89pub struct StateSnapshot {
90 pub tracks: HashMap<String, TrackHandle>,
91}
92
93impl State {
94 pub fn lock(&self) -> StateGuard<'_> {
95 StateGuard {
96 ptr: self.inner.get(),
97 _marker: PhantomData,
98 }
99 }
100
101 pub fn snapshot(&self) -> StateSnapshot {
102 StateData::snapshot(self)
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[test]
111 fn state_default_creates_empty() {
112 let state = State::default();
113 assert!(state.lock().tracks.is_empty());
114 }
115
116 #[test]
117 fn state_debug_format() {
118 let state = State::default();
119 let debug_str = format!("{:?}", state);
120 assert!(debug_str.contains("State"));
121 assert!(debug_str.contains("tracks"));
122 }
123
124 #[test]
125 fn state_new_is_default() {
126 let state1 = State::default();
127 let state2 = State::default();
128 assert_eq!(state1.lock().tracks.len(), state2.lock().tracks.len());
129 }
130
131 #[test]
132 fn state_snapshot_clones_track_handles() {
133 let state = State::default();
134 let track = Arc::new(Track::new("track".to_string(), 1, 1, 0, 0, 64, 48_000.0));
135 state
136 .lock()
137 .tracks
138 .insert("track".to_string(), track.clone());
139
140 let snapshot = state.snapshot();
141
142 assert!(Arc::ptr_eq(snapshot.tracks.get("track").unwrap(), &track));
143 }
144}