diff --git a/src/component/context.rs b/src/component/context.rs index 17c7a17..b8751f5 100644 --- a/src/component/context.rs +++ b/src/component/context.rs @@ -19,7 +19,7 @@ use super::{scope::Scope, Component, ComponentImpl}; pub struct Context { component: AccessCell, view: AccessCell, - event_handlers: Mutex>>, + event_handlers: AccessCell>>, pub(crate) scopes: Mutex>>, executor: Arc, } @@ -32,14 +32,15 @@ impl Context { Arc::new(Self { component: AccessCell::new(Arc::new(component)), view: AccessCell::new(Arc::new(|_| {})), - event_handlers: Mutex::new(HashMap::new()), + event_handlers: AccessCell::new(HashMap::new()), scopes: Mutex::new(Vec::new()), executor, }) } pub fn refresh(self: &Arc) { - self.event_handlers.lock().unwrap().clear(); + self.event_handlers + .access(|event_handlers| event_handlers.clear()); self.component.access({ let s = self.clone(); move |component| { @@ -53,10 +54,11 @@ impl Context { } pub fn refresh_sync(self: &Arc) { - self.event_handlers.lock().unwrap().clear(); - let (tx, rx) = std::sync::mpsc::channel::<()>(); + self.event_handlers + .access(|event_handlers| event_handlers.clear()); + self.component.access({ let s = self.clone(); move |component| { @@ -85,30 +87,37 @@ impl Context { 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 Any| { - if let Some(e) = event.downcast_ref::() { - (handler)(ctx, e); - } - }, - ))); + let new_handler: EventHandler = Arc::new(Mutex::new( + move |ctx: &Arc, event: &dyn Any| { + if let Some(e) = event.downcast_ref::() { + (handler)(ctx, e); + } + }, + )); + self.event_handlers.access(|event_handlers| { + event_handlers + .entry(TypeId::of::()) + .or_insert_with(Vec::new) + .push(new_handler); + }); } - 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(self: &Arc, event: E) { + let event = Arc::new(event); + let handlers_to_call: Vec = { + let guard = self.event_handlers.access_ref(); + guard + .get(&TypeId::of::()) + .cloned() + .unwrap_or_default() + }; + for h in &handlers_to_call { + (h.lock().unwrap())(self, event.as_ref()); } for scope in self.scopes.lock().unwrap().iter() { for (child, _) in scope.children.lock().unwrap().iter() { - child.emit_event(event); + child.emit_event(event.clone()); } } } @@ -117,15 +126,19 @@ impl Context { 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); - }); - } + let handlers_to_call: Vec = { + let guard = self.event_handlers.access_ref(); + guard + .get(&TypeId::of::()) + .cloned() + .unwrap_or_default() + }; + for h in handlers_to_call { + let event = event.clone(); + let s = self.clone(); + std::thread::spawn(move || { + (h.lock().unwrap())(&s, &event); + }); } for scope in self.scopes.lock().unwrap().iter() { diff --git a/src/state.rs b/src/state.rs index fae81c6..15f7631 100644 --- a/src/state.rs +++ b/src/state.rs @@ -192,7 +192,7 @@ pub fn use_sync_state< pub fn use_sync_effect< T: Send + Sync + 'static, - Ev: 'static, + Ev: Send + Sync + 'static, E: Fn(&State) -> Ev + Send + Sync + 'static, >( cx: &Arc, @@ -205,7 +205,8 @@ pub fn use_sync_effect< let state = state.clone(); let cx = cx.clone(); move || { - cx.emit_event(&encoder(&state)); + let ev = encoder(&state); + cx.emit_event(ev); } }, deps,