Explorar el Código

feat: move back to combined cx/props

Jonathan Kelley hace 3 años
padre
commit
96b3d56

+ 3 - 3
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<FragmentProps>) -> 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()
 }

+ 2 - 2
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<VPortal>;
-    pub type Component<P> = for<'a> fn(Context<'a>, &'a P) -> Element;
+    pub type Component<P> = for<'a> fn(Context<'a, P>) -> Element;
 }
 
 pub use crate::innerlude::{

+ 4 - 18
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<Option<ListenerCallback<'bump>>>,
 }
@@ -355,6 +356,7 @@ impl EventHandler<'_> {
         self.callback.replace(None);
     }
 }
+
 type ListenerCallback<'bump> = BumpBox<'bump, dyn FnMut(Arc<dyn Any + Send + Sync>) + 'bump>;
 
 impl Copy for EventHandler<'_> {}
@@ -552,7 +554,7 @@ impl<'a> NodeFactory<'a> {
 
     pub fn component<P>(
         &self,
-        component: fn(Context<'a>, &'a P) -> Element,
+        component: fn(Context<'a, P>) -> Element,
         props: P,
         key: Option<Arguments>,
     ) -> 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,

+ 27 - 1
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<P> Clone for Context<'_, P> {
+    fn clone(&self) -> Self {
+        Self {
+            scope: self.scope,
+            props: self.props,
+        }
+    }
+}
+impl<P> Copy for Context<'_, P> {}
+impl<P> 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.
 ///

+ 2 - 4
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

+ 6 - 1
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);