use std::{ any::{Any, TypeId}, collections::HashMap, sync::{Arc, Mutex}, }; use crate::View; pub trait Event { fn as_any(&self) -> &dyn Any; } impl<'a> dyn Event + 'a { pub fn get(&self) -> Option<&T> { self.as_any().downcast_ref() } } pub type Component = Arc) -> View + Send + Sync>; pub type EventHandler = Arc, &dyn Event) + Send + Sync>>; pub struct Context { component: Mutex, event_handlers: Mutex>>, view: Mutex, } impl Context { pub fn new) -> View + Send + Sync + 'static>(component: F) -> Arc { Arc::new(Self { component: Mutex::new(Arc::new(component)), event_handlers: Mutex::new(HashMap::new()), view: Mutex::new(Arc::new(|_| {})), }) } pub fn refresh(self: &Arc) { let c = self.component.lock().unwrap().clone(); *self.view.lock().unwrap() = (c)(self); } pub fn get_view(self: &Arc) -> View { self.view.lock().unwrap().clone() } pub fn on_event, &T) + Send + Sync + 'static>( self: &Arc, handler: F, ) { self.event_handlers .lock() .unwrap() .entry(TypeId::of::()) .or_insert_with(|| Vec::new()) .push(Arc::new(Mutex::new( move |ctx: &Arc, event: &dyn Event| { if let Some(e) = event.get::() { (handler)(ctx, e); } }, ))); } pub fn emit_event(self: &Arc, event: &E) { if let Some(v) = self.event_handlers.lock().unwrap().get(&TypeId::of::()) { for i in v { (i.lock().unwrap())(self, event); } } } pub fn emit_event_threaded( self: &Arc, event: &E, ) { if let Some(v) = self.event_handlers.lock().unwrap().get(&TypeId::of::()) { for i in v { let i = i.clone(); let event = event.clone(); let s = self.clone(); std::thread::spawn(move || { (i.lock().unwrap())(&s, &event); }); } } } }