Files
dioxus/packages/core/src/effect.rs
T
Evan Almloff 5290b658fd Fix effects triggered from async tasks; improve work scheduling docs (#2370)
* outline work scheduling

* move scheduling code from dirty_scope to scheduler

* introduce queue_effect

* Run effects after all tasks are polled if there are no components rerendered

* add a new test for async effects
2024-05-04 15:30:13 +01:00

67 lines
1.9 KiB
Rust

use crate::innerlude::ScopeOrder;
use crate::Runtime;
use std::borrow::Borrow;
use std::cell::RefCell;
use std::collections::VecDeque;
/// Effects will always run after all changes to the DOM have been applied.
///
/// Effects are the lowest priority task in the scheduler.
/// They are run after all other dirty scopes and futures have been resolved. Other dirty scopes and futures may cause the component this effect is attached to to rerun, which would update the DOM.
pub(crate) struct Effect {
// The scope that the effect is attached to
pub(crate) order: ScopeOrder,
// The callbacks that will be run when effects are rerun
effect: RefCell<VecDeque<Box<dyn FnOnce() + 'static>>>,
}
impl Effect {
pub(crate) fn new(order: ScopeOrder, f: impl FnOnce() + 'static) -> Self {
let mut effect = VecDeque::new();
effect.push_back(Box::new(f) as Box<dyn FnOnce() + 'static>);
Self {
order,
effect: RefCell::new(effect),
}
}
pub(crate) fn push_back(&self, f: impl FnOnce() + 'static) {
self.effect.borrow_mut().push_back(Box::new(f));
}
pub(crate) fn run(&self, runtime: &Runtime) {
runtime.rendering.set(false);
let mut effect = self.effect.borrow_mut();
while let Some(f) = effect.pop_front() {
f();
}
runtime.rendering.set(true);
}
}
impl PartialOrd for Effect {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.order.cmp(&other.order))
}
}
impl Ord for Effect {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.order.cmp(&other.order)
}
}
impl PartialEq for Effect {
fn eq(&self, other: &Self) -> bool {
self.order == other.order
}
}
impl Eq for Effect {}
impl Borrow<ScopeOrder> for Effect {
fn borrow(&self) -> &ScopeOrder {
&self.order
}
}