diff --git a/README.md b/README.md
index 091fcabae..4cc9fec32 100644
--- a/README.md
+++ b/README.md
@@ -16,11 +16,9 @@ static Example: FC<()> = |ctx| {
ctx.view(html! {
>;
pub struct EditMachine<'src> {
@@ -306,38 +326,41 @@ impl<'a> EditMachine<'a> {
self.forcing_new_listeners = previous;
}
- pub fn new_event_listener(&mut self, listener: &Listener) {
+ pub fn new_event_listener(&mut self, event: &'a str, idx: CbIdx) {
debug_assert!(self.traversal_is_committed());
- // todo!("Event listener not wired up yet");
- log::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.push(Edit::NewEventListener {
- event_type: listener.event.into(),
- a,
- b,
+ event_type: event,
+ idx,
});
+ // todo!("Event listener not wired up yet");
+ // log::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(listener.event.into(), a, b);
}
- pub fn update_event_listener(&mut self, listener: &Listener) {
+ pub fn update_event_listener(&mut self, event: &'a str, idx: CbIdx) {
debug_assert!(self.traversal_is_committed());
-
if self.forcing_new_listeners {
- self.new_event_listener(listener);
+ self.new_event_listener(event, idx);
return;
}
- log::debug!("emit: update_event_listener({:?})", listener);
- // todo!("Event listener not wired up yet");
- let (a, b) = listener.get_callback_parts();
- debug_assert!(a != 0);
- self.emitter.push(Edit::UpdateEventListener {
- event_type: listener.event.into(),
- a,
- b,
+ self.emitter.push(Edit::NewEventListener {
+ event_type: event,
+ idx,
});
+
+ // log::debug!("emit: update_event_listener({:?})", listener);
+ // // todo!("Event listener not wired up yet");
+ // let (a, b) = listener.get_callback_parts();
+ // debug_assert!(a != 0);
+ // self.emitter.push(Edit::UpdateEventListener {
+ // event_type: listener.event.into(),
+ // a,
+ // b,
+ // });
// self.emitter.update_event_listener(event_id.into(), a, b);
}
diff --git a/packages/core/src/context.rs b/packages/core/src/context.rs
index e3e77df80..1feeb2b61 100644
--- a/packages/core/src/context.rs
+++ b/packages/core/src/context.rs
@@ -44,9 +44,9 @@ pub struct Context<'src> {
}
impl<'a> Context<'a> {
- pub fn props() -> &'a P {
- todo!()
- }
+ // pub fn props
() -> &'a P {
+ // todo!()
+ // }
// impl<'a, PropType> Context<'a, PropType> {
/// Access the children elements passed into the component
@@ -56,7 +56,8 @@ impl<'a> Context<'a> {
/// Create a subscription that schedules a future render for the reference component
pub fn schedule_update(&self) -> impl Fn() -> () {
- todo!("Subscription API is not ready yet");
+ // log::debug!()
+ // todo!("Subscription API is not ready yet");
|| {}
}
diff --git a/packages/core/src/dodriodiff.rs b/packages/core/src/dodriodiff.rs
index 269996248..62816d77c 100644
--- a/packages/core/src/dodriodiff.rs
+++ b/packages/core/src/dodriodiff.rs
@@ -37,7 +37,7 @@ use fxhash::{FxHashMap, FxHashSet};
use generational_arena::Index;
use crate::{
- changelist::{Edit, EditList, EditMachine},
+ changelist::{CbIdx, Edit, EditList, EditMachine},
innerlude::{Attribute, Listener, Scope, VElement, VNode, VText},
virtual_dom::LifecycleEvent,
};
@@ -61,16 +61,20 @@ pub struct DiffMachine<'a> {
immediate_queue: Vec,
diffed: FxHashSet,
need_to_diff: FxHashSet,
+
+ // Current scopes we're comparing
+ current_idx: Option,
}
impl<'a> DiffMachine<'a> {
pub fn new(bump: &'a Bump) -> Self {
- log::debug!("starsting diff machine");
+ log::debug!("starting diff machine");
Self {
change_list: EditMachine::new(bump),
immediate_queue: Vec::new(),
diffed: FxHashSet::default(),
need_to_diff: FxHashSet::default(),
+ current_idx: None,
}
}
@@ -78,8 +82,17 @@ impl<'a> DiffMachine<'a> {
self.change_list.emitter
}
- pub fn diff_node(&mut self, old: &VNode<'a>, new: &VNode<'a>) {
+ pub fn diff_node(
+ &mut self,
+ old: &VNode<'a>,
+ new: &VNode<'a>,
+ scope: Option,
+ ) {
log::debug!("Diffing nodes");
+
+ // Set it while diffing
+ // Reset it when finished diffing
+ self.current_idx = scope;
/*
For each valid case, we "commit traversal", meaning we save this current position in the tree.
Then, we diff and queue an edit event (via chagelist). s single trees - when components show up, we save that traversal and then re-enter later.
@@ -222,6 +235,7 @@ impl<'a> DiffMachine<'a> {
todo!("Suspended components not currently available")
}
}
+ self.current_idx = None;
}
// Diff event listeners between `old` and `new`.
@@ -237,16 +251,20 @@ impl<'a> DiffMachine<'a> {
}
'outer1: for new_l in new {
- unsafe {
- // Safety relies on removing `new_l` from the registry manually at
- // the end of its lifetime. This happens below in the `'outer2`
- // loop, and elsewhere in diffing when removing old dom trees.
- // registry.add(new_l);
- }
+ // unsafe {
+ // Safety relies on removing `new_l` from the registry manually at
+ // the end of its lifetime. This happens below in the `'outer2`
+ // loop, and elsewhere in diffing when removing old dom trees.
+ // registry.add(new_l);
+ // }
- for old_l in old {
+ for (l_idx, old_l) in old.iter().enumerate() {
if new_l.event == old_l.event {
- self.change_list.update_event_listener(new_l);
+ let event_type = new_l.event;
+ if let Some(scope) = self.current_idx {
+ let cb = CbIdx::from_gi_index(scope, l_idx);
+ self.change_list.update_event_listener(event_type, cb);
+ }
continue 'outer1;
}
}
@@ -507,7 +525,7 @@ impl<'a> DiffMachine<'a> {
self.change_list.go_to_sibling(i);
- self.diff_node(old, new);
+ self.diff_node(old, new, self.current_idx);
shared_prefix_count += 1;
}
@@ -705,7 +723,7 @@ impl<'a> DiffMachine<'a> {
// [... parent]
self.change_list.go_down_to_temp_child(temp);
// [... parent last]
- self.diff_node(&old[old_index], last);
+ self.diff_node(&old[old_index], last, self.current_idx);
if new_index_is_in_lis.contains(&last_index) {
// Don't move it, since it is already where it needs to be.
@@ -758,7 +776,7 @@ impl<'a> DiffMachine<'a> {
// [... parent new_child]
}
- self.diff_node(&old[old_index], new_child);
+ self.diff_node(&old[old_index], new_child, self.current_idx);
}
}
@@ -789,8 +807,7 @@ impl<'a> DiffMachine<'a> {
for (i, (old_child, new_child)) in old.iter().zip(new.iter()).enumerate() {
self.change_list.go_to_sibling(new_shared_suffix_start + i);
-
- self.diff_node(old_child, new_child);
+ self.diff_node(old_child, new_child, self.current_idx);
}
// [... parent]
@@ -818,7 +835,7 @@ impl<'a> DiffMachine<'a> {
// [... parent prev_child]
self.change_list.go_to_sibling(i);
// [... parent this_child]
- self.diff_node(old_child, new_child);
+ self.diff_node(old_child, new_child, self.current_idx);
}
match old.len().cmp(&new.len()) {
@@ -880,12 +897,21 @@ impl<'a> DiffMachine<'a> {
self.change_list.create_element(tag_name);
}
- for l in listeners {
- // unsafe {
- // registry.add(l);
- // }
- self.change_list.new_event_listener(l);
- }
+ listeners.iter().enumerate().for_each(|(id, listener)| {
+ if let Some(index) = self.current_idx {
+ self.change_list
+ .new_event_listener(listener.event, CbIdx::from_gi_index(index, id));
+ } else {
+ // Don't panic
+ // Used for testing
+ log::trace!("Failed to set listener, create was not called in the context of the virtual dom");
+ }
+ });
+ // for l in listeners {
+ // unsafe {
+ // registry.add(l);
+ // }
+ // }
for attr in attributes {
self.change_list
diff --git a/packages/core/src/lib.rs b/packages/core/src/lib.rs
index 83e87f656..479ceb0d4 100644
--- a/packages/core/src/lib.rs
+++ b/packages/core/src/lib.rs
@@ -96,6 +96,7 @@ pub(crate) mod innerlude {
pub(crate) use crate::virtual_dom::VirtualDom;
pub(crate) use nodes::*;
+ pub use crate::changelist::CbIdx;
// pub use nodes::iterables::IterableNodes;
/// This type alias is an internal way of abstracting over the static functions that represent components.
@@ -151,119 +152,3 @@ pub mod prelude {
pub use crate::hooks::*;
}
-
-// #[macro_use]
-// extern crate dioxus_core_macro;
-
-// #[macro_use]
-// extern crate fstrings;
-// pub use dioxus_core_macro::format_args_f;
-// macro_rules! mk_macros {( @with_dollar![$dol:tt]=>
-// $(
-// #[doc = $doc_string:literal]
-// $printlnf:ident
-// => $println:ident!($($stream:ident,)? ...)
-// ,
-// )*
-// ) => (
-// $(
-// #[doc = $doc_string]
-// #[macro_export]
-// macro_rules! $printlnf {(
-// $($dol $stream : expr,)? $dol($dol args:tt)*
-// ) => (
-// $println!($($dol $stream,)? "{}", format_args_f!($dol($dol args)*))
-// )}
-// )*
-// )}
-
-// mk_macros! { @with_dollar![$]=>
-// #[doc = "Like [`print!`](https://doc.rust-lang.org/std/macro.print.html), but with basic f-string interpolation."]
-// print_f
-// => print!(...)
-// ,
-// #[doc = "Like [`println!`](https://doc.rust-lang.org/std/macro.println.html), but with basic f-string interpolation."]
-// println_f
-// => println!(...)
-// ,
-// #[doc = "Like [`eprint!`](https://doc.rust-lang.org/std/macro.eprint.html), but with basic f-string interpolation."]
-// eprint_f
-// => eprint!(...)
-// ,
-// #[doc = "Like [`eprintln!`](https://doc.rust-lang.org/std/macro.eprintln.html), but with basic f-string interpolation."]
-// eprintln_f
-// => eprintln!(...)
-// ,
-// #[doc = "Like [`format!`](https://doc.rust-lang.org/std/macro.format.html), but with basic f-string interpolation."]
-// format_f
-// => format!(...)
-// ,
-// #[doc = "Shorthand for [`format_f`]."]
-// f
-// => format!(...)
-// ,
-// #[doc = "Like [`panic!`](https://doc.rust-lang.org/std/macro.panic.html), but with basic f-string interpolation."]
-// panic_f
-// => panic!(...)
-// ,
-// #[doc = "Like [`unreachable!`](https://doc.rust-lang.org/std/macro.unreachable.html), but with basic f-string interpolation."]
-// unreachable_f
-// => unreachable!(...)
-// ,
-// #[doc = "Like [`unimplemented!`](https://doc.rust-lang.org/std/macro.unimplemented.html), but with basic f-string interpolation."]
-// unimplemented_f
-// => unimplemented!(...)
-// ,
-// #[doc = "Like [`write!`](https://doc.rust-lang.org/std/macro.write.html), but with basic f-string interpolation."]
-// write_f
-// => write!(stream, ...)
-// ,
-// #[doc = "Like [`writeln!`](https://doc.rust-lang.org/std/macro.writeln.html), but with basic f-string interpolation."]
-// writeln_f
-// => writeln!(stream, ...)
-// ,
-// }
-/// Like the `format!` macro for creating `std::string::String`s but for
-/// `bumpalo::collections::String`.
-///
-/// # Examples
-///
-/// ```
-/// use bumpalo::Bump;
-///
-/// let b = Bump::new();
-///
-/// let who = "World";
-/// let s = bumpalo::format!(in &b, "Hello, {}!", who);
-/// assert_eq!(s, "Hello, World!")
-/// ```
-#[macro_export]
-macro_rules! ifmt {
- ( in $bump:expr; $fmt:literal;) => {{
- use bumpalo::core_alloc::fmt::Write;
- use $crate::prelude::bumpalo;
- let bump = $bump;
- let mut s = bumpalo::collections::String::new_in(bump);
- let args = $crate::prelude::format_args_f!($fmt);
- s.write_fmt(args);
- s
- }};
-}
-// ( in $bump:expr; $fmt:expr; ) => {
-// $println!("{}", format_args_f!($dol($dol args)*))
-
-// write!(&mut s, println!("{}", args));
-// let _ = $crate::write_f!(&mut s, $fmt);
-// s
-// use fstrings::*;
-// $crate::ifmt!(in $bump, $fmt)
-// };
-
-#[test]
-fn macro_test() {
- let w = 123;
- let world = &w;
- // let g = format_args_f!("Hello {world}");
-
- // dbg!(g);
-}
diff --git a/packages/web/Cargo.toml b/packages/web/Cargo.toml
index fac29f672..0321fddd9 100644
--- a/packages/web/Cargo.toml
+++ b/packages/web/Cargo.toml
@@ -19,6 +19,7 @@ log = "0.4.14"
fxhash = "0.2.1"
pretty_env_logger = "0.4.0"
console_error_panic_hook = "0.1.6"
+generational-arena = "0.2.8"
# html-validation = { path = "../html-validation", version = "0.1.1" }
[dependencies.web-sys]
diff --git a/packages/web/examples/jackjill.rs b/packages/web/examples/jackjill.rs
index d14680c91..5933c4cf8 100644
--- a/packages/web/examples/jackjill.rs
+++ b/packages/web/examples/jackjill.rs
@@ -23,16 +23,3 @@ static Example: FC<()> = |ctx, props| {
})
};
-
-struct ItemProps {
- name: String,
- birthdate: String,
-}
-static Item: FC = |ctx, ItemProps { name, birthdate }| {
- ctx.view(html! {
-
-
"{name}"
-
"{birthdate}"
-
- })
-};
diff --git a/packages/web/src/interpreter.rs b/packages/web/src/interpreter.rs
index c5bd707f9..bc0b227fd 100644
--- a/packages/web/src/interpreter.rs
+++ b/packages/web/src/interpreter.rs
@@ -20,22 +20,50 @@ impl std::fmt::Debug for RootCallback {
pub(crate) struct PatchMachine {
pub(crate) stack: Stack,
+ pub(crate) root: Element,
+
+ pub(crate) temporaries: FxHashMap,
+
+ pub(crate) document: Document,
+
+ pub(crate) events: EventDelegater,
+}
+
+#[derive(Debug)]
+pub(crate) struct EventDelegater {
root: Element,
- temporaries: FxHashMap,
-
- // callback: RootCallback,
- // callback: Option>,
- document: Document,
-
// every callback gets a monotomically increasing callback ID
callback_id: usize,
+ // map of listener types to number of those listeners
+ listeners: FxHashMap<&'static str, (usize, Closure)>,
+
// Map of callback_id to component index and listener id
callback_map: FxHashMap,
}
-// templates: FxHashMap,
+impl EventDelegater {
+ pub fn new(root: Element) -> Self {
+ Self {
+ root,
+ callback_id: 0,
+ listeners: FxHashMap::default(),
+ callback_map: FxHashMap::default(),
+ }
+ }
+
+ pub fn add_listener(
+ &mut self,
+ event: &'static str,
+ gi: generational_arena::Index,
+ listener_id: usize,
+ ) {
+ }
+}
+
+// callback: RootCallback,
+// callback: Option>,
#[derive(Debug, Default)]
pub struct Stack {
@@ -85,16 +113,14 @@ impl PatchMachine {
.expect("must have access to the Document");
// attach all listeners to the container element
+ let events = EventDelegater::new(root.clone());
- // templates: Default::default(),
Self {
root,
+ events,
stack: Stack::with_capacity(20),
temporaries: Default::default(),
- // callback: None,
document,
- callback_id: 0,
- callback_map: FxHashMap::default(),
}
}
@@ -293,7 +319,11 @@ impl PatchMachine {
}
// 11
- Edit::NewEventListener { event_type, a, b } => {
+ Edit::NewEventListener {
+ event_type,
+ idx: a,
+ b,
+ } => {
// 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
@@ -304,16 +334,20 @@ impl PatchMachine {
let el = el
.dyn_ref::()
.expect(&format!("not an element: {:?}", el));
+
// el.add_event_listener_with_callback(
// event_type,
// self.callback.as_ref().unwrap().as_ref().unchecked_ref(),
// )
// .unwrap();
+
debug!("adding attributes: {}, {}", a, b);
el.set_attribute(&format!("dioxus-a-{}", event_type), &a.to_string())
.unwrap();
el.set_attribute(&format!("dioxus-b-{}", event_type), &b.to_string())
.unwrap();
+
+ self.events.add_listener(event_type, gi, listener_id)
}
// 12