Преглед изворни кода

Feat: add context to builder

Jonathan Kelley пре 4 година
родитељ
комит
cf16090838

+ 1 - 1
packages/core-macro/src/htm.rs

@@ -59,7 +59,7 @@ impl ToTokens for HtmlRender {
         // create a lazy tree that accepts a bump allocator
         let final_tokens = quote! {
             move |ctx| {
-                let bump = ctx.bump();
+                let bump = ctx.bump;
 
                 #new_toks
             }

+ 1 - 1
packages/core-macro/src/rsxt.rs

@@ -73,7 +73,7 @@ impl ToTokens for RsxRender {
         // create a lazy tree that accepts a bump allocator
         let final_tokens = quote! {
             move |ctx| {
-                let bump = ctx.bump();
+                let bump = ctx.bump;
                 #new_toks
             }
         };

+ 5 - 5
packages/core/src/context.rs

@@ -78,17 +78,17 @@ impl<'a> Context<'a> {
     ///     ctx.render(lazy_tree)
     /// }
     ///```
-    pub fn render(self, lazy_nodes: impl FnOnce(&'a NodeCtx<'a>) -> VNode<'a> + 'a) -> DomTree {
+    pub fn render(self, lazy_nodes: impl FnOnce(&NodeCtx<'a>) -> VNode<'a> + 'a) -> DomTree {
         let ctx = NodeCtx {
             bump: self.bump,
             idx: 0.into(),
             scope: self.scope,
         };
-        todo!();
-        // let safe_nodes = lazy_nodes(&ctx);
+        // todo!();
+        let safe_nodes = lazy_nodes(&ctx);
 
-        // let unsafe_nodes = unsafe { std::mem::transmute::<VNode<'a>, VNode<'static>>(safe_nodes) };
-        // self.final_nodes.deref().borrow_mut().replace(unsafe_nodes);
+        let unsafe_nodes = unsafe { std::mem::transmute::<VNode<'a>, VNode<'static>>(safe_nodes) };
+        self.final_nodes.deref().borrow_mut().replace(unsafe_nodes);
         DomTree {}
     }
 

+ 21 - 19
packages/core/src/nodebuilder.rs

@@ -19,13 +19,13 @@ use bumpalo::Bump;
 /// function for building `<div>` elements or the `button` function for building
 /// `<button>` elements.
 #[derive(Debug)]
-pub struct ElementBuilder<'a, Listeners, Attributes, Children>
+pub struct ElementBuilder<'a, 'b, Listeners, Attributes, Children>
 where
     Listeners: 'a + AsRef<[Listener<'a>]>,
     Attributes: 'a + AsRef<[Attribute<'a>]>,
     Children: 'a + AsRef<[VNode<'a>]>,
 {
-    ctx: &'a NodeCtx<'a>,
+    ctx: &'b NodeCtx<'a>,
     key: NodeKey,
     tag_name: &'a str,
     listeners: Listeners,
@@ -34,9 +34,10 @@ where
     namespace: Option<&'a str>,
 }
 
-impl<'a>
+impl<'a, 'b>
     ElementBuilder<
         'a,
+        'b,
         bumpalo::collections::Vec<'a, Listener<'a>>,
         bumpalo::collections::Vec<'a, Attribute<'a>>,
         bumpalo::collections::Vec<'a, VNode<'a>>,
@@ -65,9 +66,9 @@ impl<'a>
     /// let my_element_builder = ElementBuilder::new(&b, tag_name);
     /// # fn flip_coin() -> bool { true }
     /// ```
-    pub fn new(ctx: &'a NodeCtx<'a>, tag_name: &'static str) -> Self {
+    pub fn new(ctx: &'b NodeCtx<'a>, tag_name: &'static str) -> Self {
         // pub fn new<B>(ctx: &'a mut NodeCtx<'a>, tag_name: &'a str) -> Self {
-        let bump = ctx.bump();
+        let bump = ctx.bump;
         ElementBuilder {
             ctx,
             key: NodeKey::NONE,
@@ -80,7 +81,8 @@ impl<'a>
     }
 }
 
-impl<'a, Listeners, Attributes, Children> ElementBuilder<'a, Listeners, Attributes, Children>
+impl<'a, 'b, Listeners, Attributes, Children>
+    ElementBuilder<'a, 'b, Listeners, Attributes, Children>
 where
     Listeners: 'a + AsRef<[Listener<'a>]>,
     Attributes: 'a + AsRef<[Attribute<'a>]>,
@@ -114,7 +116,7 @@ where
     ///     .finish();
     /// ```
     #[inline]
-    pub fn listeners<L>(self, listeners: L) -> ElementBuilder<'a, L, Attributes, Children>
+    pub fn listeners<L>(self, listeners: L) -> ElementBuilder<'a, 'b, L, Attributes, Children>
     where
         L: 'a + AsRef<[Listener<'a>]>,
     {
@@ -153,7 +155,7 @@ where
     ///     .finish();
     /// ```
     #[inline]
-    pub fn attributes<A>(self, attributes: A) -> ElementBuilder<'a, Listeners, A, Children>
+    pub fn attributes<A>(self, attributes: A) -> ElementBuilder<'a, 'b, Listeners, A, Children>
     where
         A: 'a + AsRef<[Attribute<'a>]>,
     {
@@ -192,7 +194,7 @@ where
     ///     .finish();
     /// ```
     #[inline]
-    pub fn children<C>(self, children: C) -> ElementBuilder<'a, Listeners, Attributes, C>
+    pub fn children<C>(self, children: C) -> ElementBuilder<'a, 'b, Listeners, Attributes, C>
     where
         C: 'a + AsRef<[VNode<'a>]>,
     {
@@ -290,17 +292,17 @@ where
     /// ```
     #[inline]
     pub fn finish(self) -> VNode<'a> {
-        let children: &'a Children = self.ctx.bump().alloc(self.children);
+        let children: &'a Children = self.ctx.bump.alloc(self.children);
         let children: &'a [VNode<'a>] = children.as_ref();
 
-        let listeners: &'a Listeners = self.ctx.bump().alloc(self.listeners);
+        let listeners: &'a Listeners = self.ctx.bump.alloc(self.listeners);
         let listeners: &'a [Listener<'a>] = listeners.as_ref();
 
