remove logging, clean up some code, and fix effect test

This commit is contained in:
Evan Almloff 2024-03-04 15:09:31 -06:00
parent c4b8ebc1cf
commit 797feb5657
5 changed files with 47 additions and 48 deletions

View file

@ -2,7 +2,7 @@ use std::ops::{Deref, DerefMut};
use crate::{ use crate::{
any_props::AnyProps, any_props::AnyProps,
innerlude::{DirtyScopes,ScopeOrder, ElementRef, MountId, VComponent, WriteMutations}, innerlude::{DirtyScopes, ElementRef, MountId, ScopeOrder, VComponent, WriteMutations},
nodes::RenderReturn, nodes::RenderReturn,
nodes::VNode, nodes::VNode,
scopes::ScopeId, scopes::ScopeId,

View file

@ -3,8 +3,8 @@ use crate::Task;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::cell::Cell; use std::cell::Cell;
use std::cell::RefCell; use std::cell::RefCell;
use std::hash::Hash;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::hash::Hash;
#[derive(Debug, Clone, Copy, Eq)] #[derive(Debug, Clone, Copy, Eq)]
pub struct ScopeOrder { pub struct ScopeOrder {
@ -82,34 +82,37 @@ impl DirtyScopes {
match (dirty_scope, dirty_task) { match (dirty_scope, dirty_task) {
(Some(scope), Some(task)) => { (Some(scope), Some(task)) => {
let tasks_order = task.borrow(); let tasks_order = task.borrow();
if scope > tasks_order{ match scope.cmp(tasks_order) {
let scope = self.scopes.pop_first().unwrap(); std::cmp::Ordering::Less => {
Some(Work{ let scope = self.scopes.pop_first().unwrap();
scope: scope, Some(Work {
rerun_scope: true, scope: scope,
tasks: Vec::new(), rerun_scope: true,
}) tasks: Vec::new(),
} else if tasks_order> scope { })
let task = self.tasks.pop_first().unwrap(); }
Some(Work{ std::cmp::Ordering::Greater => {
scope: task.order, let task = self.tasks.pop_first().unwrap();
rerun_scope: false, Some(Work {
tasks: task.tasks_queued.into_inner(), scope: task.order,
}) rerun_scope: false,
} tasks: task.tasks_queued.into_inner(),
else { })
let scope = self.scopes.pop_first().unwrap(); }
let task = self.tasks.pop_first().unwrap(); std::cmp::Ordering::Equal => {
Some(Work{ let scope = self.scopes.pop_first().unwrap();
scope: scope, let task = self.tasks.pop_first().unwrap();
rerun_scope: true, Some(Work {
tasks: task.tasks_queued.into_inner(), scope: scope,
}) rerun_scope: true,
tasks: task.tasks_queued.into_inner(),
})
}
} }
} }
(Some(scope), None) => { (Some(scope), None) => {
let scope = self.scopes.pop_first().unwrap(); let scope = self.scopes.pop_first().unwrap();
Some(Work{ Some(Work {
scope: scope, scope: scope,
rerun_scope: true, rerun_scope: true,
tasks: Vec::new(), tasks: Vec::new(),
@ -117,13 +120,13 @@ impl DirtyScopes {
} }
(None, Some(task)) => { (None, Some(task)) => {
let task = self.tasks.pop_first().unwrap(); let task = self.tasks.pop_first().unwrap();
Some(Work{ Some(Work {
scope: task.order, scope: task.order,
rerun_scope: false, rerun_scope: false,
tasks: task.tasks_queued.into_inner(), tasks: task.tasks_queued.into_inner(),
}) })
} }
(None, None) => None (None, None) => None,
} }
} }
@ -132,6 +135,7 @@ impl DirtyScopes {
} }
} }
#[derive(Debug)]
pub struct Work { pub struct Work {
pub scope: ScopeOrder, pub scope: ScopeOrder,
pub rerun_scope: bool, pub rerun_scope: bool,
@ -154,7 +158,6 @@ impl From<ScopeOrder> for DirtyTasks {
} }
impl DirtyTasks { impl DirtyTasks {
pub fn queue_task(&self, task: Task) { pub fn queue_task(&self, task: Task) {
self.tasks_queued.borrow_mut().push(task); self.tasks_queued.borrow_mut().push(task);
} }

View file

@ -32,7 +32,6 @@ impl RenderSignal {
waker: None, waker: None,
})); }));
self.wakers.borrow_mut().push(inner.clone()); self.wakers.borrow_mut().push(inner.clone());
println!("RenderSignalFutureInner");
let waker = RenderSignalFuture { inner }; let waker = RenderSignalFuture { inner };
waker waker
} }

View file

@ -8,8 +8,8 @@ use crate::{
any_props::AnyProps, any_props::AnyProps,
arena::ElementId, arena::ElementId,
innerlude::{ innerlude::{
DirtyScopes, ElementRef, ErrorBoundary, NoOpMutations, SchedulerMsg, ScopeState, VNodeMount, DirtyScopes, ElementRef, ErrorBoundary, NoOpMutations, SchedulerMsg, ScopeState,
VProps, WriteMutations, VNodeMount, VProps, WriteMutations,
}, },
nodes::RenderReturn, nodes::RenderReturn,
nodes::{Template, TemplateId}, nodes::{Template, TemplateId},
@ -185,7 +185,6 @@ pub struct VirtualDom {
pub(crate) scopes: Slab<ScopeState>, pub(crate) scopes: Slab<ScopeState>,
pub(crate) dirty_scopes: DirtyScopes, pub(crate) dirty_scopes: DirtyScopes,
pub(crate) scopes_need_rerun: bool,
// Maps a template path to a map of byte indexes to templates // Maps a template path to a map of byte indexes to templates
pub(crate) templates: FxHashMap<TemplateId, FxHashMap<usize, Template>>, pub(crate) templates: FxHashMap<TemplateId, FxHashMap<usize, Template>>,
@ -313,7 +312,6 @@ impl VirtualDom {
rx, rx,
runtime: Runtime::new(tx), runtime: Runtime::new(tx),
scopes: Default::default(), scopes: Default::default(),
scopes_need_rerun: false,
dirty_scopes: Default::default(), dirty_scopes: Default::default(),
templates: Default::default(), templates: Default::default(),
queued_templates: Default::default(), queued_templates: Default::default(),
@ -378,7 +376,6 @@ impl VirtualDom {
}; };
tracing::trace!("Marking scope {:?} as dirty", id); tracing::trace!("Marking scope {:?} as dirty", id);
self.scopes_need_rerun = true;
let order = ScopeOrder::new(scope.height(), id); let order = ScopeOrder::new(scope.height(), id);
self.dirty_scopes.queue_scope(order); self.dirty_scopes.queue_scope(order);
} }
@ -450,7 +447,7 @@ impl VirtualDom {
self.process_events(); self.process_events();
// Now that we have collected all queued work, we should check if we have any dirty scopes. If there are not, then we can poll any queued futures // Now that we have collected all queued work, we should check if we have any dirty scopes. If there are not, then we can poll any queued futures
if self.scopes_need_rerun { if self.dirty_scopes.has_dirty_scopes() {
return; return;
} }
@ -485,7 +482,7 @@ impl VirtualDom {
self.queue_events(); self.queue_events();
// Now that we have collected all queued work, we should check if we have any dirty scopes. If there are not, then we can poll any queued futures // Now that we have collected all queued work, we should check if we have any dirty scopes. If there are not, then we can poll any queued futures
if self.scopes_need_rerun { if self.dirty_scopes.has_dirty_scopes() {
return; return;
} }
@ -498,12 +495,12 @@ impl VirtualDom {
} }
// Then poll any tasks that might be pending // Then poll any tasks that might be pending
let tasks = std::mem::take(&mut *task.tasks_queued.borrow_mut()); let tasks = task.tasks_queued.into_inner();
for task in tasks { for task in tasks {
let _ = self.runtime.handle_task_wakeup(task); let _ = self.runtime.handle_task_wakeup(task);
// Running that task, may mark a scope higher up as dirty. If it does, return from the function early // Running that task, may mark a scope higher up as dirty. If it does, return from the function early
self.queue_events(); self.queue_events();
if self.scopes_need_rerun { if self.dirty_scopes.has_dirty_scopes() {
return; return;
} }
} }
@ -602,7 +599,7 @@ impl VirtualDom {
let _runtime = RuntimeGuard::new(self.runtime.clone()); let _runtime = RuntimeGuard::new(self.runtime.clone());
// Then, poll any tasks that might be pending in the scope // Then, poll any tasks that might be pending in the scope
// This will run effects, so this **must** be done after the scope is diffed // This will run effects, so this **must** be done after the scope is diffed
for task in work.tasks{ for task in work.tasks {
let _ = self.runtime.handle_task_wakeup(task); let _ = self.runtime.handle_task_wakeup(task);
} }
// If the scope is dirty, run the scope and get the mutations // If the scope is dirty, run the scope and get the mutations
@ -615,7 +612,6 @@ impl VirtualDom {
} }
self.runtime.render_signal.send(); self.runtime.render_signal.send();
self.scopes_need_rerun = false;
} }
/// [`Self::render_immediate`] to a vector of mutations for testing purposes /// [`Self::render_immediate`] to a vector of mutations for testing purposes

