iced_devtools/
time_machine.rs

1use crate::Program;
2
3#[cfg(feature = "time-travel")]
4pub struct TimeMachine<P>
5where
6    P: Program,
7{
8    state: Option<P::State>,
9    messages: Vec<P::Message>,
10}
11
12#[cfg(feature = "time-travel")]
13impl<P> TimeMachine<P>
14where
15    P: Program,
16{
17    pub fn new() -> Self {
18        Self {
19            state: None,
20            messages: Vec::new(),
21        }
22    }
23
24    pub fn is_rewinding(&self) -> bool {
25        self.state.is_some()
26    }
27
28    pub fn push(&mut self, message: &P::Message) {
29        self.messages.push(message.clone());
30    }
31
32    pub fn rewind(&mut self, program: &P, message: usize) {
33        let (mut state, _) = program.boot();
34
35        if message < self.messages.len() {
36            // TODO: Run concurrently (?)
37            for message in &self.messages[0..message] {
38                let _ = program.update(&mut state, message.clone());
39            }
40        }
41
42        self.state = Some(state);
43        crate::debug::disable();
44    }
45
46    pub fn go_to_present(&mut self) {
47        self.state = None;
48        crate::debug::enable();
49    }
50
51    pub fn state(&self) -> Option<&P::State> {
52        self.state.as_ref()
53    }
54}
55
56#[cfg(not(feature = "time-travel"))]
57pub struct TimeMachine<P>
58where
59    P: Program,
60{
61    _program: std::marker::PhantomData<P>,
62}
63
64#[cfg(not(feature = "time-travel"))]
65impl<P> TimeMachine<P>
66where
67    P: Program,
68{
69    pub fn new() -> Self {
70        Self {
71            _program: std::marker::PhantomData,
72        }
73    }
74
75    pub fn is_rewinding(&self) -> bool {
76        false
77    }
78
79    pub fn push(&mut self, _message: &P::Message) {}
80
81    pub fn rewind(&mut self, _program: &P, _message: usize) {}
82
83    pub fn go_to_present(&mut self) {}
84
85    pub fn state(&self) -> Option<&P::State> {
86        None
87    }
88}