From 6e481862ec2997622a6ed63b97431c84770eec9b Mon Sep 17 00:00:00 2001 From: Leo dev Date: Sun, 25 Jan 2026 02:17:08 +0100 Subject: [PATCH] Dynamic scoping with if statement --- examples/hello_world.rs | 56 ++++++++++++++++++++++++++--------------- src/component.rs | 31 ++++++++++++++++++++--- src/state.rs | 9 ++++++- 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/examples/hello_world.rs b/examples/hello_world.rs index 23aeeab..dc65101 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -25,6 +25,21 @@ fn main() { fn app(cx: &Arc) -> View { let count = use_state(0); + cx.on_event({ + let count = count.clone(); + move |_, _: &KeyPress| { + let mut count = count.get(); + + if *count > 5 { + *count = 0; + + return; + } + + *count += 1; + } + }); + { let scope = cx.scope(); @@ -35,29 +50,30 @@ fn app(cx: &Arc) -> View { ctx.draw_view(area, view) })), ); + } - cx.on_event({ - let count = count.clone(); - move |_, _: &KeyPress| { - let mut count = count.get(); - - if *count > 5 { - if scope.children.lock().unwrap().len() == 1 { - scope.child( - my_component, - Some(Arc::new(|ctx, view| { - let area = ctx.allocate(0, 1, 0, 0); - ctx.draw_view(area, view) - })), - ); + { + cx.dyn_scope( + { + let count = count.clone(); + move |scope| { + if *count.get() != 0 { + if scope.children.lock().unwrap().len() == 0 { + scope.child( + my_component, + Some(Arc::new(|ctx, view| { + let area = ctx.allocate(0, 2, 0, 0); + ctx.draw_view(area, view) + })), + ); + } + } else { + scope.children.lock().unwrap().clear(); } - - *count = 0; } - - *count += 1; - } - }); + }, + &[&count], + ); } Arc::new({ diff --git a/src/component.rs b/src/component.rs index 4c6a585..18a4d9b 100644 --- a/src/component.rs +++ b/src/component.rs @@ -4,7 +4,11 @@ use std::{ sync::{Arc, Mutex}, }; -use crate::{render::DrawContext, View, ViewWrapper}; +use crate::{ + render::DrawContext, + state::{use_effect, HookDependency}, + View, ViewWrapper, +}; pub trait Event { fn as_any(&self) -> &dyn Any; @@ -21,7 +25,6 @@ pub type EventHandler = Arc, &dyn Event) + Send + pub struct Scope { pub children: Mutex, Option)>>, - pub scope: Mutex, } pub struct Context { @@ -131,13 +134,35 @@ impl Context { pub fn scope(self: &Arc) -> Arc { let scope = Arc::new(Scope { children: Mutex::new(Vec::new()), - scope: Mutex::new(0), }); self.scopes.lock().unwrap().push(scope.clone()); scope } + pub fn dyn_scope) + Send + Sync + 'static>( + self: &Arc, + drawer: F, + dependencies: &[&dyn HookDependency], + ) -> Arc { + let scope = Arc::new(Scope { + children: Mutex::new(Vec::new()), + }); + self.scopes.lock().unwrap().push(scope.clone()); + + use_effect( + { + let scope = scope.clone(); + move || { + drawer(&scope); + } + }, + dependencies, + ); + + 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() { diff --git a/src/state.rs b/src/state.rs index c851b68..669ecca 100644 --- a/src/state.rs +++ b/src/state.rs @@ -113,7 +113,14 @@ impl HookDependency for State { } pub fn use_effect(f: F, dependencies: &[&dyn HookDependency]) { - let hook = HookEffect(Arc::new(Mutex::new(f))); + let f = Arc::new(Mutex::new(f)); + let hook = HookEffect(Arc::new(Mutex::new({ + let f = f.clone(); + move || { + let f = f.clone(); + std::thread::spawn(move || (f.lock().unwrap())()); + } + }))); for d in dependencies { d.on_update(hook.clone());