-        let attributes: &'a Attributes = self.ctx.bump().alloc(self.attributes);
+        let attributes: &'a Attributes = self.ctx.bump.alloc(self.attributes);
         let attributes: &'a [Attribute<'a>] = attributes.as_ref();
 
         VNode::element(
-            self.ctx.bump(),
+            self.ctx.bump,
             self.key,
             self.tag_name,
             listeners,
@@ -311,8 +313,8 @@ where
     }
 }
 
-impl<'a, Attributes, Children>
-    ElementBuilder<'a, bumpalo::collections::Vec<'a, Listener<'a>>, Attributes, Children>
+impl<'a, 'b, Attributes, Children>
+    ElementBuilder<'a, 'b, bumpalo::collections::Vec<'a, Listener<'a>>, Attributes, Children>
 where
     Attributes: 'a + AsRef<[Attribute<'a>]>,
     Children: 'a + AsRef<[VNode<'a>]>,
@@ -355,8 +357,8 @@ where
     }
 }
 
-impl<'a, Listeners, Children>
-    ElementBuilder<'a, Listeners, bumpalo::collections::Vec<'a, Attribute<'a>>, Children>
+impl<'a, 'b, Listeners, Children>
+    ElementBuilder<'a, 'b, Listeners, bumpalo::collections::Vec<'a, Attribute<'a>>, Children>
 where
     Listeners: 'a + AsRef<[Listener<'a>]>,
     Children: 'a + AsRef<[VNode<'a>]>,
@@ -414,8 +416,8 @@ where
     }
 }
 
-impl<'a, Listeners, Attributes>
-    ElementBuilder<'a, Listeners, Attributes, bumpalo::collections::Vec<'a, VNode<'a>>>
+impl<'a, 'b, Listeners, Attributes>
+    ElementBuilder<'a, 'b, Listeners, Attributes, bumpalo::collections::Vec<'a, VNode<'a>>>
 where
     Listeners: 'a + AsRef<[Listener<'a>]>,
     Attributes: 'a + AsRef<[Attribute<'a>]>,

+ 71 - 37
packages/core/src/patch.rs

@@ -24,49 +24,90 @@ use bumpalo::Bump;
 use crate::innerlude::{Listener, ScopeIdx};
 use serde::{Deserialize, Serialize};
 /// The `Edit` represents a single modifcation of the renderer tree.
-///
-///
-///
-///
-///
-///
-///
-///
 /// todo@ jon: allow serde to be optional
 #[derive(Debug, Serialize, Deserialize)]
 #[serde(tag = "type")]
 pub enum Edit<'d> {
