use std::ops::{Deref, DerefMut};
use crate::{Editable, EditableSimulationInfo};
use super::{Simulation, SimulationInfo};
pub struct MultiSimulation<Info: SimulationInfo> {
info: Info,
states: Vec<Info::State>,
}
impl<Info: SimulationInfo> MultiSimulation<Info> {
pub fn new<T: Into<Info>>(info: T) -> Self {
Self {
info: info.into(),
states: Vec::new(),
}
}
pub fn add_simulation(&mut self) -> usize {
let index = self.states.len();
self.states.push(Info::default_state(&self.info));
index
}
pub fn add_simulation_from_data(
&mut self,
data: Info::LoadData,
) -> Result<usize, Info::StateLoadingError> {
let index = self.states.len();
self.states.push(Info::load_state(&self.info, data)?);
Ok(index)
}
pub fn get(&self, index: usize) -> Option<SimulationBorrow<'_, Info>> {
let state = self.states.get(index)?;
Some(SimulationBorrow {
info: &self.info,
state,
})
}
pub fn get_mut(&mut self, index: usize) -> Option<SimulationBorrowMut<'_, Info>> {
let state = self.states.get_mut(index)?;
Some(SimulationBorrowMut {
info: &self.info,
state,
})
}
pub fn states(&self) -> &[Info::State] {
&self.states
}
pub fn states_mut(&mut self) -> &mut [Info::State] {
&mut self.states
}
pub fn iter(&self) -> Iter<'_, Info> {
self.into_iter()
}
pub fn iter_mut(&mut self) -> IterMut<'_, Info> {
self.into_iter()
}
pub fn release(self) -> Info {
self.info
}
}
impl<Info: SimulationInfo + Clone> Clone for MultiSimulation<Info> {
fn clone(&self) -> Self {
let info = self.info.clone();
let states = self
.states
.iter()
.map(|state| unsafe { info.clone_state(state) })
.collect();
Self { info, states }
}
}
impl<Info: SimulationInfo> Deref for MultiSimulation<Info> {
type Target = Info;
fn deref(&self) -> &Info {
&self.info
}
}
pub struct GenericSimulationBorrow<'a, Info: SimulationInfo, StateRef> {
info: &'a Info,
pub state: StateRef,
}
impl<Info: SimulationInfo, S> Deref for GenericSimulationBorrow<'_, Info, S> {
type Target = Info;
fn deref(&self) -> &Info {
self.info
}
}
pub type SimulationBorrow<'a, Info> =
GenericSimulationBorrow<'a, Info, &'a <Info as SimulationInfo>::State>;
pub type SimulationBorrowMut<'a, Info> =
GenericSimulationBorrow<'a, Info, &'a mut <Info as SimulationInfo>::State>;
pub struct Iter<'a, Info: SimulationInfo> {
info: &'a Info,
states: std::slice::Iter<'a, Info::State>,
}
pub struct IterMut<'a, Info: SimulationInfo> {
info: &'a Info,
states: std::slice::IterMut<'a, Info::State>,
}
impl<'a, Info: SimulationInfo> IntoIterator for &'a MultiSimulation<Info> {
type Item = SimulationBorrow<'a, Info>;
type IntoIter = Iter<'a, Info>;
fn into_iter(self) -> Self::IntoIter {
Iter {
info: &self.info,
states: self.states.iter(),
}
}
}
impl<'a, Info: SimulationInfo> IntoIterator for &'a mut MultiSimulation<Info> {
type Item = SimulationBorrowMut<'a, Info>;
type IntoIter = IterMut<'a, Info>;
fn into_iter(self) -> Self::IntoIter {
IterMut {
info: &self.info,
states: self.states.iter_mut(),
}
}
}
impl<'a, Info: SimulationInfo> Iterator for Iter<'a, Info> {
type Item = SimulationBorrow<'a, Info>;
fn next(&mut self) -> Option<Self::Item> {
let state = self.states.next()?;
Some(SimulationBorrow {
info: self.info,
state,
})
}
}
impl<'a, Info: SimulationInfo> Iterator for IterMut<'a, Info> {
type Item = SimulationBorrowMut<'a, Info>;
fn next(&mut self) -> Option<Self::Item> {
let state = self.states.next()?;
Some(SimulationBorrowMut {
info: self.info,
state,
})
}
}
impl<Info: SimulationInfo> Simulation for SimulationBorrowMut<'_, Info> {
type StateLoadingError = Info::StateLoadingError;
type AccessData = Info::AccessData;
type LoadData = Info::LoadData;
type Event = Info::Event;
type EventContainer<'a> = Info::EventContainer<'a>
where
Self: 'a;
#[inline]
fn data(&self) -> &Info::AccessData {
unsafe { self.info.data(self.state) }
}
#[inline]
fn reload(&mut self, data: Info::LoadData) -> Result<(), Info::StateLoadingError> {
*self.state = self.info.load_state(data)?;
Ok(())
}
#[inline]
fn callables(&self) -> Info::EventContainer<'_> {
Info::callables(self.state)
}
#[inline]
fn callable(&self, event: Info::Event) -> bool {
Info::callable(self.state, event)
}
#[inline]
unsafe fn call(&mut self, event: Info::Event) {
self.info.call(self.state, event)
}
#[inline]
fn revertables(&self) -> Info::EventContainer<'_> {
Info::revertables(self.state)
}
#[inline]
fn revertable(&self, event: Info::Event) -> bool {
Info::revertable(self.state, event)
}
#[inline]
unsafe fn revert(&mut self, event: Info::Event) {
self.info.revert(self.state, event)
}
}
impl<Info: EditableSimulationInfo> Editable for MultiSimulation<Info> {
type Edit<'a> = MultiSimulationEdit<'a, Info>
where
Self: 'a;
fn edit(&mut self) -> MultiSimulationEdit<'_, Info> {
let edit = unsafe { self.info.edit() };
MultiSimulationEdit {
edit,
states: &mut self.states,
}
}
}
pub struct MultiSimulationEdit<'a, Info: EditableSimulationInfo + 'a> {
edit: Info::Edit<'a>,
states: &'a mut [Info::State],
}
impl<Info: EditableSimulationInfo> Drop for MultiSimulationEdit<'_, Info> {
fn drop(&mut self) {
for state in self.states.iter_mut() {
unsafe { self.edit.refresh_state(state) }
}
}
}
impl<'a, Info: EditableSimulationInfo> Deref for MultiSimulationEdit<'a, Info> {
type Target = Info::Edit<'a>;
fn deref(&self) -> &Info::Edit<'a> {
&self.edit
}
}
impl<'a, Info: EditableSimulationInfo> DerefMut for MultiSimulationEdit<'a, Info> {
fn deref_mut(&mut self) -> &mut Info::Edit<'a> {
&mut self.edit
}
}