Skip to main content

anathema_runtime/runtime/
testing.rs

1use std::time::{Duration, Instant};
2
3use anathema_backend::Backend;
4use anathema_state::{Watched, Watcher, drain_watchers};
5use anathema_store::stack::Stack;
6use anathema_widgets::query::Children;
7
8use crate::Frame;
9use crate::error::Result;
10use crate::events::GlobalEventHandler;
11
12// -----------------------------------------------------------------------------
13//   - Used with test driver -
14//   These functions should not be used outside of testing
15// -----------------------------------------------------------------------------
16impl<'bp, G> Frame<'_, 'bp, G>
17where
18    G: GlobalEventHandler,
19{
20    pub fn elements(&mut self) -> Children<'_, 'bp> {
21        Children::new(
22            self.tree.view(),
23            self.layout_ctx.attribute_storage,
24            &mut self.needs_layout,
25        )
26    }
27
28    // TODO: this can't really be called a frame if we can tick it multiple
29    // times. Maybe RuntimeMut or something less mental
30    pub fn wait_for_monitor<B: Backend>(
31        &mut self,
32        backend: &mut B,
33        watcher: Watcher,
34        timeout: Duration,
35    ) -> Result<Watched> {
36        let now = Instant::now();
37
38        let mut watchers = Stack::empty();
39        drain_watchers(&mut watchers);
40
41        if watchers.contains(&watcher) {
42            return Ok(Watched::Triggered);
43        }
44
45        loop {
46            let dur = self.tick(backend)?;
47            self.present(backend);
48            self.cleanup();
49
50            drain_watchers(&mut watchers);
51
52            if watchers.contains(&watcher) {
53                return Ok(Watched::Triggered);
54            }
55
56            if timeout.saturating_sub(now.elapsed()).is_zero() {
57                break Ok(Watched::Timeout);
58            }
59
60            let sleep = self.sleep_micros - dur.as_micros() as u64;
61            std::thread::sleep(Duration::from_micros(sleep));
62        }
63    }
64}