event_simulation/
multi.rs

1use std::ops::{Deref, DerefMut};
2
3use crate::{Editable, EditableSimulationInfo};
4
5use super::{Simulation, SimulationInfo};
6
7/// A simulation with support for multiple states.
8pub struct MultiSimulation<Info: SimulationInfo> {
9    info: Info,
10    states: Vec<Info::State>,
11}
12
13impl<Info: SimulationInfo> MultiSimulation<Info> {
14    /// Creates a new `MultiSimulation` from the provided `info` with no states.
15    pub fn new<T: Into<Info>>(info: T) -> Self {
16        Self {
17            info: info.into(),
18            states: Vec::new(),
19        }
20    }
21
22    /// Adds a new simulation state to the simulation and returns its index.
23    pub fn add_simulation(&mut self) -> usize {
24        let index = self.states.len();
25        self.states.push(Info::default_state(&self.info));
26        index
27    }
28
29    /// Adds a new simulation state loaded from the provided `data` to the simulation and returns its index.
30    pub fn add_simulation_from_data(
31        &mut self,
32        data: Info::LoadData,
33    ) -> Result<usize, Info::StateLoadingError> {
34        let index = self.states.len();
35        self.states.push(Info::load_state(&self.info, data)?);
36        Ok(index)
37    }
38
39    /// Retrieves an immutable borrow of the simulation at the specified index.
40    pub fn get(&self, index: usize) -> Option<SimulationBorrow<'_, Info>> {
41        let state = self.states.get(index)?;
42        Some(SimulationBorrow {
43            info: &self.info,
44            state,
45        })
46    }
47
48    /// Retrieves a mutable borrow of the simulation at the specified index.
49    pub fn get_mut(&mut self, index: usize) -> Option<SimulationBorrowMut<'_, Info>> {
50        let state = self.states.get_mut(index)?;
51        Some(SimulationBorrowMut {
52            info: &self.info,
53            state,
54        })
55    }
56
57    /// Get access to all simulation states.
58    pub fn states(&self) -> &[Info::State] {
59        &self.states
60    }
61
62    /// Get mutable access to all simulation states.
63    pub fn states_mut(&mut self) -> &mut [Info::State] {
64        &mut self.states
65    }
66
67    /// Returns an iterator over the simulation states.
68    pub fn iter(&self) -> Iter<'_, Info> {
69        self.into_iter()
70    }
71
72    /// Returns a mutable iterator over the simulation states.
73    pub fn iter_mut(&mut self) -> IterMut<'_, Info> {
74        self.into_iter()
75    }
76
77    /// Release the info from the simulation again and destroys all states.
78    pub fn release(self) -> Info {
79        self.info
80    }
81}
82
83impl<Info: SimulationInfo + Clone> Clone for MultiSimulation<Info> {
84    fn clone(&self) -> Self {
85        let info = self.info.clone();
86        let states = self
87            .states
88            .iter()
89            .map(|state| unsafe { info.clone_state(state) })
90            .collect();
91        Self { info, states }
92    }
93}
94
95impl<Info: SimulationInfo> Deref for MultiSimulation<Info> {
96    type Target = Info;
97
98    fn deref(&self) -> &Info {
99        &self.info
100    }
101}
102
103/// A generic struct representing a borrowed simulation with an immutable or mutable reference to the state.
104pub struct GenericSimulationBorrow<'a, Info: SimulationInfo, StateRef> {
105    info: &'a Info,
106    /// The referenced simulation state.
107    pub state: StateRef,
108}
109
110impl<Info: SimulationInfo, S> Deref for GenericSimulationBorrow<'_, Info, S> {
111    type Target = Info;
112
113    fn deref(&self) -> &Info {
114        self.info
115    }
116}
117
118/// Represents a single immutable simulation.
119pub type SimulationBorrow<'a, Info> =
120    GenericSimulationBorrow<'a, Info, &'a <Info as SimulationInfo>::State>;
121
122/// Represents a single mutable simulation.
123pub type SimulationBorrowMut<'a, Info> =
124    GenericSimulationBorrow<'a, Info, &'a mut <Info as SimulationInfo>::State>;
125
126/// An iterator over the simulation states.
127pub struct Iter<'a, Info: SimulationInfo> {
128    info: &'a Info,
129    states: std::slice::Iter<'a, Info::State>,
130}
131
132/// A mutable iterator over the simulation states.
133pub struct IterMut<'a, Info: SimulationInfo> {
134    info: &'a Info,
135    states: std::slice::IterMut<'a, Info::State>,
136}
137
138impl<'a, Info: SimulationInfo> IntoIterator for &'a MultiSimulation<Info> {
139    type Item = SimulationBorrow<'a, Info>;
140    type IntoIter = Iter<'a, Info>;
141
142    fn into_iter(self) -> Self::IntoIter {
143        Iter {
144            info: &self.info,
145            states: self.states.iter(),
146        }
147    }
148}
149
150impl<'a, Info: SimulationInfo> IntoIterator for &'a mut MultiSimulation<Info> {
151    type Item = SimulationBorrowMut<'a, Info>;
152    type IntoIter = IterMut<'a, Info>;
153
154    fn into_iter(self) -> Self::IntoIter {
155        IterMut {
156            info: &self.info,
157            states: self.states.iter_mut(),
158        }
159    }
160}
161
162impl<'a, Info: SimulationInfo> Iterator for Iter<'a, Info> {
163    type Item = SimulationBorrow<'a, Info>;
164
165    fn next(&mut self) -> Option<Self::Item> {
166        let state = self.states.next()?;
167        Some(SimulationBorrow {
168            info: self.info,
169            state,
170        })
171    }
172}
173
174impl<'a, Info: SimulationInfo> Iterator for IterMut<'a, Info> {
175    type Item = SimulationBorrowMut<'a, Info>;
176
177    fn next(&mut self) -> Option<Self::Item> {
178        let state = self.states.next()?;
179        Some(SimulationBorrowMut {
180            info: self.info,
181            state,
182        })
183    }
184}
185
186impl<Info: SimulationInfo> Simulation for SimulationBorrowMut<'_, Info> {
187    type StateLoadingError = Info::StateLoadingError;
188    type AccessData = Info::AccessData;
189    type LoadData = Info::LoadData;
190    type Event = Info::Event;
191    type EventContainer<'a> = Info::EventContainer<'a>
192    where
193        Self: 'a;
194
195    #[inline]
196    fn data(&self) -> &Info::AccessData {
197        unsafe { self.info.data(self.state) }
198    }
199
200    #[inline]
201    fn reload(&mut self, data: Info::LoadData) -> Result<(), Info::StateLoadingError> {
202        *self.state = self.info.load_state(data)?;
203        Ok(())
204    }
205
206    #[inline]
207    fn callables(&self) -> Info::EventContainer<'_> {
208        Info::callables(self.state)
209    }
210
211    #[inline]
212    fn callable(&self, event: Info::Event) -> bool {
213        Info::callable(self.state, event)
214    }
215
216    #[inline]
217    unsafe fn call(&mut self, event: Info::Event) {
218        self.info.call(self.state, event)
219    }
220
221    #[inline]
222    fn revertables(&self) -> Info::EventContainer<'_> {
223        Info::revertables(self.state)
224    }
225
226    #[inline]
227    fn revertable(&self, event: Info::Event) -> bool {
228        Info::revertable(self.state, event)
229    }
230
231    #[inline]
232    unsafe fn revert(&mut self, event: Info::Event) {
233        self.info.revert(self.state, event)
234    }
235}
236
237impl<Info: EditableSimulationInfo> Editable for MultiSimulation<Info> {
238    type Edit<'a> = MultiSimulationEdit<'a, Info>
239    where
240        Self: 'a;
241
242    fn edit(&mut self) -> MultiSimulationEdit<'_, Info> {
243        let edit = unsafe { self.info.edit() };
244        MultiSimulationEdit {
245            edit,
246            states: &mut self.states,
247        }
248    }
249}
250
251/// Helper type for safely editing the info of a multi simulation without invalidating the state.
252pub struct MultiSimulationEdit<'a, Info: EditableSimulationInfo + 'a> {
253    edit: Info::Edit<'a>,
254    states: &'a mut [Info::State],
255}
256
257impl<Info: EditableSimulationInfo> Drop for MultiSimulationEdit<'_, Info> {
258    fn drop(&mut self) {
259        for state in self.states.iter_mut() {
260            unsafe { self.edit.refresh_state(state) }
261        }
262    }
263}
264
265impl<'a, Info: EditableSimulationInfo> Deref for MultiSimulationEdit<'a, Info> {
266    type Target = Info::Edit<'a>;
267    fn deref(&self) -> &Info::Edit<'a> {
268        &self.edit
269    }
270}
271
272impl<'a, Info: EditableSimulationInfo> DerefMut for MultiSimulationEdit<'a, Info> {
273    fn deref_mut(&mut self) -> &mut Info::Edit<'a> {
274        &mut self.edit
275    }
276}