1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use crate::{cached_node::CachedNode, interfaces::node::Child};
use futures::{
future::LocalFutureObj,
task::{LocalSpawn, SpawnError},
};
use moxie::runtime::RunLoop;
#[must_use]
pub struct DomLoop {
inner: RunLoop<Box<dyn FnMut()>>,
}
impl DomLoop {
pub fn new<Root: Child + 'static>(
parent: impl Into<augdom::Node>,
mut root: impl (FnMut() -> Root) + 'static,
) -> Self {
let parent = parent.into();
let mut inner = RunLoop::new(Box::new(move || {
let parent = CachedNode::new(parent.clone());
#[allow(clippy::redundant_closure)]
let new_root = topo::call(|| root());
parent.ensure_child_attached(new_root.to_bind());
parent.remove_trailing_children();
}) as Box<dyn FnMut()>);
#[cfg(feature = "webdom")]
{
inner.set_task_executor(WebSpawner);
}
Self { inner }
}
pub fn run_once(&mut self) {
self.inner.run_once();
}
}
#[cfg(feature = "rsdom")]
impl DomLoop {
#[cfg(feature = "rsdom")]
pub fn new_virtual<Root: Child + 'static>(
parent: impl Into<augdom::Node>,
root: impl (FnMut() -> Root) + 'static,
) -> Self {
Self::new(parent, augdom::in_virtual_document(root))
}
}
#[cfg(feature = "webdom")]
impl DomLoop {
pub fn animation_frame_scheduler(self) -> raf::AnimationFrameScheduler<Self> {
raf::AnimationFrameScheduler::new(self)
}
}
#[cfg(feature = "webdom")]
impl raf::Tick for DomLoop {
fn tick(&mut self) {
self.inner.run_once();
}
}
#[cfg(feature = "webdom")]
impl raf::Waking for DomLoop {
fn set_waker(&mut self, wk: std::task::Waker) {
self.inner.set_state_change_waker(wk);
}
}
#[cfg(feature = "webdom")]
struct WebSpawner;
#[cfg(feature = "webdom")]
impl LocalSpawn for WebSpawner {
fn spawn_local_obj(&self, fut: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> {
wasm_bindgen_futures::spawn_local(fut);
Ok(())
}
}