use bit_set::BitSet;
use event_simulation::EditableSimulationInfo;
use std::ops::Deref;
use crate::{
Aspect, Change, EventEdit, From, InvalidChangeError, MultilinearInfo, MultilinearState, To,
};
pub struct EditMultilinearInfo<'a> {
info: &'a mut MultilinearInfo,
}
impl Deref for EditMultilinearInfo<'_> {
type Target = MultilinearInfo;
fn deref(&self) -> &MultilinearInfo {
self.info
}
}
impl<'a> EditMultilinearInfo<'a> {
pub(crate) fn new(info: &'a mut MultilinearInfo) -> Self {
Self { info }
}
pub fn add_aspect(&mut self) -> Aspect {
self.info.add_aspect()
}
pub fn add_event(&mut self) -> EventEdit<'_> {
self.info.add_event()
}
pub fn add_event_with_changes(
&mut self,
changes: &[&[Change]],
) -> Result<EventEdit<'_>, InvalidChangeError> {
let mut event = self.info.add_event();
for &change_set in changes {
event.add_change(change_set)?;
}
Ok(event)
}
}
impl EditableSimulationInfo for MultilinearInfo {
type Edit<'a> = EditMultilinearInfo<'a>;
unsafe fn edit(&mut self) -> EditMultilinearInfo<'_> {
EditMultilinearInfo::new(self)
}
unsafe fn refresh_state(&self, state: &mut MultilinearState) {
state.values.resize(self.aspects.len(), 0);
state.callables = BitSet::new();
state.revertables = BitSet::new();
for (index, event) in self.events.iter().enumerate() {
if event.check_action::<From>(&state.values) {
state.callables.insert(index);
}
if event.check_action::<To>(&state.values) {
state.revertables.insert(index);
}
}
}
}