Fix: some stuff related to event listeners. POC for lifecyel

This commit is contained in:
Jonathan Kelley committed 2021-03-15 02:16:03 -04:00
1 parent 4e48e0514e
commit 5b7887d76c
6 files changed
+102 -23

No files matched your search

+10
View File
@@ -147,12 +147,16 @@ pub struct EditMachine<'lock> {
next_temporary: u32, next_temporary: u32,
forcing_new_listeners: bool, forcing_new_listeners: bool,
// // if the current node is a "known" node
// // any actions that modify this node should update the mapping
// current_known: Option<u32>,
pub emitter: EditList<'lock>, pub emitter: EditList<'lock>,
} }
impl<'lock> EditMachine<'lock> { impl<'lock> EditMachine<'lock> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
// current_known: None,
traversal: Traversal::new(), traversal: Traversal::new(),
next_temporary: 0, next_temporary: 0,
forcing_new_listeners: false, forcing_new_listeners: false,
@@ -283,6 +287,11 @@ impl<'a> EditMachine<'a> {
debug_assert!(self.traversal_is_committed()); debug_assert!(self.traversal_is_committed());
// debug!("emit: replace_with()"); // debug!("emit: replace_with()");
self.emitter.push(Edit::ReplaceWith {}); self.emitter.push(Edit::ReplaceWith {});
// if let Some(id) = self.current_known {
// // update mapping
// self.emitter.push(Edit::MakeKnown{node: id});
// self.current_known = None;
// }
// self.emitter.replace_with(); // self.emitter.replace_with();
} }
@@ -377,6 +386,7 @@ impl<'a> EditMachine<'a> {
pub fn load_known_root(&mut self, id: u32) { pub fn load_known_root(&mut self, id: u32) {
log::debug!("emit: TraverseToKnown({:?})", id); log::debug!("emit: TraverseToKnown({:?})", id);
// self.current_known = Some(id);
self.emitter.push(Edit::TraverseToKnown { node: id }) self.emitter.push(Edit::TraverseToKnown { node: id })
} }
+9 -2
View File
@@ -73,6 +73,12 @@ impl Scope {
} }
} }
pub fn update_caller<'creator_node>(&mut self, caller: Weak<OpaqueComponent<'creator_node>>) {
let broken_caller: Weak<OpaqueComponent<'static>> = unsafe { std::mem::transmute(caller) };
self.caller = broken_caller;
}
/// Create a new context and run the component with references from the Virtual Dom /// Create a new context and run the component with references from the Virtual Dom
/// This function downcasts the function pointer based on the stored props_type /// This function downcasts the function pointer based on the stored props_type
/// ///
@@ -115,13 +121,14 @@ impl Scope {
- Public API cannot drop or destructure VNode - Public API cannot drop or destructure VNode
*/ */
frame.head_node = node_slot.as_ref() frame.head_node = node_slot
.as_ref()
// .deref() // .deref()
.borrow_mut() .borrow_mut()
.take() .take()
.expect("Viewing did not happen"); .expect("Viewing did not happen");
Ok(()) Ok(())
} }
// A safe wrapper around calling listeners // A safe wrapper around calling listeners
+4 -5
View File
@@ -3,7 +3,7 @@
use crate::{error::Error, innerlude::*}; use crate::{error::Error, innerlude::*};
use crate::{patch::Edit, scope::Scope}; use crate::{patch::Edit, scope::Scope};
use generational_arena::Arena; use generational_arena::Arena;
use std::{any::TypeId, borrow::Borrow, rc::{Rc, Weak}}; use std::{any::TypeId, borrow::{Borrow, BorrowMut}, rc::{Rc, Weak}};
use thiserror::private::AsDynError; use thiserror::private::AsDynError;
// We actually allocate the properties for components in their parent's properties // We actually allocate the properties for components in their parent's properties
@@ -119,21 +119,20 @@ impl VirtualDom {
diff_machine.change_list.load_known_root(id); diff_machine.change_list.load_known_root(id);
diff_machine.diff_node(c.old_frame(), c.new_frame()); diff_machine.diff_node(c.old_frame(), c.new_frame());
diff_machine.change_list.save_known_root(id); // diff_machine.change_list.save_known_root(id);
} }
} }
LifeCycleEvent::PropsChanged { caller, id, scope } => { LifeCycleEvent::PropsChanged { caller, id, scope } => {
let idx = scope.upgrade().unwrap().as_ref().borrow().unwrap(); let idx = scope.upgrade().unwrap().as_ref().borrow().unwrap();
// We're modifying the component arena while holding onto references into the assoiated bump arenas of its children
// those references are stable, even if the component arena moves around in memory, thanks to the bump arenas.
// However, there is no way to convey this to rust, so we need to use unsafe to pierce through the lifetime.
unsafe { unsafe {
let p = &mut *(very_unsafe_components); let p = &mut *(very_unsafe_components);
// todo, hook up the parent/child indexes properly // todo, hook up the parent/child indexes properly
// let idx = p.insert_with(|f| Scope::new(caller, f, None)); // let idx = p.insert_with(|f| Scope::new(caller, f, None));
let c = p.get_mut(idx).unwrap(); let c = p.get_mut(idx).unwrap();
c.update_caller(caller);
c.run_scope()?; c.run_scope()?;
// c.caller = caller;
diff_machine.change_list.load_known_root(id); diff_machine.change_list.load_known_root(id);
+58 -12
View File
@@ -40,10 +40,56 @@ static Example: FC<ExampleProps> = |ctx, props| {
} }
// CustomButton { name: sub, set_name: Box::new(move || set_name("jack")) } // CustomButton { name: sub, set_name: Box::new(move || set_name("jack")) }
CustomButton { name: "Jack!", set_name: Box::new(move || set_name("jack")) } CustomButton { name: "Jack!", set_name: Box::new(set_name) }
CustomButton { name: "Jill!", set_name: Box::new(move || set_name("jill")) } CustomButton { name: "Jill!", set_name: Box::new(set_name) }
CustomButton { name: "Bill!", set_name: Box::new(move || set_name("Bill")) } CustomButton { name: "Bob!", set_name: Box::new(set_name) }
CustomButton { name: "Reset!", set_name: Box::new(move || set_name(props.initial_name)) } CustomButton { name: "Bill!", set_name: Box::new(set_name) }
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
CustomButton { name: "back!", set_name: Box::new(set_name) }
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
CustomButton { name: "Jack!", set_name: Box::new(set_name) }
CustomButton { name: "Jill!", set_name: Box::new(set_name) }
CustomButton { name: "Bob!", set_name: Box::new(set_name) }
CustomButton { name: "Bill!", set_name: Box::new(set_name) }
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
CustomButton { name: "back!", set_name: Box::new(set_name) }
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
CustomButton { name: "Jack!", set_name: Box::new(set_name) }
CustomButton { name: "Jill!", set_name: Box::new(set_name) }
CustomButton { name: "Bob!", set_name: Box::new(set_name) }
CustomButton { name: "Bill!", set_name: Box::new(set_name) }
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
CustomButton { name: "back!", set_name: Box::new(set_name) }
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
CustomButton { name: "Jack!", set_name: Box::new(set_name) }
CustomButton { name: "Jill!", set_name: Box::new(set_name) }
CustomButton { name: "Bob!", set_name: Box::new(set_name) }
CustomButton { name: "Bill!", set_name: Box::new(set_name) }
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
CustomButton { name: "back!", set_name: Box::new(set_name) }
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
CustomButton { name: "Jack!", set_name: Box::new(set_name) }
CustomButton { name: "Jill!", set_name: Box::new(set_name) }
CustomButton { name: "Bob!", set_name: Box::new(set_name) }
CustomButton { name: "Bill!", set_name: Box::new(set_name) }
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
CustomButton { name: "back!", set_name: Box::new(set_name) }
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
CustomButton { name: "Jack!", set_name: Box::new(set_name) }
CustomButton { name: "Jill!", set_name: Box::new(set_name) }
CustomButton { name: "Bob!", set_name: Box::new(set_name) }
CustomButton { name: "Bill!", set_name: Box::new(set_name) }
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
CustomButton { name: "back!", set_name: Box::new(set_name) }
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
// CustomButton { name: "Bill!", set_name: Box::new(move || set_name("Bill")) }
// CustomButton { name: "Reset!", set_name: Box::new(move || set_name(props.initial_name)) }
} }
}) })
@@ -51,9 +97,9 @@ static Example: FC<ExampleProps> = |ctx, props| {
#[derive(Props)] #[derive(Props)]
struct ButtonProps<'src> { struct ButtonProps<'src> {
name: &'src str, name: &'static str,
// name: &'src str, // name: &'src str,
set_name: Box< dyn Fn() + 'src> set_name: Box< dyn Fn(&'static str) + 'src>
} }
impl PartialEq for ButtonProps<'_> { impl PartialEq for ButtonProps<'_> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
@@ -63,13 +109,13 @@ impl PartialEq for ButtonProps<'_> {
fn CustomButton<'a>(ctx: Context<'a>, props: &'a ButtonProps<'a>) -> DomTree { fn CustomButton<'a>(ctx: Context<'a>, props: &'a ButtonProps<'a>) -> DomTree {
ctx.render(rsx!{ ctx.render(rsx!{
div { // div {
button { button {
class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow" class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
onmouseover: move |_| (props.set_name)() onmouseover: move |_| (props.set_name)(props.name)
"{props.name}" "{props.name}"
}
} }
// }
}) })
} }
+20 -3
View File
@@ -36,6 +36,8 @@ pub(crate) struct PatchMachine {
pub(crate) document: Document, pub(crate) document: Document,
pub(crate) events: EventDelegater, pub(crate) events: EventDelegater,
pub(crate) current_known: Option<u32>,
} }
#[derive(Debug)] #[derive(Debug)]
@@ -95,9 +97,13 @@ impl EventDelegater {
if let (Some(gi_id), Some(gi_gen), Some(li_idx)) = (gi_id, gi_gen, li_idx) { if let (Some(gi_id), Some(gi_gen), Some(li_idx)) = (gi_id, gi_gen, li_idx) {
// Call the trigger // Call the trigger
log::debug!("decoded gi_id: {}, gi_gen: {}, li_idx: {}", gi_id,gi_gen,li_idx);
let triggered_scope = ScopeIdx::from_raw_parts(gi_id, gi_gen);
trigger.0.as_ref()(EventTrigger::new( trigger.0.as_ref()(EventTrigger::new(
virtual_event_from_websys_event(event), virtual_event_from_websys_event(event),
scope, triggered_scope,
// scope,
li_idx, li_idx,
)); ));
} }
@@ -167,6 +173,7 @@ impl PatchMachine {
let events = EventDelegater::new(root.clone(), event_callback); let events = EventDelegater::new(root.clone(), event_callback);
Self { Self {
current_known: None,
known_roots: Default::default(), known_roots: Default::default(),
root, root,
events, events,
@@ -250,6 +257,13 @@ impl PatchMachine {
panic!("Cannot replace node: {:?}", old_node); panic!("Cannot replace node: {:?}", old_node);
} }
// poc to see if this is a valid solution
if let Some(id) = self.current_known {
// update mapping
self.known_roots.insert(id, new_node.clone());
self.current_known = None;
}
self.stack.push(new_node); self.stack.push(new_node);
} }
@@ -485,9 +499,12 @@ impl PatchMachine {
self.known_roots.insert(node, domnode.clone()); self.known_roots.insert(node, domnode.clone());
} }
Edit::TraverseToKnown { node } => { Edit::TraverseToKnown { node } => {
let domnode = self.known_roots.get(&node).expect("Failed to pop know root"); let domnode = self
.known_roots
.get(&node)
.expect("Failed to pop know root");
self.current_known = Some(node);
self.stack.push(domnode.clone()); self.stack.push(domnode.clone());
} }
Edit::RemoveKnown => {} Edit::RemoveKnown => {}
} }
+1 -1
View File
@@ -102,7 +102,7 @@ impl WebsysRenderer {
for edit in &edits { for edit in &edits {
log::debug!("edit stream {:?}", edit); log::debug!("edit stream {:?}", edit);
log::debug!("Stream stack {:#?}", patch_machine.stack.top()); // log::debug!("Stream stack {:#?}", patch_machine.stack.top());
patch_machine.handle_edit(edit); patch_machine.handle_edit(edit);
} }