-    SetText { text: &'d str },
+    SetText {
+        text: &'d str,
+    },
     RemoveSelfAndNextSiblings {},
     ReplaceWith,
-    SetAttribute { name: &'d str, value: &'d str },
-    RemoveAttribute { name: &'d str },
-    PushReverseChild { n: u32 },
-    PopPushChild { n: u32 },
+    SetAttribute {
+        name: &'d str,
+        value: &'d str,
+    },
+    RemoveAttribute {
+        name: &'d str,
+    },
+    PushReverseChild {
+        n: u32,
+    },
+    PopPushChild {
+        n: u32,
+    },
     Pop,
     AppendChild,
-    CreateTextNode { text: &'d str },
-    CreateElement { tag_name: &'d str },
-    NewEventListener { event_type: &'d str, s: ScopeIdx },
-    UpdateEventListener { event_type: &'d str, s: ScopeIdx },
-    RemoveEventListener { event_type: &'d str },
-    CreateElementNs { tag_name: &'d str, ns: &'d str },
-    SaveChildrenToTemporaries { temp: u32, start: u32, end: u32 },
-    PushChild { n: u32 },
-    PushTemporary { temp: u32 },
+    CreateTextNode {
+        text: &'d str,
+    },
+    CreateElement {
+        tag_name: &'d str,
+    },
+
+    CreateElementNs {
+        tag_name: &'d str,
+        ns: &'d str,
+    },
+    SaveChildrenToTemporaries {
+        temp: u32,
+        start: u32,
+        end: u32,
+    },
+    PushChild {
+        n: u32,
+    },
+    PushTemporary {
+        temp: u32,
+    },
     InsertBefore,
-    PopPushReverseChild { n: u32 },
-    RemoveChild { n: u32 },
-    SetClass { class_name: &'d str },
+    PopPushReverseChild {
+        n: u32,
+    },
+    RemoveChild {
+        n: u32,
+    },
+    SetClass {
+        class_name: &'d str,
+    },
 
     // push a known node on to the stack
-    TraverseToKnown { node: ScopeIdx },
+    TraverseToKnown {
+        node: ScopeIdx,
+    },
 
     // Add the current top of the stack to the known nodes
-    MakeKnown { node: ScopeIdx },
+    MakeKnown {
+        node: ScopeIdx,
+    },
 
     // Remove the current top of the stack from the known nodes
     RemoveKnown,
+
+    NewListener {
+        event: &'d str,
+        scope: ScopeIdx,
+        id: usize,
+    },
+    UpdateListener {
+        event: &'d str,
+        scope: ScopeIdx,
+        id: usize,
+    },
+    RemoveListener {
+        event: &'d str,
+    },
+    // NewListener { event: &'d str, id: usize, s: ScopeIdx },
 }
 
 pub type EditList<'src> = Vec<Edit<'src>>;
@@ -318,10 +359,7 @@ impl<'a> EditMachine<'a> {
 
     pub fn new_event_listener(&mut self, event: &'a str, scope: ScopeIdx, id: usize) {
         debug_assert!(self.traversal_is_committed());
-        self.emitter.push(Edit::NewEventListener {
-            event_type: event,
-            s: scope,
-        });
+        self.emitter.push(Edit::NewListener { event, scope, id });
         // log::debug!("emit: new_event_listener({:?})", listener);
     }
 
@@ -332,16 +370,12 @@ impl<'a> EditMachine<'a> {
             return;
         }
 
-        self.emitter.push(Edit::NewEventListener {
-            event_type: event,
-            s: scope,
-        });
+        self.emitter.push(Edit::NewListener { event, scope, id });
     }
 
     pub fn remove_event_listener(&mut self, event: &'a str) {
         debug_assert!(self.traversal_is_committed());
-        self.emitter
-            .push(Edit::RemoveEventListener { event_type: event });
+        self.emitter.push(Edit::RemoveListener { event });
         // debug!("emit: remove_event_listener({:?})", event);
     }
 

+ 8 - 4
packages/core/src/scope.rs

@@ -277,11 +277,15 @@ mod tests {
     use crate::prelude::format_args_f;
 
     static ListenerTest: FC<()> = |ctx, props| {
-        ctx.render(html! {
-            <div onclick={|_| println!("Hell owlrld")}>
-                "hello"
-            </div>
+        ctx.render(move |c| {
+            //
+            builder::ElementBuilder::new(c, "div").finish()
         })
+        // ctx.render(html! {
+        //     <div onclick={|_| println!("Hell owlrld")}>
+        //         "hello"
+        //     </div>
+        // })
     };
 
     #[test]

+ 10 - 9
packages/web/examples/basic.rs

@@ -15,15 +15,16 @@ fn main() {
 static App: FC<()> = |ctx, _| {
     log::info!("Ran component");
     use dioxus::builder::*;
-    ctx.render(|b| {
-        div(b)
-            .child(text("hello"))
-            .listeners([on(b, "click", |_| {
-                //
-                log::info!("button1 clicked!");
-            })])
-            .finish()
-    })
+    todo!()
+    // ctx.render(|b| {
+    //     div(b)
+    //         .child(text("hello"))
+    //         .listeners([on(b, "click", |_| {
+    //             //
+    //             log::info!("button1 clicked!");
+    //         })])
+    //         .finish()
+    // })
     // ctx.render(html! {
     //     <div onclick={move |_| log::info!("button1 clicked!")}>
     //         "Hello"

+ 27 - 22
packages/web/src/interpreter.rs

@@ -1,6 +1,10 @@
 use std::{borrow::Borrow, fmt::Debug, sync::Arc};
 
-use dioxus_core::events::{EventTrigger, MouseEvent, VirtualEvent};
+use dioxus_core::{
+    events::{EventTrigger, MouseEvent, VirtualEvent},
+    patch::Edit,
+    prelude::ScopeIdx,
+};
 use fxhash::FxHashMap;
 use log::debug;
 use wasm_bindgen::{closure::Closure, JsCast};
@@ -59,7 +63,7 @@ impl EventDelegater {
         }
     }
 
-    pub fn add_listener(&mut self, event: &str, cb: CbIdx) {
+    pub fn add_listener(&mut self, event: &str, scope: ScopeIdx) {
         if let Some(entry) = self.listeners.get_mut(event) {
             entry.0 += 1;
         } else {
@@ -75,15 +79,15 @@ impl EventDelegater {
 
                 let typ = event.type_();
 
-                let gi_id = target
+                let gi_id: Option<usize> = target
                     .get_attribute(&format!("dioxus-giid-{}", typ))
                     .and_then(|v| v.parse().ok());
 
-                let gi_gen = target
+                let gi_gen: Option<u64> = target
                     .get_attribute(&format!("dioxus-gigen-{}", typ))
                     .and_then(|v| v.parse().ok());
 
-                let li_idx = target
+                let li_idx: Option<usize> = target
                     .get_attribute(&format!("dioxus-lidx-{}", typ))
                     .and_then(|v| v.parse().ok());
 
@@ -91,11 +95,8 @@ impl EventDelegater {
                     // Call the trigger
                     trigger.0.as_ref()(EventTrigger::new(
                         virtual_event_from_websys_event(event),
-                        CbIdx {
-                            gi_gen,
-                            gi_id,
-                            listener_idx: li_idx,
-                        },
+                        scope,
+                        li_idx,
                     ));
                 }
             }) as Box<dyn FnMut(&Event)>);
@@ -342,7 +343,7 @@ impl PatchMachine {
             }
 
             // 11
-            Edit::NewEventListener { event_type, idx } => {
+            Edit::NewListener { event, id, scope } => {
                 // attach the correct attributes to the element
                 // these will be used by accessing the event's target
                 // This ensures we only ever have one handler attached to the root, but decide
@@ -362,24 +363,25 @@ impl PatchMachine {
 
                 // debug!("adding attributes: {}, {}", a, b);
 
-                let CbIdx {
-                    gi_id,
-                    gi_gen,
-                    listener_idx: lidx,
-                } = idx;
+                // let CbIdx {
+                //     gi_id,
+                //     gi_gen,
+                //     listener_idx: lidx,
+                // } = idx;
 
-                el.set_attribute(&format!("dioxus-giid-{}", event_type), &gi_id.to_string())
+                let (gi_id, gi_gen) = (&scope).into_raw_parts();
+                el.set_attribute(&format!("dioxus-giid-{}", event), &gi_id.to_string())
                     .unwrap();
-                el.set_attribute(&format!("dioxus-gigen-{}", event_type), &gi_gen.to_string())
+                el.set_attribute(&format!("dioxus-gigen-{}", event), &gi_gen.to_string())
                     .unwrap();
-                el.set_attribute(&format!("dioxus-lidx-{}", event_type), &lidx.to_string())
+                el.set_attribute(&format!("dioxus-lidx-{}", event), &id.to_string())
                     .unwrap();
 
-                self.events.add_listener(event_type, idx);
+                self.events.add_listener(event, scope);
             }
 
             // 12
-            Edit::UpdateEventListener { event_type, idx } => {
+            Edit::UpdateListener { event, scope, id } => {
                 // update our internal mapping, and then modify the attribute
 
                 if let Some(el) = self.stack.top().dyn_ref::<Element>() {
@@ -391,7 +393,7 @@ impl PatchMachine {
             }
 
             // 13
-            Edit::RemoveEventListener { event_type } => {
+            Edit::RemoveListener { event: event_type } => {
                 if let Some(el) = self.stack.top().dyn_ref::<Element>() {
                     // el.remove_event_listener_with_callback(
                     //     event_type,
@@ -474,6 +476,9 @@ impl PatchMachine {
                     el.set_class_name(class_name);
                 }
             }
+            Edit::TraverseToKnown { node } => {}
+            Edit::MakeKnown { node } => {}
+            Edit::RemoveKnown => {}
         }
     }