yuno 0.2.1

Multimedia UI layout and rendering framework powered by Skia.
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()),
        })
    }
}