feagi_data_structures/
feagi_signal.rs1use std::collections::HashMap;
2use std::fmt::Debug;
3use crate::{define_index, FeagiDataError};
4
5define_index!(FeagiSignalIndex, u32, "A unique identifier for a subscription to a FeagiSignal");
6
7pub struct FeagiSignal<T> { listeners: HashMap<FeagiSignalIndex, Box<dyn Fn(&T) + Send + Sync>>,
9 next_index: u32,
10}
11
12
13impl<T> FeagiSignal<T> {
14 pub fn new() -> Self {
15 Self { listeners: HashMap::new(), next_index: 0 }
16 }
17
18 pub fn connect<F>(&mut self, f: F) -> FeagiSignalIndex where
20 F: Fn(&T) + Send + Sync + 'static,
21 {
22 self.listeners.insert(self.next_index.into(), Box::new(f));
23 self.next_index += 1;
24 (self.next_index - 1).into()
25 }
26
27 pub fn disconnect(&mut self, index: FeagiSignalIndex) -> Result<(), FeagiDataError> {
28 if self.listeners.remove(&index).is_some() {
29 return Ok(())
30 }
31 Err(FeagiDataError::BadParameters(format!("No subscription found with identifier {}!", index)))
32 }
33
34 pub fn emit(&self, value: T) {
35 for f in &self.listeners {
36 f.1(&value);
37 }
38 }
39}
40
41impl<T> Debug for FeagiSignal<T> {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 f.debug_struct("FeagiSignal")
44 .field("listener_count", &self.listeners.len())
45 .field("next_index", &self.next_index)
46 .field("listener_indices", &self.listeners.keys().collect::<Vec<_>>())
47 .finish()
48 }
49}