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