Skip to main content

event_simulation/
multi.rs

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