diff --git a/docs/advanced-guides/custom-renderer.md b/docs/advanced-guides/custom-renderer.md index ac141e92a..5e1f8d878 100644 --- a/docs/advanced-guides/custom-renderer.md +++ b/docs/advanced-guides/custom-renderer.md @@ -25,7 +25,7 @@ The current `RealDom` trait lives in `dioxus_core/diff`. A version of it is prov ```rust pub trait RealDom<'a> { fn handle_edit(&mut self, edit: DomEdit); - fn request_available_node(&mut self) -> RealDomNode; + fn request_available_node(&mut self) -> ElementId; fn raw_node_as_any(&self) -> &mut dyn Any; } ``` diff --git a/examples/basic.rs b/examples/basic.rs new file mode 100644 index 000000000..63ab7d3fc --- /dev/null +++ b/examples/basic.rs @@ -0,0 +1,15 @@ +use dioxus::prelude::*; + +fn main() { + let g = dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory| { + use dioxus_elements::{GlobalAttributes, SvgAttributes}; + __cx.element( + dioxus_elements::button, + __cx.bump() + .alloc([dioxus::events::on::onclick(__cx, move |_| {})]), + __cx.bump().alloc([]), + __cx.bump().alloc([]), + None, + ) + }); +} diff --git a/examples/testbed.rs b/examples/testbed.rs index 240c75a76..1eadcac53 100644 --- a/examples/testbed.rs +++ b/examples/testbed.rs @@ -3,7 +3,7 @@ use std::cell::Cell; use dioxus::prelude::*; use dioxus_core::{ nodes::{VElement, VText}, - RealDomNode, + ElementId, }; fn main() { @@ -33,6 +33,7 @@ const Example: FC<()> = |cx| { } "h4" div { "h5" } + button { } Child {} }) }; diff --git a/packages/core-macro/src/props/mod.rs b/packages/core-macro/src/props/mod.rs index 9291dd6de..f91eebbda 100644 --- a/packages/core-macro/src/props/mod.rs +++ b/packages/core-macro/src/props/mod.rs @@ -502,7 +502,6 @@ mod field_info { mod struct_info { use proc_macro2::TokenStream; - use quote::__private::ext::RepToTokensExt; use quote::quote; use syn::parse::Error; @@ -1095,13 +1094,6 @@ Finally, call `.build()` to create the instance of `{name}`. } ) } - - pub fn build_props_impl(&self) -> TokenStream { - // SomeProps: #name - // #builder_name - // #generics_with_empty - quote! {} - } } #[derive(Debug, Default)] diff --git a/packages/core-macro/src/rsx/element.rs b/packages/core-macro/src/rsx/element.rs index c4fa949e8..45c391831 100644 --- a/packages/core-macro/src/rsx/element.rs +++ b/packages/core-macro/src/rsx/element.rs @@ -199,9 +199,12 @@ impl ToTokens for Element { tokens.append_all(quote! { __cx.element( dioxus_elements::#name, - __cx.bump().alloc([ #(#listeners),* ]), - __cx.bump().alloc([ #(#attr),* ]), - __cx.bump().alloc([ #(#childs),* ]), + [ #(#listeners),* ], + [ #(#attr),* ], + [ #(#childs),* ], + // __cx.bump().alloc([ #(#listeners),* ]), + // __cx.bump().alloc([ #(#attr),* ]), + // __cx.bump().alloc([ #(#childs),* ]), None, ) }); diff --git a/packages/core/src/arena.rs b/packages/core/src/arena.rs index 1ea90f93b..2fd1f1d2f 100644 --- a/packages/core/src/arena.rs +++ b/packages/core/src/arena.rs @@ -13,10 +13,10 @@ use slab::Slab; // #[cfg(feature = "serialize", serde::Serialize)] // #[cfg(feature = "serialize", serde::Serialize)] #[derive(serde::Serialize, serde::Deserialize, Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct ScopeId(usize); +pub struct ScopeId(pub usize); #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct ElementId(usize); +pub struct ElementId(pub usize); impl ElementId { pub fn as_u64(self) -> u64 { diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs index f28b9052a..1ce705e4d 100644 --- a/packages/core/src/diff.rs +++ b/packages/core/src/diff.rs @@ -34,12 +34,16 @@ //! For all components, we employ some basic heuristics to speed up allocations and pre-size bump arenas. The heuristics are //! currently very rough, but will get better as time goes on. For FFI, we recommend using a bloom filter to cache strings. //! +//! //! ## Garbage Collection //! --------------------- //! Dioxus uses a passive garbage collection system to clean up old nodes once the work has been completed. This garabge //! collection is done internally once the main diffing work is complete. After the "garbage" is collected, Dioxus will then //! start to re-use old keys for new nodes. This results in a passive memory management system that is very efficient. //! +//! The IDs used by the key/map are just an index into a vec. This means that Dioxus will drive the key allocation strategy +//! so the client only needs to maintain a simple list of nodes. By default, Dioxus will not manually clean up old nodes +//! for the client. As new nodes are created, old nodes will be over-written. //! //! Further Reading and Thoughts //! ---------------------------- @@ -53,10 +57,9 @@ use smallvec::{smallvec, SmallVec}; use std::{any::Any, borrow::Borrow}; -/// Instead of having handles directly over nodes, Dioxus uses simple u64s as node IDs. -/// The expectation is that the underlying renderer will mainain their Nodes in something like slotmap or an ECS memory -/// where indexing is very fast. For reference, the slotmap in the WebSys renderer takes about 3ns to randomly access any -/// node. +/// Instead of having handles directly over nodes, Dioxus uses simple u32 as node IDs. +/// The expectation is that the underlying renderer will mainain their Nodes in vec where the ids are the index. This allows +/// for a form of passive garbage collection where nodes aren't immedately cleaned up. /// /// The "RealDom" abstracts over the... real dom. The RealDom trait assumes that the renderer maintains a stack of real /// nodes as the diffing algorithm descenes through the tree. This means that whatever is on top of the stack will receive @@ -531,7 +534,7 @@ impl<'a, 'bump> DiffMachine<'a, 'bump> { // [... node] // // The change list stack is left unchanged. - fn diff_listeners(&mut self, old: &[&mut Listener<'_>], new: &[&mut Listener<'_>]) { + fn diff_listeners(&mut self, old: &[Listener<'_>], new: &[Listener<'_>]) { if !old.is_empty() || !new.is_empty() { // self.edits.commit_traversal(); } @@ -721,7 +724,6 @@ impl<'a, 'bump> DiffMachine<'a, 'bump> { // // Upon exiting, the change list stack is in the same state. fn diff_keyed_children(&mut self, old: &'bump [VNode<'bump>], new: &'bump [VNode<'bump>]) { - // todo!(); if cfg!(debug_assertions) { let mut keys = fxhash::FxHashSet::default(); let mut assert_unique_keys = |children: &'bump [VNode<'bump>]| { diff --git a/packages/core/src/events.rs b/packages/core/src/events.rs index 9cd6d2c0b..74dca1dab 100644 --- a/packages/core/src/events.rs +++ b/packages/core/src/events.rs @@ -4,7 +4,10 @@ //! 3rd party renderers are responsible for converting their native events into these virtual event types. Events might //! be heavy or need to interact through FFI, so the events themselves are designed to be lazy. -use std::{cell::Cell, rc::Rc}; +use std::{ + cell::{Cell, RefCell}, + rc::Rc, +}; use crate::innerlude::{ElementId, HeightMarker, ScopeId}; @@ -135,7 +138,7 @@ pub mod on { //! #![allow(unused)] - use std::{fmt::Debug, ops::Deref, rc::Rc}; + use std::{cell::RefCell, fmt::Debug, ops::Deref, rc::Rc}; use crate::{ innerlude::NodeFactory, @@ -183,10 +186,10 @@ pub mod on { event: stringify!($name), mounted_node: Cell::new(None), scope: c.scope.our_arena_idx, - callback: bump.alloc(move |evt: VirtualEvent| match evt { + callback: RefCell::new(bump.alloc(move |evt: VirtualEvent| match evt { VirtualEvent::$wrapper(event) => callback(event), _ => unreachable!("Downcasted VirtualEvent to wrong event type - this is an internal bug!") - }), + })), } } )* diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index 844e4e66e..d549aa1dd 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -8,7 +8,7 @@ use crate::{ innerlude::{empty_cell, Context, DomTree, ElementId, Properties, Scope, ScopeId, FC}, }; use std::{ - cell::Cell, + cell::{Cell, RefCell}, fmt::{Arguments, Debug, Formatter}, marker::PhantomData, rc::Rc, @@ -77,7 +77,7 @@ pub struct VElement<'a> { pub namespace: Option<&'static str>, pub static_listeners: bool, - pub listeners: &'a [&'a mut Listener<'a>], + pub listeners: &'a [Listener<'a>], pub static_attrs: bool, pub attributes: &'a [Attribute<'a>], @@ -112,7 +112,7 @@ pub struct Listener<'bump> { pub mounted_node: Cell>, - pub(crate) callback: &'bump mut dyn FnMut(VirtualEvent), + pub(crate) callback: RefCell<&'bump mut dyn FnMut(VirtualEvent)>, } /// Virtual Components for custom user-defined components @@ -200,14 +200,19 @@ impl<'a> NodeFactory<'a> { } } - pub fn element( + pub fn element( &self, el: impl DioxusElement, - listeners: &'a mut [&'a mut Listener<'a>], - attributes: &'a [Attribute<'a>], - children: &'a [VNode<'a>], + listeners: L, + attributes: A, + children: V, key: Option<&'a str>, - ) -> VNode<'a> { + ) -> VNode<'a> + where + L: 'a + AsRef<[Listener<'a>]>, + A: 'a + AsRef<[Attribute<'a>]>, + V: 'a + AsRef<[VNode<'a>]>, + { self.raw_element( el.tag_name(), el.namespace(), @@ -218,26 +223,39 @@ impl<'a> NodeFactory<'a> { ) } - pub fn raw_element( + pub fn raw_element( &self, tag: &'static str, namespace: Option<&'static str>, - listeners: &'a mut [&'a mut Listener<'a>], - attributes: &'a [Attribute], - children: &'a [VNode<'a>], + listeners: L, + attributes: A, + children: V, key: Option<&'a str>, - ) -> VNode<'a> { + ) -> VNode<'a> + where + L: 'a + AsRef<[Listener<'a>]>, + A: 'a + AsRef<[Attribute<'a>]>, + V: 'a + AsRef<[VNode<'a>]>, + { + let listeners: &'a L = self.bump().alloc(listeners); + let listeners = listeners.as_ref(); + + let attributes: &'a A = self.bump().alloc(attributes); + let attributes = attributes.as_ref(); + + let children: &'a V = self.bump().alloc(children); + let children = children.as_ref(); + // We take the references directly from the bump arena + // + // // TODO: this code shouldn't necessarily be here of all places // It would make more sense to do this in diffing let mut queue = self.scope.listeners.borrow_mut(); - for listener in listeners.iter_mut() { - let raw_listener = &mut **listener; - - let long_listener: &mut Listener<'static> = - unsafe { std::mem::transmute(raw_listener) }; - queue.push(long_listener as *mut _) + for listener in listeners.iter() { + let long_listener: &Listener<'static> = unsafe { std::mem::transmute(listener) }; + queue.push(long_listener as *const _) } VNode { diff --git a/packages/core/src/scope.rs b/packages/core/src/scope.rs index 01a52fc7b..1a70fc13f 100644 --- a/packages/core/src/scope.rs +++ b/packages/core/src/scope.rs @@ -1,4 +1,5 @@ use crate::innerlude::*; +use bumpalo::boxed::Box as BumpBox; use std::{ any::{Any, TypeId}, cell::{Cell, RefCell}, @@ -31,7 +32,7 @@ pub struct Scope { pub(crate) child_nodes: &'static [VNode<'static>], // Listeners - pub(crate) listeners: RefCell>>, + pub(crate) listeners: RefCell>>, pub(crate) listener_idx: Cell, // State @@ -154,7 +155,7 @@ impl Scope { let listners = self.listeners.borrow_mut(); let raw_listener = listners.iter().find(|lis| { - let search = unsafe { &mut ***lis }; + let search = unsafe { &***lis }; let search_id = search.mounted_node.get(); log::info!("searching listener {:#?}", search_id); @@ -165,8 +166,9 @@ impl Scope { }); if let Some(raw_listener) = raw_listener { - let listener = unsafe { &mut **raw_listener }; - (listener.callback)(event); + let listener = unsafe { &**raw_listener }; + let mut cb = listener.callback.borrow_mut(); + (cb)(event); } else { log::warn!("An event was triggered but there was no listener to handle it"); } diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index 1dd6ccfd4..f82026a8d 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -181,8 +181,8 @@ impl VirtualDom { /// The diff machine expects the RealDom's stack to be the root of the application pub fn rebuild<'s>( &'s mut self, - realdom: &'s mut dyn RealDom<'s>, - edits: &'s mut Vec>, + realdom: &'_ mut dyn RealDom<'s>, + edits: &'_ mut Vec>, ) -> Result<()> { let mut diff_machine = DiffMachine::new(edits, realdom, self.base_scope, &self.shared); @@ -355,6 +355,10 @@ impl VirtualDom { pub fn base_scope(&self) -> &Scope { unsafe { self.shared.get_scope(self.base_scope).unwrap() } } + + pub fn get_scope(&self, id: ScopeId) -> Option<&Scope> { + unsafe { self.shared.get_scope(id) } + } } // TODO! diff --git a/packages/desktop/Cargo.toml b/packages/desktop/Cargo.toml index 4249d4826..4c44aecb1 100644 --- a/packages/desktop/Cargo.toml +++ b/packages/desktop/Cargo.toml @@ -23,6 +23,7 @@ wry = "0.11.0" [dev-dependencies] +dioxus-html = { path = "../html" } tide = "0.15.0" tide-websockets = "0.3.0" async-std = { version = "1.9.0", features = ["attributes"] } diff --git a/packages/desktop/examples/test.rs b/packages/desktop/examples/test.rs index 51eca643f..f18103c71 100644 --- a/packages/desktop/examples/test.rs +++ b/packages/desktop/examples/test.rs @@ -1,5 +1,6 @@ use dioxus_core as dioxus; use dioxus_core::prelude::*; +use dioxus_html as dioxus_elements; fn main() { dioxus_desktop::launch(App, |f| f.with_maximized(true)).expect("Failed"); @@ -13,13 +14,3 @@ static App: FC<()> = |cx| { } )) }; - -mod dioxus_elements { - use super::*; - pub struct div; - impl DioxusElement for div { - const TAG_NAME: &'static str = "div"; - const NAME_SPACE: Option<&'static str> = None; - } - pub trait GlobalAttributes {} -} diff --git a/packages/desktop/src/dom.rs b/packages/desktop/src/dom.rs index 72aa87d68..59debac46 100644 --- a/packages/desktop/src/dom.rs +++ b/packages/desktop/src/dom.rs @@ -1,7 +1,6 @@ //! webview dom -use dioxus_core::{DomEdit, RealDom, RealDomNode, ScopeId}; -use DomEdit::*; +use dioxus_core::{DomEdit, RealDom}; pub struct WebviewRegistry {} @@ -35,9 +34,4 @@ impl<'bump> RealDom<'bump> for WebviewDom<'bump> { todo!() // self.edits.push(PushRoot { root }); } - - fn request_available_node(&mut self) -> RealDomNode { - self.node_counter += 1; - RealDomNode::from_u64(self.node_counter) - } } diff --git a/packages/desktop/src/index.html b/packages/desktop/src/index.html index e67dee623..584685419 100644 --- a/packages/desktop/src/index.html +++ b/packages/desktop/src/index.html @@ -8,9 +8,7 @@ this.stack = [root]; this.listeners = {}; this.lastNodeWasText = false; - this.nodes = { - 0: root - }; + this.nodes = []; } top() { diff --git a/packages/html/src/attrval.s b/packages/html/src/attrval.s new file mode 100644 index 000000000..cb081f4cb --- /dev/null +++ b/packages/html/src/attrval.s @@ -0,0 +1,30 @@ + +trait AsAttributeValue: Sized { + fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a>; +} +enum AttributeValue<'a> { + Int(i32), + Float(f32), + Str(&'a str), + Bool(bool), +} +impl<'b> AsAttributeValue for Arguments<'b> { + fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> { + todo!() + } +} +impl AsAttributeValue for &'static str { + fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> { + todo!() + } +} +impl AsAttributeValue for f32 { + fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> { + todo!() + } +} +impl AsAttributeValue for i32 { + fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> { + todo!() + } +} diff --git a/packages/html/src/lib.rs b/packages/html/src/lib.rs index 22709da86..b726d34a5 100644 --- a/packages/html/src/lib.rs +++ b/packages/html/src/lib.rs @@ -1,3 +1,4 @@ +#![allow(non_snake_case)] //! # Dioxus Namespace for HTML //! //! This crate provides a set of compile-time correct HTML elements that can be used with the Rsx and Html macros. @@ -2100,33 +2101,3 @@ summary slot template */ - -trait AsAttributeValue: Sized { - fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a>; -} -enum AttributeValue<'a> { - Int(i32), - Float(f32), - Str(&'a str), - Bool(bool), -} -impl<'b> AsAttributeValue for Arguments<'b> { - fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> { - todo!() - } -} -impl AsAttributeValue for &'static str { - fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> { - todo!() - } -} -impl AsAttributeValue for f32 { - fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> { - todo!() - } -} -impl AsAttributeValue for i32 { - fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> { - todo!() - } -} diff --git a/packages/mobile/src/dom.rs b/packages/mobile/src/dom.rs index 72aa87d68..cea4f530d 100644 --- a/packages/mobile/src/dom.rs +++ b/packages/mobile/src/dom.rs @@ -1,6 +1,6 @@ //! webview dom -use dioxus_core::{DomEdit, RealDom, RealDomNode, ScopeId}; +use dioxus_core::{DomEdit, ElementId, RealDom, ScopeId}; use DomEdit::*; pub struct WebviewRegistry {} @@ -35,9 +35,4 @@ impl<'bump> RealDom<'bump> for WebviewDom<'bump> { todo!() // self.edits.push(PushRoot { root }); } - - fn request_available_node(&mut self) -> RealDomNode { - self.node_counter += 1; - RealDomNode::from_u64(self.node_counter) - } } diff --git a/packages/ssr/src/lib.rs b/packages/ssr/src/lib.rs index 6a9636364..3d81c33b6 100644 --- a/packages/ssr/src/lib.rs +++ b/packages/ssr/src/lib.rs @@ -21,7 +21,7 @@ pub fn render_vdom_scope(vdom: &VirtualDom, scope: ScopeId) -> Option { "{:}", TextRenderer { cfg: SsrConfig::default(), - root: vdom.shared.get_scope(scope).unwrap().root(), + root: vdom.get_scope(scope).unwrap().root(), vdom: Some(vdom) } )) @@ -163,7 +163,7 @@ impl<'a> TextRenderer<'a> { VNodeKind::Component(vcomp) => { let idx = vcomp.ass_scope.get().unwrap(); if let Some(vdom) = self.vdom { - let new_node = vdom.shared.get_scope(idx).unwrap().root(); + let new_node = vdom.get_scope(idx).unwrap().root(); self.html_render(new_node, f, il + 1)?; } } @@ -260,22 +260,22 @@ mod tests { .unwrap(); } - #[test] - fn styles() { - const STLYE_APP: FC<()> = |cx| { - // - cx.render(rsx! { - div { - style: { - color: "blue", - font_size: "46px" - } - } - }) - }; + // #[test] + // fn styles() { + // const STLYE_APP: FC<()> = |cx| { + // // + // cx.render(rsx! { + // div { + // style: { + // color: "blue", + // font_size: "46px" + // } + // } + // }) + // }; - let mut dom = VirtualDom::new(STLYE_APP); - dom.rebuild_in_place().expect("failed to run virtualdom"); - dbg!(render_vdom(&dom)); - } + // let mut dom = VirtualDom::new(STLYE_APP); + // dom.rebuild_in_place().expect("failed to run virtualdom"); + // dbg!(render_vdom(&dom)); + // } } diff --git a/packages/web/Cargo.toml b/packages/web/Cargo.toml index 9de645a68..e23d4c76d 100644 --- a/packages/web/Cargo.toml +++ b/packages/web/Cargo.toml @@ -23,7 +23,6 @@ wasm-bindgen-test = "0.3.21" once_cell = "1.8" async-channel = "1.6.1" anyhow = "1.0.41" -slotmap = "1.0.3" futures-util = "0.3.15" diff --git a/packages/web/src/lib.rs b/packages/web/src/lib.rs index d517b4744..1a41b930b 100644 --- a/packages/web/src/lib.rs +++ b/packages/web/src/lib.rs @@ -68,36 +68,37 @@ pub async fn event_loop(mut internal_dom: VirtualDom) -> dioxus_core::error::Res log::info!("Going into event loop"); loop { - let trigger = { - let real_queue = websys_dom.wait_for_event(); - if internal_dom.tasks.is_empty() { - log::info!("tasks is empty, waiting for dom event to trigger soemthing"); - real_queue.await - } else { - log::info!("tasks is not empty, waiting for either tasks or event system"); - let task_queue = (&mut internal_dom.tasks).next(); + todo!(); + // let trigger = { + // let real_queue = websys_dom.wait_for_event(); + // if internal_dom.tasks.is_empty() { + // log::info!("tasks is empty, waiting for dom event to trigger soemthing"); + // real_queue.await + // } else { + // log::info!("tasks is not empty, waiting for either tasks or event system"); + // let task_queue = (&mut internal_dom.tasks).next(); - pin_mut!(real_queue); - pin_mut!(task_queue); + // pin_mut!(real_queue); + // pin_mut!(task_queue); - match futures_util::future::select(real_queue, task_queue).await { - futures_util::future::Either::Left((trigger, _)) => trigger, - futures_util::future::Either::Right((trigger, _)) => trigger, - } - } - }; + // match futures_util::future::select(real_queue, task_queue).await { + // futures_util::future::Either::Left((trigger, _)) => trigger, + // futures_util::future::Either::Right((trigger, _)) => trigger, + // } + // } + // }; - if let Some(real_trigger) = trigger { - log::info!("event received"); + // if let Some(real_trigger) = trigger { + // log::info!("event received"); - internal_dom.queue_event(real_trigger)?; + // internal_dom.queue_event(real_trigger); - let mut edits = Vec::new(); - internal_dom - .progress_with_event(&mut websys_dom, &mut edits) - .await?; - websys_dom.process_edits(&mut edits); - } + // let mut edits = Vec::new(); + // internal_dom + // .progress_with_event(&mut websys_dom, &mut edits) + // .await?; + // websys_dom.process_edits(&mut edits); + // } } // should actually never return from this, should be an error, rustc just cant see it diff --git a/packages/web/src/new.rs b/packages/web/src/new.rs index b196f726b..51110cd11 100644 --- a/packages/web/src/new.rs +++ b/packages/web/src/new.rs @@ -5,7 +5,6 @@ use dioxus_core::{ DomEdit, ElementId, ScopeId, }; use fxhash::FxHashMap; -use slotmap::{DefaultKey, Key, KeyData}; use wasm_bindgen::{closure::Closure, JsCast}; use web_sys::{ window, Document, Element, Event, HtmlElement, HtmlInputElement, HtmlOptionElement, Node, @@ -13,7 +12,7 @@ use web_sys::{ pub struct WebsysDom { pub stack: Stack, - nodes: slotmap::SlotMap, + nodes: Vec, document: Document, root: Element, @@ -49,9 +48,9 @@ impl WebsysDom { }); }); - let mut nodes = slotmap::SlotMap::with_capacity(1000); + let mut nodes = Vec::with_capacity(1000); - let root_id = nodes.insert(root.clone().dyn_into::().unwrap()); + // let root_id = nodes.insert(root.clone().dyn_into::().unwrap()); Self { stack: Stack::with_capacity(10), @@ -98,7 +97,8 @@ impl WebsysDom { } } fn push(&mut self, root: u64) { - let key = DefaultKey::from(KeyData::from_ffi(root)); + // let key = DefaultKey::from(KeyData::from_ffi(root)); + let key = root as usize; let domnode = self.nodes.get_mut(key); let real_node: Node = match domnode { @@ -203,11 +203,9 @@ impl WebsysDom { .dyn_into::() .unwrap(); + let id = id as usize; self.stack.push(textnode.clone()); - *self - .nodes - .get_mut(DefaultKey::from(KeyData::from_ffi(id))) - .unwrap() = textnode; + *self.nodes.get_mut(id).unwrap() = textnode; } fn create_element(&mut self, tag: &str, ns: Option<&'static str>, id: u64) { @@ -226,14 +224,14 @@ impl WebsysDom { .dyn_into::() .unwrap(), }; - let id = DefaultKey::from(KeyData::from_ffi(id)); + let id = id as usize; self.stack.push(el.clone()); *self.nodes.get_mut(id).unwrap() = el; // let nid = self.node_counter.?next(); // let nid = self.nodes.insert(el).data().as_ffi(); // log::debug!("Called [`create_element`]: {}, {:?}", tag, nid); - // RealDomNode::new(nid) + // ElementId::new(nid) } fn new_event_listener( @@ -257,7 +255,9 @@ impl WebsysDom { .dyn_ref::() .expect(&format!("not an element: {:?}", el)); - let scope_id = scope.data().as_ffi(); + // let scope_id = scope.data().as_ffi(); + let scope_id = scope.0 as u64; + el.set_attribute( &format!("dioxus-event-{}", event), &format!("{}.{}", scope_id, real_id), @@ -349,10 +349,10 @@ impl WebsysDom { } impl<'a> dioxus_core::diff::RealDom<'a> for WebsysDom { - // fn request_available_node(&mut self) -> RealDomNode { + // fn request_available_node(&mut self) -> ElementId { // let key = self.nodes.insert(None); // log::debug!("making new key: {:#?}", key); - // RealDomNode(key.data().as_ffi()) + // ElementId(key.data().as_ffi()) // } fn raw_node_as_any(&self) -> &mut dyn std::any::Any { @@ -588,6 +588,9 @@ fn virtual_event_from_websys_event(event: &web_sys::Event) -> VirtualEvent { // let evt: web_sys::ToggleEvent = event.clone().dyn_into().unwrap(); todo!() } + _ => { + todo!() + } } } @@ -632,12 +635,13 @@ fn decode_trigger(event: &web_sys::Event) -> anyhow::Result { // Call the trigger log::debug!("decoded scope_id: {}, node_id: {:#?}", gi_id, real_id); - let triggered_scope: ScopeId = KeyData::from_ffi(gi_id).into(); + let triggered_scope = gi_id; + // let triggered_scope: ScopeId = KeyData::from_ffi(gi_id).into(); log::debug!("Triggered scope is {:#?}", triggered_scope); Ok(EventTrigger::new( virtual_event_from_websys_event(event), - triggered_scope, - Some(RealDomNode::from_u64(real_id)), + ScopeId(triggered_scope as usize), + Some(ElementId(real_id as usize)), dioxus_core::events::EventPriority::High, )) }