diff --git a/src/component/context.rs b/src/component/context.rs index b8751f5..41f0f77 100644 --- a/src/component/context.rs +++ b/src/component/context.rs @@ -20,7 +20,7 @@ pub struct Context { component: AccessCell, view: AccessCell, event_handlers: AccessCell>>, - pub(crate) scopes: Mutex>>, + scopes: AccessCell>>, executor: Arc, } @@ -33,7 +33,7 @@ impl Context { component: AccessCell::new(Arc::new(component)), view: AccessCell::new(Arc::new(|_| {})), event_handlers: AccessCell::new(HashMap::new()), - scopes: Mutex::new(Vec::new()), + scopes: AccessCell::new(Vec::new()), executor, }) } @@ -87,13 +87,12 @@ impl Context { self: &Arc, handler: F, ) { - let new_handler: EventHandler = Arc::new(Mutex::new( - move |ctx: &Arc, event: &dyn Any| { + 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::()) @@ -106,20 +105,19 @@ impl Context { 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() + 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.clone()); + self.scopes.access(move |scopes| { + for scope in scopes { + for (child, _) in scope.children.lock().unwrap().iter() { + child.emit_event(event.clone()); + } } - } + }); } pub fn emit_event_threaded( @@ -128,10 +126,7 @@ impl Context { ) { let handlers_to_call: Vec = { let guard = self.event_handlers.access_ref(); - guard - .get(&TypeId::of::()) - .cloned() - .unwrap_or_default() + guard.get(&TypeId::of::()).cloned().unwrap_or_default() }; for h in handlers_to_call { let event = event.clone(); @@ -141,16 +136,23 @@ impl Context { }); } - for scope in self.scopes.lock().unwrap().iter() { - for (child, _) in scope.children.lock().unwrap().iter() { - child.emit_event_threaded(event); + let event = event.clone(); + self.scopes.access(move |scopes| { + for scope in scopes { + for (child, _) in scope.children.lock().unwrap().iter() { + child.emit_event_threaded(&event); + } } - } + }); } pub fn scope(self: &Arc) -> Arc { let scope = Scope::new(self.executor.clone()); - self.scopes.lock().unwrap().push(scope.clone()); + + self.scopes.access({ + let scope = scope.clone(); + move |scopes| scopes.push(scope) + }); scope } @@ -161,7 +163,11 @@ impl Context { dependencies: &[&dyn HookDependency], ) -> Arc { let scope = Scope::new(self.executor.clone()); - self.scopes.lock().unwrap().push(scope.clone()); + + self.scopes.access({ + let scope = scope.clone(); + move |scopes| scopes.push(scope) + }); drawer(&scope); @@ -178,18 +184,32 @@ impl Context { scope } - pub fn draw_children(self: &Arc, ctx: &mut DrawContext) { - for scope in self.scopes.lock().unwrap().iter() { - for (child, view_wrapper) in scope.children.lock().unwrap().iter() { - let view = child.get_view(); + pub fn add_scope(self: &Arc, scope: Arc) { + self.scopes.access(|scopes| scopes.push(scope)); + } - if let Some(view_wrapper) = view_wrapper { - view_wrapper(ctx, view) - } else { - ctx.draw_view(ctx.area.clone(), view); + pub fn draw_children(self: &Arc, ctx: &mut DrawContext) { + let mut c = ctx.clone(); + + let (tx, rx) = std::sync::mpsc::channel::(); + + self.scopes.access(move |scopes| { + for scope in scopes { + for (child, view_wrapper) in scope.children.lock().unwrap().iter() { + let view = child.get_view(); + + if let Some(view_wrapper) = view_wrapper { + view_wrapper(&mut c, view) + } else { + c.draw_view(c.area.clone(), view); + } + + tx.send(c.clone()).expect("Failed transmitting DrawContext"); } } - } + }); + + *ctx = rx.recv().expect("Failed receiving DrawContext"); } pub fn get_executor(self: &Arc) -> Arc { diff --git a/src/frontend.rs b/src/frontend.rs index 2689f75..df66c54 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -50,7 +50,7 @@ impl Rsx { RsxScope::Static(scope_fn) => { let scope = Scope::new(executor.clone()); (scope_fn)(&scope); - context.scopes.lock().unwrap().push(scope) + context.add_scope(scope) } RsxScope::Dynamic(drawer, dependencies) => { let drawer = drawer.clone();