View file

@ -104,10 +104,11 @@ async fn flushing() {
}); });
use_hook(|| { use_hook(|| {
spawn(async move { spawn(async move {
let mut channel = BROADCAST.with(|b| b.1.resubscribe());
for _ in 0..10 { for _ in 0..10 {
flush_sync().await; flush_sync().await;
BROADCAST.with(|b| b.1.resubscribe()).recv().await.unwrap();
println!("Task 1 recved"); println!("Task 1 recved");
channel.recv().await.unwrap();
println!("Task 1"); println!("Task 1");
SEQUENCE.with(|s| s.borrow_mut().push(1)); SEQUENCE.with(|s| s.borrow_mut().push(1));
} }
@ -116,10 +117,11 @@ async fn flushing() {
use_hook(|| { use_hook(|| {
spawn(async move { spawn(async move {
let mut channel = BROADCAST.with(|b| b.1.resubscribe());
for _ in 0..10 { for _ in 0..10 {
flush_sync().await; flush_sync().await;
BROADCAST.with(|b| b.1.resubscribe()).recv().await.unwrap();
println!("Task 2 recved"); println!("Task 2 recved");
channel.recv().await.unwrap();
println!("Task 2"); println!("Task 2");
SEQUENCE.with(|s| s.borrow_mut().push(2)); SEQUENCE.with(|s| s.borrow_mut().push(2));
} }
@ -135,16 +137,15 @@ async fn flushing() {
let fut = async { let fut = async {
// Trigger the flush by waiting for work // Trigger the flush by waiting for work
for i in 0..30 { for i in 0..10 {
BROADCAST.with(|b| b.0.send(()).unwrap()); BROADCAST.with(|b| b.0.send(()).unwrap());
tokio::select! {
_ = dom.wait_for_work() => {}
_ = tokio::time::sleep(Duration::from_millis(10)) => {}
}
dom.mark_dirty(ScopeId(0)); dom.mark_dirty(ScopeId(0));
dom.wait_for_work().await;
dom.render_immediate(&mut dioxus_core::NoOpMutations); dom.render_immediate(&mut dioxus_core::NoOpMutations);
println!("Flushed {}", i); println!("Flushed {}", i);
} }
BROADCAST.with(|b| b.0.send(()).unwrap());
dom.wait_for_work().await;
}; };
tokio::select! { tokio::select! {