Dynamic scoping with if statement

This commit is contained in:
2026-01-25 02:17:08 +01:00
parent 05a390b10f
commit 6e481862ec
3 changed files with 72 additions and 24 deletions
+28 -12
View File
@@ -25,6 +25,21 @@ fn main() {
fn app(cx: &Arc<Context>) -> View { fn app(cx: &Arc<Context>) -> View {
let count = use_state(0); 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(); let scope = cx.scope();
@@ -35,29 +50,30 @@ fn app(cx: &Arc<Context>) -> View {
ctx.draw_view(area, view) ctx.draw_view(area, view)
})), })),
); );
}
cx.on_event({ {
cx.dyn_scope(
{
let count = count.clone(); let count = count.clone();
move |_, _: &KeyPress| { move |scope| {
let mut count = count.get(); if *count.get() != 0 {
if scope.children.lock().unwrap().len() == 0 {
if *count > 5 {
if scope.children.lock().unwrap().len() == 1 {
scope.child( scope.child(
my_component, my_component,
Some(Arc::new(|ctx, view| { Some(Arc::new(|ctx, view| {
let area = ctx.allocate(0, 1, 0, 0); let area = ctx.allocate(0, 2, 0, 0);
ctx.draw_view(area, view) ctx.draw_view(area, view)
})), })),
); );
} }
} else {
*count = 0; scope.children.lock().unwrap().clear();
} }
*count += 1;
} }
}); },
&[&count],
);
} }
Arc::new({ Arc::new({
+28 -3
View File
@@ -4,7 +4,11 @@ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use crate::{render::DrawContext, View, ViewWrapper}; use crate::{
render::DrawContext,
state::{use_effect, HookDependency},
View, ViewWrapper,
};
pub trait Event { pub trait Event {
fn as_any(&self) -> &dyn Any; fn as_any(&self) -> &dyn Any;
@@ -21,7 +25,6 @@ pub type EventHandler = Arc<Mutex<dyn FnMut(&Arc<Context>, &dyn Event) + Send +
pub struct Scope { pub struct Scope {
pub children: Mutex<Vec<(Arc<Context>, Option<ViewWrapper>)>>, pub children: Mutex<Vec<(Arc<Context>, Option<ViewWrapper>)>>,
pub scope: Mutex<usize>,
} }
pub struct Context { pub struct Context {
@@ -131,13 +134,35 @@ impl Context {
pub fn scope(self: &Arc<Self>) -> Arc<Scope> { pub fn scope(self: &Arc<Self>) -> Arc<Scope> {
let scope = Arc::new(Scope { let scope = Arc::new(Scope {
children: Mutex::new(Vec::new()), children: Mutex::new(Vec::new()),
scope: Mutex::new(0),
}); });
self.scopes.lock().unwrap().push(scope.clone()); self.scopes.lock().unwrap().push(scope.clone());
scope scope
} }
pub fn dyn_scope<F: Fn(&Arc<Scope>) + Send + Sync + 'static>(
self: &Arc<Self>,
drawer: F,
dependencies: &[&dyn HookDependency],
) -> Arc<Scope> {
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<Self>, ctx: &mut DrawContext) { pub fn draw_children(self: &Arc<Self>, ctx: &mut DrawContext) {
for scope in self.scopes.lock().unwrap().iter() { for scope in self.scopes.lock().unwrap().iter() {
for (child, view_wrapper) in scope.children.lock().unwrap().iter() { for (child, view_wrapper) in scope.children.lock().unwrap().iter() {
+8 -1
View File
@@ -113,7 +113,14 @@ impl<T> HookDependency for State<T> {
} }
pub fn use_effect<F: FnMut() + Send + Sync + 'static>(f: F, dependencies: &[&dyn HookDependency]) { pub fn use_effect<F: FnMut() + Send + Sync + 'static>(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 { for d in dependencies {
d.on_update(hook.clone()); d.on_update(hook.clone());