clean up the task queue
This commit is contained in:
1 parent
c7ffdc7b29
commit
26f5fb80cb
2 files changed
+56
-24
No files matched your search
+30
-4
@@ -12,11 +12,37 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
let mut count = use_signal(|| 0);
|
let mut vec = use_signal(|| vec![1, 2, 3]);
|
||||||
|
|
||||||
|
let len = vec.len();
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
h1 { "High-Five counter: {count}" }
|
button {
|
||||||
button { onclick: move |_| count += 1, "Up high!" }
|
onclick: move |_| {
|
||||||
button { onclick: move |_| count -= 1, "Down low!" }
|
let mut vec = vec.write();
|
||||||
|
vec.push(len);
|
||||||
|
},
|
||||||
|
"Add"
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
onclick: move |_| {
|
||||||
|
vec.pop();
|
||||||
|
},
|
||||||
|
"Remove"
|
||||||
|
}
|
||||||
|
for i in 0..len {
|
||||||
|
Child {
|
||||||
|
index: i,
|
||||||
|
vec,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn Child(index: usize, vec: Signal<Vec<usize>>) -> Element {
|
||||||
|
let item = use_memo(move || vec.read()[index]);
|
||||||
|
rsx! {
|
||||||
|
div { "Item: {item}" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -479,25 +479,6 @@ impl VirtualDom {
|
|||||||
// Make sure we set the runtime since we're running user code
|
// Make sure we set the runtime since we're running user code
|
||||||
let _runtime = RuntimeGuard::new(self.runtime.clone());
|
let _runtime = RuntimeGuard::new(self.runtime.clone());
|
||||||
|
|
||||||
// Next, run any queued tasks
|
|
||||||
// We choose not to poll the deadline since we complete pretty quickly anyways
|
|
||||||
while let Some(dirty) = self.dirty_scopes.pop_first() {
|
|
||||||
// If the scope doesn't exist for whatever reason, then we should skip it
|
|
||||||
if !self.scopes.contains(dirty.order.id.0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then poll any tasks that might be pending
|
|
||||||
for task in dirty.tasks_queued.borrow().iter() {
|
|
||||||
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
|
|
||||||
self.process_events();
|
|
||||||
if self.scopes_need_rerun {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hold a lock to the flush sync to prevent tasks from running in the event we get an immediate
|
// Hold a lock to the flush sync to prevent tasks from running in the event we get an immediate
|
||||||
// When we're doing awaiting the rx, the lock will be dropped and tasks waiting on the lock will get waked
|
// When we're doing awaiting the rx, the lock will be dropped and tasks waiting on the lock will get waked
|
||||||
// We have to own the lock since poll_tasks is cancel safe - the future that this is running in might get dropped
|
// We have to own the lock since poll_tasks is cancel safe - the future that this is running in might get dropped
|
||||||
@@ -528,6 +509,30 @@ impl VirtualDom {
|
|||||||
SchedulerMsg::TaskNotified(task) => self.mark_task_dirty(task),
|
SchedulerMsg::TaskNotified(task) => self.mark_task_dirty(task),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, run any queued tasks
|
||||||
|
// We choose not to poll the deadline since we complete pretty quickly anyways
|
||||||
|
while let Some(dirty) = self.dirty_scopes.pop_first() {
|
||||||
|
// If the scope doesn't exist for whatever reason, then we should skip it
|
||||||
|
if !self.scopes.contains(dirty.order.id.0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then poll any tasks that might be pending
|
||||||
|
for task in dirty.tasks_queued.borrow().iter() {
|
||||||
|
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
|
||||||
|
self.process_events();
|
||||||
|
if self.scopes_need_rerun {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace a template at runtime. This will re-render all components that use this template.
|
/// Replace a template at runtime. This will re-render all components that use this template.
|
||||||
@@ -619,7 +624,8 @@ impl VirtualDom {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let _runtime = RuntimeGuard::new(self.runtime.clone());
|
let _runtime = RuntimeGuard::new(self.runtime.clone());
|
||||||
// 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
|
||||||
for task in dirty.tasks_queued.borrow().iter() {
|
for task in dirty.tasks_queued.borrow().iter() {
|
||||||
let _ = self.runtime.handle_task_wakeup(*task);
|
let _ = self.runtime.handle_task_wakeup(*task);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user