1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
use crate::HitError; use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; pub struct Listeners<T>(HashMap<String, Vec<FieldListenerRef<T>>>); impl<T> Listeners<T> { pub fn new() -> Self { Listeners(HashMap::new()) } fn get_or_create_property_listeners( &mut self, property: &str, ) -> &mut Vec<FieldListenerRef<T>> { self.0.entry(property.to_string()).or_insert(vec![]) } fn get_property_listeners_mut( &mut self, property: &str, ) -> Option<&mut Vec<FieldListenerRef<T>>> { self.0.get_mut(property) } pub fn insert(&mut self, property: &str, value: FieldListenerRef<T>) { let listeners = self.get_or_create_property_listeners(property); listeners.push(value); } pub fn remove(&mut self, property: &str, listener_id: &str) -> Result<(), HitError> { let listeners = self .get_property_listeners_mut(property) .ok_or(HitError::ListenerNotFound(listener_id.to_string()))?; listeners.retain(|listener2| listener2.borrow().get_unique_id() != listener_id); Ok(()) } pub fn dispatch_value(&mut self, property: &str, value: &T) { match self.get_property_listeners_mut(property) { Some(listeners) => { for listener in listeners.iter_mut() { listener.borrow_mut().on_update(value); } } None => {} } } } pub type FieldListenerRef<T> = Rc<RefCell<dyn FieldListener<T>>>; pub trait FieldListener<T> { fn on_update(&mut self, value: &T); fn get_unique_id(&self) -> &str; }