use std::any::Any;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::Mutex;
pub struct Property<T>
where
T: Sized + Copy,
{
v: Mutex<T>,
#[allow(clippy::type_complexity)]
listeners: Mutex<HashMap<String, (Box<dyn Fn(T, &dyn Any)>, Box<dyn Any>)>>,
}
impl<T> Property<T>
where
T: Sized + Copy,
{
pub fn get(&self) -> T {
if let Ok(v) = self.v.lock() {
return *v;
}
panic!("Other thread panic");
}
pub fn set(&self, t: T) {
if let Ok(mut v) = self.v.lock()
&& let Ok(listeners) = self.listeners.lock()
{
*v = t;
for i in listeners.values() {
(i.0)(*v, i.1.as_ref());
}
}
}
#[allow(clippy::type_complexity)]
pub fn listen(&self, id: &str, f: Box<dyn Fn(T, &dyn Any)>, data: Box<dyn Any>) {
if let Ok(mut listeners) = self.listeners.lock() {
listeners.insert(id.to_string(), (f, data));
}
}
pub fn hang_up(&self, id: &str) {
if let Ok(mut listeners) = self.listeners.lock() {
listeners.remove(id);
}
}
}
impl<T> Property<T>
where
T: Sized + Copy,
{
pub fn new(v: T) -> Rc<Self> {
Rc::new(Self {
v: Mutex::new(v),
listeners: Mutex::new(HashMap::new()),
})
}
}