gooey/presentation/fmod/
remote.rs1use std::sync;
4use unbounded_spsc;
5
6use crate::interface::{self, view, View};
7use crate::tree::{NodeId, Tree};
8use super::{Audio, Presentation};
9
10#[expect(clippy::type_complexity)]
12static DISPLAY_RECEIVER : sync::LazyLock <
13 sync::Mutex <Option <unbounded_spsc::Receiver <Vec <(NodeId, view::Display)>>>>
14> = sync::LazyLock::new (|| sync::Mutex::new (None));
15
16#[derive(Debug)]
18pub struct Remote {
19 display : unbounded_spsc::Sender <Vec <(NodeId, view::Display)>>,
20}
21
22pub struct Fmod {
24 pub inner : super::Fmod,
25 updates : unbounded_spsc::Receiver <Vec <(NodeId, view::Display)>>,
26 display_counter : u64,
28 frame : u64
30}
31
32impl Default for Remote {
33 fn default() -> Self {
34 let display = {
35 let (sender, receiver) =
36 unbounded_spsc::channel::<Vec <(NodeId, view::Display)>>();
37 {
38 let mut display_receiver_lock = DISPLAY_RECEIVER.lock().unwrap();
39 debug_assert!(display_receiver_lock.is_none());
40 *display_receiver_lock = Some (receiver);
41 }
42 sender
43 };
44 Remote {
45 display
46 }
47 }
48}
49
50impl Audio for Remote { }
51impl Presentation for Remote {
52 fn with_root (root : View, root_id : NodeId) -> Self {
53 let remote = Self::default();
54 log::debug!("fmod remote with root: {remote:?}");
55 remote.display.send (vec![(
56 root_id.clone(),
57 view::Display::Create (root, root_id, interface::CreateOrder::Append)
58 )]).unwrap();
59 remote
60 }
61
62 fn get_input (&mut self, _ : &mut Vec <view::Input>) { }
63
64 fn display_view <V : AsRef <View>> (&mut self,
65 _view_tree : &Tree <V>,
66 display_values : std::vec::Drain <(NodeId, view::Display)>
67 ) {
68 self.display.send (display_values.collect()).unwrap();
69 }
70}
71
72impl Fmod {
73 pub fn init() -> Self {
74 let inner = super::Fmod::default();
75 let updates = loop {
76 let maybe_receiver = (*DISPLAY_RECEIVER).lock().unwrap().take();
77 if let Some (receiver) = maybe_receiver {
78 break receiver
79 }
80 std::thread::sleep (std::time::Duration::from_millis (100));
81 };
82 Fmod {
83 inner,
84 updates,
85 display_counter: 0,
86 frame: 0
87 }
88 }
89
90 #[inline]
91 pub const fn display_counter (&self) -> u64 {
92 self.display_counter
93 }
94
95 #[inline]
96 pub const fn reset_display_counter (&mut self) {
97 self.display_counter = 0;
98 }
99
100 pub fn process_display_events (&mut self) {
101 while let Ok (updates) = self.updates.try_recv() {
103 for (node_id, display) in updates {
104 self.inner.display_value (node_id, display);
105 }
106 self.display_counter += 1;
107 }
108 }
109
110 pub fn update_audition (&mut self) {
111 self.inner.audition.update();
112 self.frame += 1;
113 }
114
115 pub fn display (&mut self) {
117 log::trace!("fmod remote display...");
118 self.process_display_events();
119 self.update_audition();
120 log::trace!("...fmod remote display");
121 }
122}