From 96b3d56e09a38843f7dc6c1047fe2a3923bd8473 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Mon, 13 Dec 2021 00:06:17 -0500 Subject: [PATCH] feat: move back to combined cx/props --- packages/core/src/component.rs | 6 +++--- packages/core/src/lib.rs | 4 ++-- packages/core/src/nodes.rs | 22 ++++------------------ packages/core/src/scope.rs | 28 +++++++++++++++++++++++++++- packages/core/src/scopearena.rs | 6 ++---- packages/core/src/virtual_dom.rs | 7 ++++++- 6 files changed, 44 insertions(+), 29 deletions(-) diff --git a/packages/core/src/component.rs b/packages/core/src/component.rs index 62ad62f70..a0093da1d 100644 --- a/packages/core/src/component.rs +++ b/packages/core/src/component.rs @@ -97,8 +97,8 @@ impl Properties for FragmentProps { /// /// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it. #[allow(non_upper_case_globals, non_snake_case)] -pub fn Fragment(cx: Context, props: &FragmentProps) -> Element { - cx.render(Some(LazyNodes::new(|f| f.fragment_from_iter(&props.0)))) +pub fn Fragment(cx: Context) -> Element { + cx.render(Some(LazyNodes::new(|f| f.fragment_from_iter(&cx.props.0)))) } /// Every "Props" used for a component must implement the `Properties` trait. This trait gives some hints to Dioxus @@ -165,6 +165,6 @@ impl EmptyBuilder { /// This utility function launches the builder method so rsx! and html! macros can use the typed-builder pattern /// to initialize a component's props. -pub fn fc_to_builder<'a, T: Properties + 'a>(_: fn(Context<'a>, &'a T) -> Element) -> T::Builder { +pub fn fc_to_builder<'a, T: Properties + 'a>(_: fn(Context<'a, T>) -> Element) -> T::Builder { T::builder() } diff --git a/packages/core/src/lib.rs b/packages/core/src/lib.rs index ce9ad0b2b..eb40b4c7a 100644 --- a/packages/core/src/lib.rs +++ b/packages/core/src/lib.rs @@ -17,11 +17,11 @@ pub(crate) mod innerlude { pub use crate::mutations::*; pub use crate::nodes::*; pub use crate::scope::*; - pub use crate::scopearena::*; + pub(crate) use crate::scopearena::*; pub use crate::virtual_dom::*; pub type Element = Option; - pub type Component

= for<'a> fn(Context<'a>, &'a P) -> Element; + pub type Component

= for<'a> fn(Context<'a, P>) -> Element; } pub use crate::innerlude::{ diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index aedd5b90c..9693024d0 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -341,6 +341,7 @@ pub struct Listener<'bump> { pub(crate) callback: EventHandler<'bump>, } +/// The callback based into element event listeners. pub struct EventHandler<'bump> { pub callback: &'bump RefCell>>, } @@ -355,6 +356,7 @@ impl EventHandler<'_> { self.callback.replace(None); } } + type ListenerCallback<'bump> = BumpBox<'bump, dyn FnMut(Arc) + 'bump>; impl Copy for EventHandler<'_> {} @@ -552,7 +554,7 @@ impl<'a> NodeFactory<'a> { pub fn component

( &self, - component: fn(Context<'a>, &'a P) -> Element, + component: fn(Context<'a, P>) -> Element, props: P, key: Option, ) -> VNode<'a> @@ -613,7 +615,7 @@ impl<'a> NodeFactory<'a> { let caller: &'a mut dyn Fn(&'a Scope) -> Element = bump.alloc(move |scope: &Scope| -> Element { let props: &'_ P = unsafe { &*(bump_props as *const P) }; - component(scope, props) + component(Context { scope, props }) }); let can_memoize = P::IS_STATIC; @@ -723,22 +725,6 @@ impl<'a> NodeFactory<'a> { // TODO // We need a dedicated path in the rsx! macro that will trigger the "you need keys" warning - // - // if cfg!(debug_assertions) { - // if children.len() > 1 { - // if children.last().unwrap().key().is_none() { - // log::error!( - // r#" - // Warning: Each child in an array or iterator should have a unique "key" prop. - // Not providing a key will lead to poor performance with lists. - // See docs.rs/dioxus for more information. - // --- - // To help you identify where this error is coming from, we've generated a backtrace. - // "#, - // ); - // } - // } - // } let frag = VNode::Fragment(VFragment { children, diff --git a/packages/core/src/scope.rs b/packages/core/src/scope.rs index 9f30019d1..36730a6b3 100644 --- a/packages/core/src/scope.rs +++ b/packages/core/src/scope.rs @@ -31,7 +31,33 @@ use bumpalo::{boxed::Box as BumpBox, Bump}; /// cx.render(rsx!{ div {"Hello, {props.name}"} }) /// } /// ``` -pub type Context<'a> = &'a Scope; +pub struct Context<'a, P: 'static> { + pub scope: &'a Scope, + pub props: &'a P, +} +impl

Clone for Context<'_, P> { + fn clone(&self) -> Self { + Self { + scope: self.scope, + props: self.props, + } + } +} +impl

Copy for Context<'_, P> {} +impl

std::ops::Deref for Context<'_, P> { + type Target = Scope; + fn deref(&self) -> &Self::Target { + &self.scope + } +} +pub trait AnyContext<'a> { + fn get_scope(&self) -> &'a Scope; +} +impl<'a, P> AnyContext<'a> for Context<'a, P> { + fn get_scope(&self) -> &'a Scope { + &self.scope + } +} /// A component's unique identifier. /// diff --git a/packages/core/src/scopearena.rs b/packages/core/src/scopearena.rs index ae4b1b67a..4f871e401 100644 --- a/packages/core/src/scopearena.rs +++ b/packages/core/src/scopearena.rs @@ -9,9 +9,9 @@ use std::{ use crate::innerlude::*; -pub type FcSlot = *const (); +pub(crate) type FcSlot = *const (); -pub struct Heuristic { +pub(crate) struct Heuristic { hook_arena_size: usize, node_arena_size: usize, } @@ -196,8 +196,6 @@ impl ScopeArena { pub fn try_remove(&self, id: &ScopeId) -> Option<()> { self.ensure_drop_safety(id); - // log::debug!("removing scope {:?}", id); - // Safety: // - ensure_drop_safety ensures that no references to this scope are in use // - this raw pointer is removed from the map diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index 4980f15c5..665bf0e9e 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -196,7 +196,12 @@ impl VirtualDom { ) -> Self { let scopes = ScopeArena::new(sender.clone()); - let mut caller = Box::new(move |scp: &Scope| -> Element { root(scp, &root_props) }); + let mut caller = Box::new(move |scp: &Scope| -> Element { + root(Context { + scope: scp, + props: &root_props, + }) + }); let caller_ref: *mut dyn Fn(&Scope) -> Element = caller.as_mut() as *mut _; let base_scope = scopes.new_with_key(root as _, caller_ref, None, ElementId(0), 0, 0);