Feat: solve some issues regarding listeners

This commit is contained in:
Jonathan Kelley committed 2021-07-24 00:29:23 -04:00
1 parent 6084fbcd11
commit dfaf5adee1
22 files changed
+192 -168

No files matched your search

+1 -1
View File
@@ -25,7 +25,7 @@ The current `RealDom` trait lives in `dioxus_core/diff`. A version of it is prov
```rust ```rust
pub trait RealDom<'a> { pub trait RealDom<'a> {
fn handle_edit(&mut self, edit: DomEdit); 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; fn raw_node_as_any(&self) -> &mut dyn Any;
} }
``` ```
+15
View File
@@ -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,
)
});
}
+2 -1
View File
@@ -3,7 +3,7 @@ use std::cell::Cell;
use dioxus::prelude::*; use dioxus::prelude::*;
use dioxus_core::{ use dioxus_core::{
nodes::{VElement, VText}, nodes::{VElement, VText},
RealDomNode, ElementId,
}; };
fn main() { fn main() {
@@ -33,6 +33,7 @@ const Example: FC<()> = |cx| {
} }
"h4" "h4"
div { "h5" } div { "h5" }
button { }
Child {} Child {}
}) })
}; };
-8
View File
@@ -502,7 +502,6 @@ mod field_info {
mod struct_info { mod struct_info {
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::__private::ext::RepToTokensExt;
use quote::quote; use quote::quote;
use syn::parse::Error; 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)] #[derive(Debug, Default)]
+6 -3
View File
@@ -199,9 +199,12 @@ impl<const AS: HTML_OR_RSX> ToTokens for Element<AS> {
tokens.append_all(quote! { tokens.append_all(quote! {
__cx.element( __cx.element(
dioxus_elements::#name, dioxus_elements::#name,
__cx.bump().alloc([ #(#listeners),* ]), [ #(#listeners),* ],
__cx.bump().alloc([ #(#attr),* ]), [ #(#attr),* ],
__cx.bump().alloc([ #(#childs),* ]), [ #(#childs),* ],
// __cx.bump().alloc([ #(#listeners),* ]),
// __cx.bump().alloc([ #(#attr),* ]),
// __cx.bump().alloc([ #(#childs),* ]),
None, None,
) )
}); });
+2 -2
View File
@@ -13,10 +13,10 @@ use slab::Slab;
// #[cfg(feature = "serialize", serde::Serialize)] // #[cfg(feature = "serialize", serde::Serialize)]
// #[cfg(feature = "serialize", serde::Serialize)] // #[cfg(feature = "serialize", serde::Serialize)]
#[derive(serde::Serialize, serde::Deserialize, Copy, Clone, PartialEq, Eq, Hash, Debug)] #[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)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct ElementId(usize); pub struct ElementId(pub usize);
impl ElementId { impl ElementId {
pub fn as_u64(self) -> u64 { pub fn as_u64(self) -> u64 {
+8 -6
View File
@@ -34,12 +34,16 @@
//! For all components, we employ some basic heuristics to speed up allocations and pre-size bump arenas. The heuristics are //! 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. //! currently very rough, but will get better as time goes on. For FFI, we recommend using a bloom filter to cache strings.
//! //!
//!
//! ## Garbage Collection //! ## Garbage Collection
//! --------------------- //! ---------------------
//! Dioxus uses a passive garbage collection system to clean up old nodes once the work has been completed. This garabge //! 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 //! 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. //! 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 //! Further Reading and Thoughts
//! ---------------------------- //! ----------------------------
@@ -53,10 +57,9 @@ use smallvec::{smallvec, SmallVec};
use std::{any::Any, borrow::Borrow}; use std::{any::Any, borrow::Borrow};
/// Instead of having handles directly over nodes, Dioxus uses simple u64s as node IDs. /// 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 something like slotmap or an ECS memory /// The expectation is that the underlying renderer will mainain their Nodes in vec where the ids are the index. This allows
/// where indexing is very fast. For reference, the slotmap in the WebSys renderer takes about 3ns to randomly access any /// for a form of passive garbage collection where nodes aren't immedately cleaned up.
/// node.
/// ///
/// The "RealDom" abstracts over the... real dom. The RealDom trait assumes that the renderer maintains a stack of real /// 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 /// 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] // [... node]
// //
// The change list stack is left unchanged. // 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() { if !old.is_empty() || !new.is_empty() {
// self.edits.commit_traversal(); // 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. // 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>]) { fn diff_keyed_children(&mut self, old: &'bump [VNode<'bump>], new: &'bump [VNode<'bump>]) {
// todo!();
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
let mut keys = fxhash::FxHashSet::default(); let mut keys = fxhash::FxHashSet::default();
let mut assert_unique_keys = |children: &'bump [VNode<'bump>]| { let mut assert_unique_keys = |children: &'bump [VNode<'bump>]| {
+7 -4
View File
@@ -4,7 +4,10 @@
//! 3rd party renderers are responsible for converting their native events into these virtual event types. Events might //! 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. //! 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}; use crate::innerlude::{ElementId, HeightMarker, ScopeId};
@@ -135,7 +138,7 @@ pub mod on {
//! //!
#![allow(unused)] #![allow(unused)]
use std::{fmt::Debug, ops::Deref, rc::Rc}; use std::{cell::RefCell, fmt::Debug, ops::Deref, rc::Rc};
use crate::{ use crate::{
innerlude::NodeFactory, innerlude::NodeFactory,
@@ -183,10 +186,10 @@ pub mod on {
event: stringify!($name), event: stringify!($name),
mounted_node: Cell::new(None), mounted_node: Cell::new(None),
scope: c.scope.our_arena_idx, 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), VirtualEvent::$wrapper(event) => callback(event),
_ => unreachable!("Downcasted VirtualEvent to wrong event type - this is an internal bug!") _ => unreachable!("Downcasted VirtualEvent to wrong event type - this is an internal bug!")
}), })),
} }
} }
)* )*
+37 -19
View File
@@ -8,7 +8,7 @@ use crate::{
innerlude::{empty_cell, Context, DomTree, ElementId, Properties, Scope, ScopeId, FC}, innerlude::{empty_cell, Context, DomTree, ElementId, Properties, Scope, ScopeId, FC},
}; };
use std::{ use std::{
cell::Cell, cell::{Cell, RefCell},
fmt::{Arguments, Debug, Formatter}, fmt::{Arguments, Debug, Formatter},
marker::PhantomData, marker::PhantomData,
rc::Rc, rc::Rc,
@@ -77,7 +77,7 @@ pub struct VElement<'a> {
pub namespace: Option<&'static str>, pub namespace: Option<&'static str>,
pub static_listeners: bool, pub static_listeners: bool,
pub listeners: &'a [&'a mut Listener<'a>], pub listeners: &'a [Listener<'a>],
pub static_attrs: bool, pub static_attrs: bool,
pub attributes: &'a [Attribute<'a>], pub attributes: &'a [Attribute<'a>],
@@ -112,7 +112,7 @@ pub struct Listener<'bump> {
pub mounted_node: Cell<Option<ElementId>>, pub mounted_node: Cell<Option<ElementId>>,
pub(crate) callback: &'bump mut dyn FnMut(VirtualEvent), pub(crate) callback: RefCell<&'bump mut dyn FnMut(VirtualEvent)>,
} }
/// Virtual Components for custom user-defined components /// Virtual Components for custom user-defined components
@@ -200,14 +200,19 @@ impl<'a> NodeFactory<'a> {
} }
} }
pub fn element( pub fn element<L, A, V>(
&self, &self,
el: impl DioxusElement, el: impl DioxusElement,
listeners: &'a mut [&'a mut Listener<'a>], listeners: L,
attributes: &'a [Attribute<'a>], attributes: A,
children: &'a [VNode<'a>], children: V,
key: Option<&'a str>, 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( self.raw_element(
el.tag_name(), el.tag_name(),
el.namespace(), el.namespace(),
@@ -218,26 +223,39 @@ impl<'a> NodeFactory<'a> {
) )
} }
pub fn raw_element( pub fn raw_element<L, A, V>(
&self, &self,
tag: &'static str, tag: &'static str,
namespace: Option<&'static str>, namespace: Option<&'static str>,
listeners: &'a mut [&'a mut Listener<'a>], listeners: L,
attributes: &'a [Attribute], attributes: A,
children: &'a [VNode<'a>], children: V,
key: Option<&'a str>, 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 // We take the references directly from the bump arena
//
//
// TODO: this code shouldn't necessarily be here of all places // TODO: this code shouldn't necessarily be here of all places
// It would make more sense to do this in diffing // It would make more sense to do this in diffing
let mut queue = self.scope.listeners.borrow_mut(); let mut queue = self.scope.listeners.borrow_mut();
for listener in listeners.iter_mut() { for listener in listeners.iter() {
let raw_listener = &mut **listener; let long_listener: &Listener<'static> = unsafe { std::mem::transmute(listener) };
queue.push(long_listener as *const _)
let long_listener: &mut Listener<'static> =
unsafe { std::mem::transmute(raw_listener) };
queue.push(long_listener as *mut _)
} }
VNode { VNode {
+6 -4
View File
@@ -1,4 +1,5 @@
use crate::innerlude::*; use crate::innerlude::*;
use bumpalo::boxed::Box as BumpBox;
use std::{ use std::{
any::{Any, TypeId}, any::{Any, TypeId},
cell::{Cell, RefCell}, cell::{Cell, RefCell},
@@ -31,7 +32,7 @@ pub struct Scope {
pub(crate) child_nodes: &'static [VNode<'static>], pub(crate) child_nodes: &'static [VNode<'static>],
// Listeners // Listeners
pub(crate) listeners: RefCell<Vec<*mut Listener<'static>>>, pub(crate) listeners: RefCell<Vec<*const Listener<'static>>>,
pub(crate) listener_idx: Cell<usize>, pub(crate) listener_idx: Cell<usize>,
// State // State
@@ -154,7 +155,7 @@ impl Scope {
let listners = self.listeners.borrow_mut(); let listners = self.listeners.borrow_mut();
let raw_listener = listners.iter().find(|lis| { let raw_listener = listners.iter().find(|lis| {
let search = unsafe { &mut ***lis }; let search = unsafe { &***lis };
let search_id = search.mounted_node.get(); let search_id = search.mounted_node.get();
log::info!("searching listener {:#?}", search_id); log::info!("searching listener {:#?}", search_id);
@@ -165,8 +166,9 @@ impl Scope {
}); });
if let Some(raw_listener) = raw_listener { if let Some(raw_listener) = raw_listener {
let listener = unsafe { &mut **raw_listener }; let listener = unsafe { &**raw_listener };
(listener.callback)(event); let mut cb = listener.callback.borrow_mut();
(cb)(event);
} else { } else {
log::warn!("An event was triggered but there was no listener to handle it"); log::warn!("An event was triggered but there was no listener to handle it");
} }
+6 -2
View File
@@ -181,8 +181,8 @@ impl VirtualDom {
/// The diff machine expects the RealDom's stack to be the root of the application /// The diff machine expects the RealDom's stack to be the root of the application
pub fn rebuild<'s>( pub fn rebuild<'s>(
&'s mut self, &'s mut self,
realdom: &'s mut dyn RealDom<'s>, realdom: &'_ mut dyn RealDom<'s>,
edits: &'s mut Vec<DomEdit<'s>>, edits: &'_ mut Vec<DomEdit<'s>>,
) -> Result<()> { ) -> Result<()> {
let mut diff_machine = DiffMachine::new(edits, realdom, self.base_scope, &self.shared); 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 { pub fn base_scope(&self) -> &Scope {
unsafe { self.shared.get_scope(self.base_scope).unwrap() } 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! // TODO!
+1
View File
@@ -23,6 +23,7 @@ wry = "0.11.0"
[dev-dependencies] [dev-dependencies]
dioxus-html = { path = "../html" }
tide = "0.15.0" tide = "0.15.0"
tide-websockets = "0.3.0" tide-websockets = "0.3.0"
async-std = { version = "1.9.0", features = ["attributes"] } async-std = { version = "1.9.0", features = ["attributes"] }
+1 -10
View File
@@ -1,5 +1,6 @@
use dioxus_core as dioxus; use dioxus_core as dioxus;
use dioxus_core::prelude::*; use dioxus_core::prelude::*;
use dioxus_html as dioxus_elements;
fn main() { fn main() {
dioxus_desktop::launch(App, |f| f.with_maximized(true)).expect("Failed"); 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 {}
}
+1 -7
View File
@@ -1,7 +1,6 @@
//! webview dom //! webview dom
use dioxus_core::{DomEdit, RealDom, RealDomNode, ScopeId}; use dioxus_core::{DomEdit, RealDom};
use DomEdit::*;
pub struct WebviewRegistry {} pub struct WebviewRegistry {}
@@ -35,9 +34,4 @@ impl<'bump> RealDom<'bump> for WebviewDom<'bump> {
todo!() todo!()
// self.edits.push(PushRoot { root }); // self.edits.push(PushRoot { root });
} }
fn request_available_node(&mut self) -> RealDomNode {
self.node_counter += 1;
RealDomNode::from_u64(self.node_counter)
}
} }
+1 -3
View File
@@ -8,9 +8,7 @@
this.stack = [root]; this.stack = [root];
this.listeners = {}; this.listeners = {};
this.lastNodeWasText = false; this.lastNodeWasText = false;
this.nodes = { this.nodes = [];
0: root
};
} }
top() { top() {
+30
View File
@@ -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!()
}
}
+1 -30
View File
@@ -1,3 +1,4 @@
#![allow(non_snake_case)]
//! # Dioxus Namespace for HTML //! # 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. //! 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 slot
template 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!()
}
}
+1 -6
View File
@@ -1,6 +1,6 @@
//! webview dom //! webview dom
use dioxus_core::{DomEdit, RealDom, RealDomNode, ScopeId}; use dioxus_core::{DomEdit, ElementId, RealDom, ScopeId};
use DomEdit::*; use DomEdit::*;
pub struct WebviewRegistry {} pub struct WebviewRegistry {}
@@ -35,9 +35,4 @@ impl<'bump> RealDom<'bump> for WebviewDom<'bump> {
todo!() todo!()
// self.edits.push(PushRoot { root }); // self.edits.push(PushRoot { root });
} }
fn request_available_node(&mut self) -> RealDomNode {
self.node_counter += 1;
RealDomNode::from_u64(self.node_counter)
}
} }
+19 -19
View File
@@ -21,7 +21,7 @@ pub fn render_vdom_scope(vdom: &VirtualDom, scope: ScopeId) -> Option<String> {
"{:}", "{:}",
TextRenderer { TextRenderer {
cfg: SsrConfig::default(), cfg: SsrConfig::default(),
root: vdom.shared.get_scope(scope).unwrap().root(), root: vdom.get_scope(scope).unwrap().root(),
vdom: Some(vdom) vdom: Some(vdom)
} }
)) ))
@@ -163,7 +163,7 @@ impl<'a> TextRenderer<'a> {
VNodeKind::Component(vcomp) => { VNodeKind::Component(vcomp) => {
let idx = vcomp.ass_scope.get().unwrap(); let idx = vcomp.ass_scope.get().unwrap();
if let Some(vdom) = self.vdom { 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)?; self.html_render(new_node, f, il + 1)?;
} }
} }
@@ -260,22 +260,22 @@ mod tests {
.unwrap(); .unwrap();
} }
#[test] // #[test]
fn styles() { // fn styles() {
const STLYE_APP: FC<()> = |cx| { // const STLYE_APP: FC<()> = |cx| {
// // //
cx.render(rsx! { // cx.render(rsx! {
div { // div {
style: { // style: {
color: "blue", // color: "blue",
font_size: "46px" // font_size: "46px"
} // }
} // }
}) // })
}; // };
let mut dom = VirtualDom::new(STLYE_APP); // let mut dom = VirtualDom::new(STLYE_APP);
dom.rebuild_in_place().expect("failed to run virtualdom"); // dom.rebuild_in_place().expect("failed to run virtualdom");
dbg!(render_vdom(&dom)); // dbg!(render_vdom(&dom));
} // }
} }
-1
View File
@@ -23,7 +23,6 @@ wasm-bindgen-test = "0.3.21"
once_cell = "1.8" once_cell = "1.8"
async-channel = "1.6.1" async-channel = "1.6.1"
anyhow = "1.0.41" anyhow = "1.0.41"
slotmap = "1.0.3"
futures-util = "0.3.15" futures-util = "0.3.15"
+26 -25
View File
@@ -68,36 +68,37 @@ pub async fn event_loop(mut internal_dom: VirtualDom) -> dioxus_core::error::Res
log::info!("Going into event loop"); log::info!("Going into event loop");
loop { loop {
let trigger = { todo!();
let real_queue = websys_dom.wait_for_event(); // let trigger = {
if internal_dom.tasks.is_empty() { // let real_queue = websys_dom.wait_for_event();
log::info!("tasks is empty, waiting for dom event to trigger soemthing"); // if internal_dom.tasks.is_empty() {
real_queue.await // log::info!("tasks is empty, waiting for dom event to trigger soemthing");
} else { // real_queue.await
log::info!("tasks is not empty, waiting for either tasks or event system"); // } else {
let task_queue = (&mut internal_dom.tasks).next(); // 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!(real_queue);
pin_mut!(task_queue); // pin_mut!(task_queue);
match futures_util::future::select(real_queue, task_queue).await { // match futures_util::future::select(real_queue, task_queue).await {
futures_util::future::Either::Left((trigger, _)) => trigger, // futures_util::future::Either::Left((trigger, _)) => trigger,
futures_util::future::Either::Right((trigger, _)) => trigger, // futures_util::future::Either::Right((trigger, _)) => trigger,
} // }
} // }
}; // };
if let Some(real_trigger) = trigger { // if let Some(real_trigger) = trigger {
log::info!("event received"); // log::info!("event received");
internal_dom.queue_event(real_trigger)?; // internal_dom.queue_event(real_trigger);
let mut edits = Vec::new(); // let mut edits = Vec::new();
internal_dom // internal_dom
.progress_with_event(&mut websys_dom, &mut edits) // .progress_with_event(&mut websys_dom, &mut edits)
.await?; // .await?;
websys_dom.process_edits(&mut edits); // websys_dom.process_edits(&mut edits);
} // }
} }
// should actually never return from this, should be an error, rustc just cant see it // should actually never return from this, should be an error, rustc just cant see it
+21 -17
View File
@@ -5,7 +5,6 @@ use dioxus_core::{
DomEdit, ElementId, ScopeId, DomEdit, ElementId, ScopeId,
}; };
use fxhash::FxHashMap; use fxhash::FxHashMap;
use slotmap::{DefaultKey, Key, KeyData};
use wasm_bindgen::{closure::Closure, JsCast}; use wasm_bindgen::{closure::Closure, JsCast};
use web_sys::{ use web_sys::{
window, Document, Element, Event, HtmlElement, HtmlInputElement, HtmlOptionElement, Node, window, Document, Element, Event, HtmlElement, HtmlInputElement, HtmlOptionElement, Node,
@@ -13,7 +12,7 @@ use web_sys::{
pub struct WebsysDom { pub struct WebsysDom {
pub stack: Stack, pub stack: Stack,
nodes: slotmap::SlotMap<DefaultKey, Node>, nodes: Vec<Node>,
document: Document, document: Document,
root: Element, 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::<Node>().unwrap()); // let root_id = nodes.insert(root.clone().dyn_into::<Node>().unwrap());
Self { Self {
stack: Stack::with_capacity(10), stack: Stack::with_capacity(10),
@@ -98,7 +97,8 @@ impl WebsysDom {
} }
} }
fn push(&mut self, root: u64) { 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 domnode = self.nodes.get_mut(key);
let real_node: Node = match domnode { let real_node: Node = match domnode {
@@ -203,11 +203,9 @@ impl WebsysDom {
.dyn_into::<Node>() .dyn_into::<Node>()
.unwrap(); .unwrap();
let id = id as usize;
self.stack.push(textnode.clone()); self.stack.push(textnode.clone());
*self *self.nodes.get_mut(id).unwrap() = textnode;
.nodes
.get_mut(DefaultKey::from(KeyData::from_ffi(id)))
.unwrap() = textnode;
} }
fn create_element(&mut self, tag: &str, ns: Option<&'static str>, id: u64) { fn create_element(&mut self, tag: &str, ns: Option<&'static str>, id: u64) {
@@ -226,14 +224,14 @@ impl WebsysDom {
.dyn_into::<Node>() .dyn_into::<Node>()
.unwrap(), .unwrap(),
}; };
let id = DefaultKey::from(KeyData::from_ffi(id)); let id = id as usize;
self.stack.push(el.clone()); self.stack.push(el.clone());
*self.nodes.get_mut(id).unwrap() = el; *self.nodes.get_mut(id).unwrap() = el;
// let nid = self.node_counter.?next(); // let nid = self.node_counter.?next();
// let nid = self.nodes.insert(el).data().as_ffi(); // let nid = self.nodes.insert(el).data().as_ffi();
// log::debug!("Called [`create_element`]: {}, {:?}", tag, nid); // log::debug!("Called [`create_element`]: {}, {:?}", tag, nid);
// RealDomNode::new(nid) // ElementId::new(nid)
} }
fn new_event_listener( fn new_event_listener(
@@ -257,7 +255,9 @@ impl WebsysDom {
.dyn_ref::<Element>() .dyn_ref::<Element>()
.expect(&format!("not an element: {:?}", el)); .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( el.set_attribute(
&format!("dioxus-event-{}", event), &format!("dioxus-event-{}", event),
&format!("{}.{}", scope_id, real_id), &format!("{}.{}", scope_id, real_id),
@@ -349,10 +349,10 @@ impl WebsysDom {
} }
impl<'a> dioxus_core::diff::RealDom<'a> for 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); // let key = self.nodes.insert(None);
// log::debug!("making new key: {:#?}", key); // 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 { 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(); // let evt: web_sys::ToggleEvent = event.clone().dyn_into().unwrap();
todo!() todo!()
} }
_ => {
todo!()
}
} }
} }
@@ -632,12 +635,13 @@ fn decode_trigger(event: &web_sys::Event) -> anyhow::Result<EventTrigger> {
// Call the trigger // Call the trigger
log::debug!("decoded scope_id: {}, node_id: {:#?}", gi_id, real_id); 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); log::debug!("Triggered scope is {:#?}", triggered_scope);
Ok(EventTrigger::new( Ok(EventTrigger::new(
virtual_event_from_websys_event(event), virtual_event_from_websys_event(event),
triggered_scope, ScopeId(triggered_scope as usize),
Some(RealDomNode::from_u64(real_id)), Some(ElementId(real_id as usize)),
dioxus_core::events::EventPriority::High, dioxus_core::events::EventPriority::High,
)) ))
} }