From cfa966f43e6c1c80ad83e86bd4fda2bb333f9bed Mon Sep 17 00:00:00 2001 From: cksac Date: Tue, 24 Dec 2024 23:34:36 +0800 Subject: [PATCH] revert generic over Node --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 7 ++- benches/basic.rs | 3 +- examples/any_data.rs | 7 ++- examples/basic.rs | 7 ++- examples/mini_demo.rs | 7 ++- examples/state.rs | 9 ++-- examples/test.rs | 7 ++- src/composer.rs | 75 ++++++++++++++------------- src/lib.rs | 4 +- src/node.rs | 114 ------------------------------------------ src/recomposer.rs | 4 +- src/scope.rs | 18 +++---- src/utils.rs | 12 ++--- 15 files changed, 77 insertions(+), 201 deletions(-) delete mode 100644 src/node.rs diff --git a/Cargo.lock b/Cargo.lock index c812872..dbea15d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,7 +107,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "compose-rt" -version = "0.18.0" +version = "0.19.0" dependencies = [ "criterion", "generational-box", diff --git a/Cargo.toml b/Cargo.toml index 66fea19..9c941fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compose-rt" -version = "0.18.0" +version = "0.19.0" edition = "2021" authors = ["cksac "] description = "A positional memoization runtime similar to Jetpack Compose Runtime." diff --git a/README.md b/README.md index a378e43..b373e1e 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,7 @@ A positional memoization runtime similar to Jetpack Compose Runtime. ```rust use std::env; -use compose_rt::node::{Node, NodeData}; -use compose_rt::{Composer, Root}; +use compose_rt::{ComposeNode, Composer, Root}; #[derive(Debug)] pub struct Data(String); @@ -29,11 +28,11 @@ impl From<&str> for Data { } } -impl NodeData for Data { +impl ComposeNode for Data { type Context = (); } -type Scope = compose_rt::Scope>; +type Scope = compose_rt::Scope; pub struct Div; pub struct Button; diff --git a/benches/basic.rs b/benches/basic.rs index 4cce6ef..a347b2c 100644 --- a/benches/basic.rs +++ b/benches/basic.rs @@ -1,10 +1,9 @@ use std::hint::black_box; -use compose_rt::node::Node; use compose_rt::{Composer, Root}; use criterion::{criterion_group, criterion_main, Criterion}; -type Scope = compose_rt::Scope>; +type Scope = compose_rt::Scope; pub struct Div; pub struct Button; diff --git a/examples/any_data.rs b/examples/any_data.rs index 287c38a..cc8fe67 100644 --- a/examples/any_data.rs +++ b/examples/any_data.rs @@ -2,8 +2,7 @@ use std::any::Any; use std::env; use std::fmt::Debug; -use compose_rt::node::{Node, NodeData}; -use compose_rt::{AnyData, Composer, Root}; +use compose_rt::{AnyData, ComposeNode, Composer, Root}; pub trait Data: Debug + 'static { fn as_any(&self) -> &dyn Any; @@ -27,11 +26,11 @@ where } } -impl NodeData for Box { +impl ComposeNode for Box { type Context = (); } -type Scope = compose_rt::Scope>>; +type Scope = compose_rt::Scope>; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Div; diff --git a/examples/basic.rs b/examples/basic.rs index d385713..9d93d16 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,7 +1,6 @@ use std::env; -use compose_rt::node::{Node, NodeData}; -use compose_rt::{Composer, Root}; +use compose_rt::{ComposeNode, Composer, Root}; #[derive(Debug)] pub struct Data(String); @@ -18,11 +17,11 @@ impl From<&str> for Data { } } -impl NodeData for Data { +impl ComposeNode for Data { type Context = (); } -type Scope = compose_rt::Scope>; +type Scope = compose_rt::Scope; pub struct Div; pub struct Button; diff --git a/examples/mini_demo.rs b/examples/mini_demo.rs index c9ce2cf..944d9c5 100644 --- a/examples/mini_demo.rs +++ b/examples/mini_demo.rs @@ -1,7 +1,6 @@ use std::fmt::Debug; -use compose_rt::node::{Node, NodeData}; -use compose_rt::{Composer, Loc, Root}; +use compose_rt::{ComposeNode, Composer, Loc, Root}; #[derive(Clone, Copy, PartialEq, Eq)] pub struct Data(Loc); @@ -26,11 +25,11 @@ impl Debug for Data { } } -impl NodeData for Data { +impl ComposeNode for Data { type Context = usize; } -type Scope = compose_rt::Scope>; +type Scope = compose_rt::Scope; pub struct Container; pub struct Left; diff --git a/examples/state.rs b/examples/state.rs index 54feb40..06029c7 100644 --- a/examples/state.rs +++ b/examples/state.rs @@ -1,7 +1,6 @@ use std::fmt::Debug; -use compose_rt::node::{Node, NodeData}; -use compose_rt::{Composer, Loc, Root}; +use compose_rt::{ComposeNode, Composer, Loc, Root}; #[derive(Clone, Copy, PartialEq, Eq)] pub struct Data(Loc); @@ -26,12 +25,12 @@ impl Debug for Data { } } -impl NodeData for Data { +impl ComposeNode for Data { type Context = (); } -type Scope = compose_rt::Scope>; -type State = compose_rt::State>; +type Scope = compose_rt::Scope; +type State = compose_rt::State; pub struct Container; pub struct Left; diff --git a/examples/test.rs b/examples/test.rs index 4313937..d313658 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -1,7 +1,6 @@ use std::fmt::Debug; -use compose_rt::node::{Node, NodeData}; -use compose_rt::{Composer, Loc, Root}; +use compose_rt::{ComposeNode, Composer, Loc, Root}; #[derive(Clone, Copy, PartialEq, Eq)] pub struct Data(Loc); @@ -26,11 +25,11 @@ impl Debug for Data { } } -impl NodeData for Data { +impl ComposeNode for Data { type Context = usize; } -type Scope = compose_rt::Scope>; +type Scope = compose_rt::Scope; pub struct Container; pub struct Left; diff --git a/src/composer.rs b/src/composer.rs index ab76cee..5eb5370 100644 --- a/src/composer.rs +++ b/src/composer.rs @@ -1,7 +1,5 @@ use std::any::Any; use std::fmt::{Debug, Formatter}; -use std::ops::RangeBounds; -use std::vec::Drain; use generational_box::{AnyStorage, UnsyncStorage}; use slab::Slab; @@ -35,29 +33,10 @@ impl Clone for Box { pub trait ComposeNode: 'static { type Context; - type Data; - - fn new(scope_id: ScopeId, parent: NodeKey) -> Self; - fn as_any(&self) -> &dyn Any; - fn as_any_mut(&mut self) -> &mut dyn Any; - - fn scope_id(&self) -> ScopeId; - fn set_scope_id(&mut self, scope_id: ScopeId); - - fn parent(&self) -> NodeKey; - fn set_parent(&mut self, parent: NodeKey); - - fn data(&self) -> Option<&Self::Data>; - fn data_mut(&mut self) -> Option<&mut Self::Data>; - fn set_data(&mut self, data: Self::Data); +} - fn children(&self) -> &[NodeKey]; - fn children_mut(&mut self) -> &mut [NodeKey]; - fn children_push(&mut self, node_key: NodeKey); - fn children_len(&self) -> usize; - fn children_drain(&mut self, range: R) -> Drain - where - R: RangeBounds; +impl ComposeNode for () { + type Context = (); } pub trait AnyData { @@ -88,12 +67,32 @@ where pub type NodeKey = usize; +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Node { + pub scope_id: ScopeId, + pub parent: NodeKey, + pub children: Vec, + pub data: Option, +} + +impl Node { + #[inline(always)] + pub fn new(scope_id: ScopeId, parent: NodeKey) -> Self { + Self { + scope_id, + parent, + children: Vec::new(), + data: None, + } + } +} + pub struct Composer where N: ComposeNode, { pub context: N::Context, - pub nodes: Slab, + pub nodes: Slab>, pub(crate) initialized: bool, pub(crate) root_node_key: NodeKey, pub(crate) composables: Map>, @@ -203,7 +202,7 @@ where #[inline(always)] pub(crate) fn start_root(&mut self, scope_id: ScopeId) { let parent_node_key = 0; - let node_key = self.nodes.insert(N::new(scope_id, parent_node_key)); + let node_key = self.nodes.insert(Node::new(scope_id, parent_node_key)); self.child_idx_stack.push(0); self.current_node_key = node_key; } @@ -212,7 +211,7 @@ where pub(crate) fn end_root(&mut self) { let child_count = self.child_idx_stack.pop().unwrap(); assert_eq!(1, child_count, "Root scope must have exactly one child"); - self.root_node_key = self.nodes[self.current_node_key].children()[0]; + self.root_node_key = self.nodes[self.current_node_key].children[0]; } #[inline(always)] @@ -221,18 +220,18 @@ where let child_idx = self.child_idx_stack.last().cloned(); if let Some(child_idx) = child_idx { let parent_node = &mut self.nodes[parent_node_key]; - if child_idx < parent_node.children_len() { - let child_key = parent_node.children()[child_idx]; + if child_idx < parent_node.children.len() { + let child_key = parent_node.children[child_idx]; let child_node = &mut self.nodes[child_key]; - if child_node.scope_id() == scope_id { + if child_node.scope_id == scope_id { // reuse existing node self.current_node_key = child_key; self.mount_nodes.insert(child_key); self.child_idx_stack.push(0); } else { // replace existing node - let node_key = self.nodes.insert(N::new(scope_id, parent_node_key)); - self.nodes[parent_node_key].children_mut()[child_idx] = node_key; + let node_key = self.nodes.insert(Node::new(scope_id, parent_node_key)); + self.nodes[parent_node_key].children[child_idx] = node_key; self.unmount_nodes.insert(child_key); self.mount_nodes.insert(node_key); self.current_node_key = node_key; @@ -240,8 +239,8 @@ where } } else { // append new node - let node_key = self.nodes.insert(N::new(scope_id, parent_node_key)); - self.nodes[parent_node_key].children_push(node_key); + let node_key = self.nodes.insert(Node::new(scope_id, parent_node_key)); + self.nodes[parent_node_key].children.push(node_key); self.mount_nodes.insert(node_key); self.current_node_key = node_key; self.child_idx_stack.push(0); @@ -252,8 +251,8 @@ where } } else { // first compose - let node_key = self.nodes.insert(N::new(scope_id, parent_node_key)); - self.nodes[parent_node_key].children_push(node_key); + let node_key = self.nodes.insert(Node::new(scope_id, parent_node_key)); + self.nodes[parent_node_key].children.push(node_key); self.current_node_key = node_key; self.child_idx_stack.push(0); } @@ -263,9 +262,9 @@ where pub(crate) fn end_node(&mut self, parent_node_key: NodeKey) { let child_count = self.child_idx_stack.pop().unwrap(); let node = &mut self.nodes[self.current_node_key]; - let old_child_count = node.children_len(); + let old_child_count = node.children.len(); if child_count < old_child_count { - let unmount_nodes = node.children_drain(child_count..); + let unmount_nodes = node.children.drain(child_count..); self.unmount_nodes.extend(unmount_nodes); } if let Some(parent_child_count) = self.child_idx_stack.last_mut() { diff --git a/src/lib.rs b/src/lib.rs index b2e9f3c..567c506 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ mod loc; pub use loc::Loc; mod composer; -pub use composer::{AnyData, Composable, ComposeNode, Composer, NodeKey}; +pub use composer::{AnyData, Composable, ComposeNode, Composer, Node, NodeKey}; mod recomposer; pub use recomposer::Recomposer; @@ -18,5 +18,3 @@ pub use scope::{Root, Scope, ScopeId}; pub mod utils; mod map; - -pub mod node; diff --git a/src/node.rs b/src/node.rs deleted file mode 100644 index 8aee09a..0000000 --- a/src/node.rs +++ /dev/null @@ -1,114 +0,0 @@ -use std::any::Any; -use std::fmt::Debug; -use std::ops::RangeBounds; -use std::vec::Drain; - -use crate::{ComposeNode, NodeKey, ScopeId}; - -pub trait NodeData: Debug + 'static { - type Context; -} - -impl NodeData for () { - type Context = (); -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Node { - pub scope_id: ScopeId, - pub parent: NodeKey, - pub children: Vec, - pub data: Option, -} - -impl ComposeNode for Node -where - T: NodeData, -{ - type Context = T::Context; - - type Data = T; - - #[inline(always)] - fn new(scope_id: ScopeId, parent: NodeKey) -> Self { - Self { - scope_id, - parent, - children: Vec::new(), - data: None, - } - } - - #[inline(always)] - fn as_any(&self) -> &dyn Any { - self - } - - #[inline(always)] - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } - - #[inline(always)] - fn scope_id(&self) -> ScopeId { - self.scope_id - } - - #[inline(always)] - fn set_scope_id(&mut self, scope_id: ScopeId) { - self.scope_id = scope_id; - } - - #[inline(always)] - fn parent(&self) -> NodeKey { - self.parent - } - - #[inline(always)] - fn set_parent(&mut self, parent: NodeKey) { - self.parent = parent; - } - - #[inline(always)] - fn data(&self) -> Option<&Self::Data> { - self.data.as_ref() - } - - #[inline(always)] - fn data_mut(&mut self) -> Option<&mut Self::Data> { - self.data.as_mut() - } - - #[inline(always)] - fn set_data(&mut self, data: Self::Data) { - self.data = Some(data); - } - - #[inline(always)] - fn children(&self) -> &[NodeKey] { - &self.children - } - - #[inline(always)] - fn children_mut(&mut self) -> &mut [NodeKey] { - &mut self.children - } - - #[inline(always)] - fn children_push(&mut self, node_key: NodeKey) { - self.children.push(node_key); - } - - #[inline(always)] - fn children_len(&self) -> usize { - self.children.len() - } - - #[inline(always)] - fn children_drain(&mut self, range: R) -> Drain - where - R: RangeBounds, - { - self.children.drain(range) - } -} diff --git a/src/recomposer.rs b/src/recomposer.rs index b55db46..02706a5 100644 --- a/src/recomposer.rs +++ b/src/recomposer.rs @@ -149,7 +149,7 @@ where #[inline(always)] pub fn print_tree(&self) where - N::Data: Debug, + N: Debug, { self.print_tree_with(self.root_node_key(), |n| format!("{:?}", n)); } @@ -157,7 +157,7 @@ where #[inline(always)] pub fn print_tree_with(&self, node_key: NodeKey, display_fn: D) where - D: Fn(Option<&N::Data>) -> String, + D: Fn(Option<&N>) -> String, { let c = self.composer.read(); utils::print_tree(&c, node_key, display_fn); diff --git a/src/scope.rs b/src/scope.rs index 2452448..09e87d9 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -7,7 +7,7 @@ use generational_box::GenerationalBox; use slab::Slab; use crate::composer::NodeKey; -use crate::{AnyData, ComposeNode, Composer, Loc, State, StateId}; +use crate::{AnyData, ComposeNode, Composer, Loc, Node, State, StateId}; pub struct Scope where @@ -96,8 +96,8 @@ where C: Fn(Scope) + Clone + 'static, I: Fn() -> A + Clone + 'static, A: 'static, - F: Fn(A, &mut N::Context) -> N::Data + Clone + 'static, - U: Fn(&mut N::Data, A, &mut N::Context) + Clone + 'static, + F: Fn(A, &mut N::Context) -> N + Clone + 'static, + U: Fn(&mut N, A, &mut N::Context) + Clone + 'static, { let parent_scope = *self; let composable = move || { @@ -159,7 +159,7 @@ where C: Fn(Scope) + Clone + 'static, I: Fn() -> A + Clone + 'static, A: 'static, - N::Data: AnyData, + N: AnyData, E: 'static, F: Fn(A, &mut N::Context) -> E + Clone + 'static, U: Fn(&mut E, A, &mut N::Context) + Clone + 'static, @@ -186,22 +186,22 @@ where fn update_node( node_key: NodeKey, context: &mut N::Context, - nodes: &mut Slab, + nodes: &mut Slab>, args: A, factory: &F, update: &U, ) where N: ComposeNode, A: 'static, - F: Fn(A, &mut N::Context) -> N::Data + Clone + 'static, - U: Fn(&mut N::Data, A, &mut N::Context) + Clone + 'static, + F: Fn(A, &mut N::Context) -> N + Clone + 'static, + U: Fn(&mut N, A, &mut N::Context) + Clone + 'static, { let node = nodes.get_mut(node_key).unwrap(); - if let Some(data) = node.data_mut() { + if let Some(data) = node.data.as_mut() { update(data, args, context); } else { let data = factory(args, context); - node.set_data(data); + node.data = Some(data); } } diff --git a/src/utils.rs b/src/utils.rs index 085e692..600f39b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,7 +4,7 @@ use crate::{ComposeNode, Composer}; pub fn print_tree(composer: &Composer, node_key: NodeKey, display_fn: D) where N: ComposeNode, - D: Fn(Option<&N::Data>) -> String, + D: Fn(Option<&N>) -> String, { println!("Root"); print_node(composer, node_key, &display_fn, false, String::new()); @@ -18,28 +18,28 @@ fn print_node( lines_string: String, ) where N: ComposeNode, - D: Fn(Option<&N::Data>) -> String, + D: Fn(Option<&N>) -> String, { let node = &composer.nodes[node_key]; - let num_children = node.children().len(); + let num_children = node.children.len(); let fork_string = if has_sibling { "├── " } else { "└── " }; - let scope = node.scope_id(); + let scope = node.scope_id; println!( "{lines}{fork} {display} [{scope:?} @ {node_key:?}]", lines = lines_string, fork = fork_string, - display = display_fn(node.data()), + display = display_fn(node.data.as_ref()), scope = scope, node_key = node_key, ); let bar = if has_sibling { "│ " } else { " " }; let new_string = lines_string + bar; // Recurse into children - for (index, child) in node.children().iter().cloned().enumerate() { + for (index, child) in node.children.iter().cloned().enumerate() { let has_sibling = index < num_children - 1; print_node(composer, child, display_fn, has_sibling, new_string.clone()); }