Skip to main content

event_simulation/
owned.rs

1use std::ops::{Deref, DerefMut};
2
3use crate::{Editable, EditableSimulationInfo, Simulation, SimulationInfo, SimulationState};
4
5/// An owned simulation that holds the simulation info and the simulation state.
6pub struct OwnedSimulation<Info: SimulationInfo> {
7    info: Info,
8    /// The simulation state.
9    pub state: Info::State,
10}
11
12impl<Info: SimulationInfo> OwnedSimulation<Info> {
13    /// Creates a new `OwnedSimulation` using the specified `info`.
14    pub fn new<T: Into<Info>>(info: T) -> Self {
15        let info = info.into();
16        let state = info.default_state();
17        Self { info, state }
18    }
19
20    /// Loads a new `OwnedSimulation` from `data` using the specified `info`.
21    ///
22    /// # Errors
23    /// Returns an error if a valid state cannot be loaded from `data`.
24    pub fn from_data(info: Info, data: Info::LoadData) -> Result<Self, Info::StateLoadingError> {
25        let state = info.load_state(data)?;
26        Ok(Self { info, state })
27    }
28
29    /// Release the info from the simulation again and destroys all states.
30    pub fn release(self) -> Info {
31        self.info
32    }
33}
34
35impl<Info: SimulationInfo + Clone> Clone for OwnedSimulation<Info> {
36    fn clone(&self) -> Self {
37        let info = self.info.clone();
38        let state = unsafe { info.clone_state(&self.state) };
39        Self { info, state }
40    }
41}
42
43impl<Info: SimulationInfo> Deref for OwnedSimulation<Info> {
44    type Target = Info;
45
46    fn deref(&self) -> &Info {
47        &self.info
48    }
49}
50
51impl<Info: SimulationInfo> SimulationState for OwnedSimulation<Info> {
52    type AccessData = Info::AccessData;
53    type Event = Info::Event;
54    type EventContainer<'a>
55        = Info::EventContainer<'a>
56    where
57        Self: 'a;
58
59    #[inline]
60    fn data(&self) -> &Info::AccessData {
61        unsafe { self.info.data(&self.state) }
62    }
63
64    #[inline]
65    fn callables(&self) -> Info::EventContainer<'_> {
66        Info::callables(&self.state)
67    }
68
69    #[inline]
70    fn callable(&self, event: Info::Event) -> bool {
71        Info::callable(&self.state, event)
72    }
73
74    #[inline]
75    fn revertables(&self) -> Info::EventContainer<'_> {
76        Info::revertables(&self.state)
77    }
78
79    #[inline]
80    fn revertable(&self, event: Info::Event) -> bool {
81        Info::revertable(&self.state, event)
82    }
83}
84
85impl<Info: SimulationInfo> Simulation for OwnedSimulation<Info> {
86    type StateLoadingError = Info::StateLoadingError;
87    type LoadData = Info::LoadData;
88
89    #[inline]
90    fn reload(&mut self, data: Info::LoadData) -> Result<(), Info::StateLoadingError> {
91        self.state = self.info.load_state(data)?;
92        Ok(())
93    }
94
95    #[inline]
96    unsafe fn call(&mut self, event: Info::Event) {
97        unsafe { self.info.call(&mut self.state, event) }
98    }
99
100    #[inline]
101    unsafe fn revert(&mut self, event: Info::Event) {
102        unsafe { self.info.revert(&mut self.state, event) }
103    }
104}
105
106impl<Info: EditableSimulationInfo> Editable for OwnedSimulation<Info> {
107    type Edit<'a>
108        = OwnedSimulationEdit<'a, Info>
109    where
110        Self: 'a;
111
112    fn edit(&mut self) -> OwnedSimulationEdit<'_, Info> {
113        let edit = unsafe { self.info.edit() };
114        OwnedSimulationEdit {
115            edit,
116            state: &mut self.state,
117        }
118    }
119}
120
121/// Helper type for safely editing the info of a owned simulation without invalidating the state.
122pub struct OwnedSimulationEdit<'a, Info: EditableSimulationInfo + 'a> {
123    edit: Info::Edit<'a>,
124    state: &'a mut Info::State,
125}
126
127impl<Info: EditableSimulationInfo> Drop for OwnedSimulationEdit<'_, Info> {
128    fn drop(&mut self) {
129        unsafe { self.edit.refresh_state(self.state) }
130    }
131}
132
133impl<'a, Info: EditableSimulationInfo> Deref for OwnedSimulationEdit<'a, Info> {
134    type Target = Info::Edit<'a>;
135    fn deref(&self) -> &Info::Edit<'a> {
136        &self.edit
137    }
138}
139
140impl<'a, Info: EditableSimulationInfo> DerefMut for OwnedSimulationEdit<'a, Info> {
141    fn deref_mut(&mut self) -> &mut Info::Edit<'a> {
142        &mut self.edit
143    }
144}