feat: proper handling of events
This commit is contained in:
1 parent
c7d2d9d050
commit
d7940aa2ac
7 files changed
+116
-62
No files matched your search
@@ -185,6 +185,7 @@ impl<'bump> DiffMachine<'bump> {
|
||||
/// Returns a `bool` indicating that the work completed properly.
|
||||
pub fn work(&mut self, mut deadline_expired: impl FnMut() -> bool) -> bool {
|
||||
while let Some(instruction) = self.stack.pop() {
|
||||
log::debug!("working {:?}", instruction);
|
||||
match instruction {
|
||||
DiffInstruction::Diff { old, new } => self.diff_node(old, new),
|
||||
DiffInstruction::Create { node } => self.create_node(node),
|
||||
@@ -194,6 +195,7 @@ impl<'bump> DiffMachine<'bump> {
|
||||
};
|
||||
|
||||
if deadline_expired() {
|
||||
log::debug!("Deadling expired before we could finished!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,6 +228,12 @@ impl Scheduler {
|
||||
ScopeId(0)
|
||||
}) as FiberTask);
|
||||
|
||||
let saved_state = SavedDiffWork {
|
||||
mutations: Mutations::new(),
|
||||
stack: DiffStack::new(),
|
||||
seen_scopes: Default::default(),
|
||||
};
|
||||
|
||||
Self {
|
||||
pool,
|
||||
|
||||
@@ -250,7 +256,7 @@ impl Scheduler {
|
||||
garbage_scopes: HashSet::new(),
|
||||
|
||||
dirty_scopes: Default::default(),
|
||||
saved_state: None,
|
||||
saved_state: Some(saved_state),
|
||||
in_progress: false,
|
||||
}
|
||||
}
|
||||
@@ -262,7 +268,7 @@ impl Scheduler {
|
||||
if let Some(scope) = self.pool.get_scope_mut(event.scope) {
|
||||
if let Some(element) = event.mounted_dom_id {
|
||||
// TODO: bubble properly here
|
||||
scope.call_listener(event.event, element);
|
||||
scope.call_listener(event, element);
|
||||
|
||||
while let Ok(Some(dirty_scope)) = self.receiver.try_next() {
|
||||
//
|
||||
@@ -321,7 +327,7 @@ impl Scheduler {
|
||||
if let Some(scope) = self.pool.get_scope_mut(event.scope) {
|
||||
if let Some(element) = event.mounted_dom_id {
|
||||
// TODO: bubble properly here
|
||||
scope.call_listener(event.event, element);
|
||||
scope.call_listener(event, element);
|
||||
|
||||
while let Ok(Some(dirty_scope)) = self.receiver.try_next() {
|
||||
//
|
||||
@@ -360,31 +366,55 @@ impl Scheduler {
|
||||
h1.cmp(&h2)
|
||||
});
|
||||
|
||||
if let Some(scope) = self.dirty_scopes.pop() {
|
||||
let component = self.pool.get_scope(scope).unwrap();
|
||||
if let Some(scopeid) = self.dirty_scopes.pop() {
|
||||
let component = self.pool.get_scope(scopeid).unwrap();
|
||||
let (old, new) = (component.frames.wip_head(), component.frames.fin_head());
|
||||
// let (old, new) = (component.frames.wip_head(), component.frames.fin_head());
|
||||
machine.stack.scope_stack.push(scopeid);
|
||||
machine.stack.push(DiffInstruction::Diff { new, old });
|
||||
}
|
||||
}
|
||||
|
||||
let deadline_expired = machine.work(deadline_reached);
|
||||
let work_completed = machine.work(deadline_reached);
|
||||
|
||||
let machine: DiffMachine<'static> = unsafe { std::mem::transmute(machine) };
|
||||
let mut saved = machine.save();
|
||||
log::debug!("Working finished? {:?}", work_completed);
|
||||
|
||||
if deadline_expired {
|
||||
self.save_work(saved);
|
||||
false
|
||||
} else {
|
||||
for node in saved.seen_scopes.drain() {
|
||||
log::debug!("raw edits {:?}", machine.mutations.edits);
|
||||
|
||||
let mut machine: DiffMachine<'static> = unsafe { std::mem::transmute(machine) };
|
||||
// let mut saved = machine.save();
|
||||
|
||||
if work_completed {
|
||||
for node in machine.seen_scopes.drain() {
|
||||
// self.dirty_scopes.clear();
|
||||
// self.ui_events.clear();
|
||||
self.dirty_scopes.remove(&node);
|
||||
// self.dirty_scopes.remove(&node);
|
||||
}
|
||||
|
||||
let mut new_mutations = Mutations::new();
|
||||
std::mem::swap(&mut new_mutations, &mut saved.mutations);
|
||||
|
||||
for edit in machine.mutations.edits.drain(..) {
|
||||
new_mutations.edits.push(edit);
|
||||
}
|
||||
|
||||
// for edit in saved.edits.drain(..) {
|
||||
// new_mutations.edits.push(edit);
|
||||
// }
|
||||
|
||||
// std::mem::swap(&mut new_mutations, &mut saved.mutations);
|
||||
|
||||
mutations.push(new_mutations);
|
||||
|
||||
log::debug!("saved edits {:?}", mutations);
|
||||
|
||||
let mut saved = machine.save();
|
||||
self.save_work(saved);
|
||||
false
|
||||
|
||||
// self.save_work(saved);
|
||||
// false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
@@ -429,18 +459,28 @@ impl Scheduler {
|
||||
*/
|
||||
let mut committed_mutations = Vec::<Mutations<'static>>::new();
|
||||
|
||||
loop {
|
||||
while self.has_any_work() {
|
||||
// switch our priority, pop off any work
|
||||
for event in self.ui_events.drain(..) {
|
||||
if let Some(scope) = self.pool.get_scope_mut(event.scope) {
|
||||
if let Some(element) = event.mounted_dom_id {
|
||||
log::info!("Calling listener {:?}, {:?}", event.scope, element);
|
||||
|
||||
// TODO: bubble properly here
|
||||
scope.call_listener(event.event, element);
|
||||
scope.call_listener(event, element);
|
||||
|
||||
while let Ok(Some(dirty_scope)) = self.receiver.try_next() {
|
||||
match dirty_scope {
|
||||
SchedulerMsg::Immediate(im) => {
|
||||
self.dirty_scopes.insert(im);
|
||||
log::debug!("Handling immediate {:?}", im);
|
||||
|
||||
if let Some(scope) = self.pool.get_scope_mut(im) {
|
||||
if scope.run_scope(&self.pool) {
|
||||
self.dirty_scopes.insert(im);
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
@@ -449,10 +489,10 @@ impl Scheduler {
|
||||
}
|
||||
}
|
||||
|
||||
let finished_before_deadline =
|
||||
let deadline_expired =
|
||||
self.work_on_current_lane(&mut deadline, &mut committed_mutations);
|
||||
|
||||
if !finished_before_deadline {
|
||||
if deadline_expired {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,22 +238,24 @@ impl Scope {
|
||||
}
|
||||
|
||||
/// A safe wrapper around calling listeners
|
||||
pub(crate) fn call_listener(&mut self, event: SyntheticEvent, element: ElementId) {
|
||||
pub(crate) fn call_listener(&mut self, event: UserEvent, element: ElementId) {
|
||||
let listners = self.listeners.borrow_mut();
|
||||
|
||||
let raw_listener = listners.iter().find(|lis| {
|
||||
let search = unsafe { &***lis };
|
||||
let search_id = search.mounted_node.get();
|
||||
|
||||
// this assumes the node might not be mounted - should we assume that though?
|
||||
search_id.map(|f| f == element).unwrap_or(false)
|
||||
if search.event == event.name {
|
||||
let search_id = search.mounted_node.get();
|
||||
search_id.map(|f| f == element).unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(raw_listener) = raw_listener {
|
||||
let listener = unsafe { &**raw_listener };
|
||||
let mut cb = listener.callback.borrow_mut();
|
||||
if let Some(cb) = cb.as_mut() {
|
||||
(cb)(event);
|
||||
(cb)(event.event);
|
||||
}
|
||||
} else {
|
||||
log::warn!("An event was triggered but there was no listener to handle it");
|
||||
|
||||
Reference in new issue
Block a user