diff --git a/.vscode/settings.json b/.vscode/settings.json index 2f418701b..80f51cff8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "rust-analyzer.inlayHints.enable": true + "rust-analyzer.inlayHints.enable": false } \ No newline at end of file diff --git a/packages/core/src/changelist.rs b/packages/core/src/changelist.rs index 254293e67..831be1ab9 100644 --- a/packages/core/src/changelist.rs +++ b/packages/core/src/changelist.rs @@ -19,7 +19,7 @@ //! //! -use crate::innerlude::Listener; +use crate::innerlude::{Listener, VirtualDom}; /// Renderers need to implement the interpreter trait /// @@ -60,6 +60,7 @@ pub struct ChangeList<'src> { next_temporary: u32, forcing_new_listeners: bool, emitter: &'src mut dyn Inrerpreter, + domlock: &'src VirtualDom, } /// Traversal methods. @@ -158,19 +159,19 @@ impl ChangeList<'_> { temp_base } - pub fn push_temporary(&self, temp: u32) { + pub fn push_temporary(&mut self, temp: u32) { debug_assert!(self.traversal_is_committed()); // debug!("emit: push_temporary({})", temp); self.emitter.push_temporary(temp); } - pub fn remove_child(&self, child: usize) { + pub fn remove_child(&mut self, child: usize) { debug_assert!(self.traversal_is_committed()); // debug!("emit: remove_child({})", child); self.emitter.remove_child(child as u32); } - pub fn insert_before(&self) { + pub fn insert_before(&mut self) { debug_assert!(self.traversal_is_committed()); // debug!("emit: insert_before()"); self.emitter.insert_before(); @@ -181,20 +182,20 @@ impl ChangeList<'_> { // self.strings.ensure_string(string, &self.emitter) } - pub fn set_text(&self, text: &str) { + pub fn set_text(&mut self, text: &str) { debug_assert!(self.traversal_is_committed()); // debug!("emit: set_text({:?})", text); self.emitter.set_text(text); // .set_text(text.as_ptr() as u32, text.len() as u32); } - pub fn remove_self_and_next_siblings(&self) { + pub fn remove_self_and_next_siblings(&mut self) { debug_assert!(self.traversal_is_committed()); // debug!("emit: remove_self_and_next_siblings()"); self.emitter.remove_self_and_next_siblings(); } - pub fn replace_with(&self) { + pub fn replace_with(&mut self) { debug_assert!(self.traversal_is_committed()); // debug!("emit: replace_with()"); self.emitter.replace_with(); @@ -218,38 +219,42 @@ impl ChangeList<'_> { } pub fn remove_attribute(&mut self, name: &str) { - debug_assert!(self.traversal_is_committed()); - // debug!("emit: remove_attribute({:?})", name); - let name_id = self.ensure_string(name); - self.emitter.remove_attribute(name_id.into()); + // todo!("figure out how to get this working with ensure string"); + self.emitter.remove_attribute(name); + // debug_assert!(self.traversal_is_committed()); + // // debug!("emit: remove_attribute({:?})", name); + // let name_id = self.ensure_string(name); + // self.emitter.remove_attribute(name_id.into()); } - pub fn append_child(&self) { + pub fn append_child(&mut self) { debug_assert!(self.traversal_is_committed()); // debug!("emit: append_child()"); self.emitter.append_child(); } - pub fn create_text_node(&self, text: &str) { + pub fn create_text_node(&mut self, text: &str) { debug_assert!(self.traversal_is_committed()); // debug!("emit: create_text_node({:?})", text); self.emitter.create_text_node(text); } pub fn create_element(&mut self, tag_name: &str) { - debug_assert!(self.traversal_is_committed()); + // debug_assert!(self.traversal_is_committed()); // debug!("emit: create_element({:?})", tag_name); - let tag_name_id = self.ensure_string(tag_name); - self.emitter.create_element(tag_name_id.into()); + // let tag_name_id = self.ensure_string(tag_name); + self.emitter.create_element(tag_name); + // self.emitter.create_element(tag_name_id.into()); } pub fn create_element_ns(&mut self, tag_name: &str, ns: &str) { debug_assert!(self.traversal_is_committed()); // debug!("emit: create_element_ns({:?}, {:?})", tag_name, ns); - let tag_name_id = self.ensure_string(tag_name); - let ns_id = self.ensure_string(ns); - self.emitter - .create_element_ns(tag_name_id.into(), ns_id.into()); + // let tag_name_id = self.ensure_string(tag_name); + // let ns_id = self.ensure_string(ns); + self.emitter.create_element_ns(tag_name, ns); + // self.emitter + // .create_element_ns(tag_name_id.into(), ns_id.into()); } pub fn push_force_new_listeners(&mut self) -> bool { @@ -265,11 +270,12 @@ impl ChangeList<'_> { pub fn new_event_listener(&mut self, listener: &Listener) { debug_assert!(self.traversal_is_committed()); + todo!("Event listener not wired up yet"); // debug!("emit: new_event_listener({:?})", listener); - let (a, b) = listener.get_callback_parts(); - debug_assert!(a != 0); - let event_id = self.ensure_string(listener.event); - self.emitter.new_event_listener(event_id.into(), a, b); + // let (a, b) = listener.get_callback_parts(); + // debug_assert!(a != 0); + // let event_id = self.ensure_string(listener.event); + // self.emitter.new_event_listener(event_id.into(), a, b); } pub fn update_event_listener(&mut self, listener: &Listener) { @@ -281,17 +287,19 @@ impl ChangeList<'_> { } // debug!("emit: update_event_listener({:?})", listener); - let (a, b) = listener.get_callback_parts(); - debug_assert!(a != 0); + todo!("Event listener not wired up yet"); + // let (a, b) = listener.get_callback_parts(); + // debug_assert!(a != 0); let event_id = self.ensure_string(listener.event); - self.emitter.update_event_listener(event_id.into(), a, b); + // self.emitter.update_event_listener(event_id.into(), a, b); } pub fn remove_event_listener(&mut self, event: &str) { debug_assert!(self.traversal_is_committed()); // debug!("emit: remove_event_listener({:?})", event); let event_id = self.ensure_string(event); - self.emitter.remove_event_listener(event_id.into()); + todo!("Event listener not wired up yet"); + // self.emitter.remove_event_listener(event_id.into()); } // #[inline] diff --git a/packages/core/src/debug_renderer.rs b/packages/core/src/debug_renderer.rs index b9961ea5a..3b63294c3 100644 --- a/packages/core/src/debug_renderer.rs +++ b/packages/core/src/debug_renderer.rs @@ -5,12 +5,12 @@ use crate::prelude::{Properties, VirtualDom}; -pub struct DebugRenderer<'a, P: Properties> { - vdom: &'a mut VirtualDom
, +pub struct DebugRenderer { + vdom: VirtualDom, } -impl<'a, P: Properties> DebugRenderer<'a, P> { - pub fn new(vdom: &'a mut VirtualDom
) -> Self {
+impl DebugRenderer {
+ pub fn new(vdom: VirtualDom) -> Self {
Self { vdom }
}
diff --git a/packages/core/src/error.rs b/packages/core/src/error.rs
index 71e6d4adf..83f528c02 100644
--- a/packages/core/src/error.rs
+++ b/packages/core/src/error.rs
@@ -7,6 +7,9 @@ pub enum Error {
#[error("No event to progress")]
NoEvent,
+ #[error("Wrong Properties Type")]
+ WrongProps,
+
// #[error("Out of compute credits")]
// OutOfCredits,
diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs
index 325341bff..e5120a9a7 100644
--- a/packages/core/src/virtual_dom.rs
+++ b/packages/core/src/virtual_dom.rs
@@ -1,4 +1,4 @@
-use crate::nodes::VNode;
+use crate::{changelist::ChangeList, nodes::VNode};
use crate::{events::EventTrigger, innerlude::*};
use any::Any;
use bumpalo::Bump;
@@ -14,7 +14,8 @@ use std::{
/// An integrated virtual node system that progresses events and diffs UI trees.
/// Differences are converted into patches which a renderer can use to draw the UI.
-pub struct VirtualDom ,
+ // Mark the root props with P, even though they're held by the root component
+ // This is done so we don't have a "generic" vdom, making it easier to hold references to it, especially when the holders
+ // don't care about the generic props type
+ // Most implementations that use the VirtualDom won't care about the root props anyways.
+ #[doc(hidden)]
+ _root_prop_type: std::any::TypeId,
}
-impl VirtualDom<()> {
+impl VirtualDom {
/// Create a new instance of the Dioxus Virtual Dom with no properties for the root component.
///
/// This means that the root component must either consumes its own context, or statics are used to generate the page.
@@ -42,13 +47,14 @@ impl VirtualDom<()> {
}
}
-impl {
+impl VirtualDom {
+ // impl {
/// Start a new VirtualDom instance with a dependent props.
/// Later, the props can be updated by calling "update" with a new set of props, causing a set of re-renders.
///
/// This is useful when a component tree can be driven by external state (IE SSR) but it would be too expensive
/// to toss out the entire tree.
- pub fn new_with_props(root: FC , root_props: P) -> Self {
+ pub fn new_with_props , root_props: P) -> Self {
// 1. Create the component arena
// 2. Create the base scope (can never be removed)
// 3. Create the lifecycle queue
@@ -67,28 +73,41 @@ impl {
// Create an event queue with a mount for the base scope
let event_queue = Rc::new(RefCell::new(vec![first_event]));
+ let _root_prop_type = TypeId::of:: ();
+
Self {
components,
base_scope,
event_queue,
- _root_props: PhantomData {},
+ _root_prop_type,
}
}
/// With access to the virtual dom, schedule an update to the Root component's props
- pub fn update_props(&mut self, new_props: P) {
+ pub fn update_props () != self._root_prop_type {
+ return Err(Error::WrongProps);
+ }
+
self.event_queue.borrow_mut().push(LifecycleEvent {
event_type: LifecycleType::PropsChanged {
props: Box::new(new_props),
},
index: self.base_scope,
});
+
+ Ok(())
}
+ /// Schedule a future update for a component from outside the vdom!
+ ///
+ /// This lets services external to the virtual dom interact directly with the component and event system.
+ pub fn queue_update() {}
+
/// Pop an event off the event queue and process it
/// Update the root props, and progress
/// Takes a bump arena to allocate into, making the diff phase as fast as possible
- ///
pub fn progress(&mut self) -> Result<()> {
let event = self.event_queue.borrow_mut().pop().ok_or(Error::NoEvent)?;
process_event(&mut self.components, event)
@@ -109,7 +128,7 @@ impl {
///
///
/// ```
- pub async fn progress_with_event(&mut self, evt: EventTrigger) -> Result<()> {
+ pub async fn progress_with_event(&mut self, evt: EventTrigger) -> Result {
process_event(&mut self.components, event)?;
}
- Ok(())
+ todo!()
+ // Ok(())
}
pub async fn progress_completely(&mut self) -> Result<()> {
diff --git a/packages/web/Cargo.toml b/packages/web/Cargo.toml
index 34026213f..0b6fdfd0e 100644
--- a/packages/web/Cargo.toml
+++ b/packages/web/Cargo.toml
@@ -15,6 +15,7 @@ wasm-bindgen-futures = "0.4.20"
futures = "0.3.12"
wasm-logger = "0.2.0"
log = "0.4.14"
+fxhash = "0.2.1"
# html-validation = { path = "../html-validation", version = "0.1.1" }
[dependencies.web-sys]
@@ -33,4 +34,5 @@ features = [
"Event",
"MouseEvent",
"InputEvent",
+ "DocumentType",
]
diff --git a/packages/web/src/interpreter.rs b/packages/web/src/interpreter.rs
index 7929ca46d..ba9473240 100644
--- a/packages/web/src/interpreter.rs
+++ b/packages/web/src/interpreter.rs
@@ -1,9 +1,12 @@
-use crate::cached_set::CacheId;
-use crate::{Element, EventsTrampoline};
+// use crate::cached_set::CacheId;
+// use crate::{Element, EventsTrampoline};
use fxhash::FxHashMap;
use log::{debug, info, log};
use wasm_bindgen::{closure::Closure, JsCast};
-use web_sys::{window, Document, Event, Node};
+use web_sys::{window, Document, Element, Event, Node};
+
+#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
+pub(crate) struct CacheId(u32);
#[derive(Debug)]
pub(crate) struct ChangeListInterpreter {
@@ -86,27 +89,29 @@ impl ChangeListInterpreter {
self.templates.get(&id)
}
- pub fn init_events_trampoline(&mut self, mut trampoline: EventsTrampoline) {
- self.callback = Some(Closure::wrap(Box::new(move |event: &web_sys::Event| {
- let target = event
- .target()
- .expect("missing target")
- .dyn_into:: ) {}
+fn attach_listeners(sender: &UnboundedSender