Skip to main content

bubbles/runtime/runner/
session.rs

1use super::{Runner, State};
2use crate::error::Result;
3
4impl<S: crate::value::VariableStorage> Runner<S> {
5    /// Captures the current session state into a [`RunnerSnapshot`](crate::RunnerSnapshot).
6    ///
7    /// The snapshot records the active node title, visit counts, and the set of
8    /// exhausted `<<once>>` blocks. Variable storage is **not** included; persist
9    /// it via [`Runner::storage`] alongside the snapshot when saving.
10    ///
11    /// Restoring with [`Runner::restore`] will restart execution from the beginning
12    /// of the snapshotted node.
13    ///
14    /// Enable the `serde` feature on `bubbles-dialogue` if you need `Serialize` /
15    /// `Deserialize` on [`RunnerSnapshot`](crate::RunnerSnapshot).
16    #[must_use]
17    pub fn snapshot(&self) -> crate::runtime::RunnerSnapshot {
18        crate::runtime::RunnerSnapshot {
19            current_node: self.stack.last().map(|f| f.node.as_ref().to_owned()),
20            visits: self.visits.clone(),
21            once_seen: self.once_seen.clone(),
22        }
23    }
24
25    /// Applies a previously captured `RunnerSnapshot`, restoring visit counts
26    /// and the `<<once>>` exhaustion set, then re-enters the snapshotted node
27    /// from its beginning.
28    ///
29    /// # Errors
30    ///
31    /// Returns [`crate::DialogueError::UnknownNode`] if the snapshotted node no longer
32    /// exists in the program (e.g. after a script update).
33    pub fn restore(&mut self, snapshot: crate::runtime::RunnerSnapshot) -> Result<()> {
34        self.visits = snapshot.visits;
35        self.once_seen = snapshot.once_seen;
36        self.stack.clear();
37        self.clear_event_queues();
38        self.state = State::Idle;
39        if let Some(node) = snapshot.current_node {
40            self.start(&node)?;
41        }
42        Ok(())
43    }
44}