mod dynamic;
mod edit;
mod helpers;
use std::ops::{Deref, DerefMut};
use event_simulation::{
BorrowedSimulation, EditableSimulationInfo, GenericSimulationBorrow, MultiSimulation,
MultiSimulationEdit, OwnedSimulation, OwnedSimulationEdit, SimulationBorrow,
SimulationBorrowMut, SimulationInfo,
};
use pns::{Net, Pid, State, StateInitializationError, Tid, TransitionView};
pub use dynamic::{DynamicNet, DynamicNetEdit};
pub use edit::EditNet;
pub use helpers::{maximum_fire_count, maximum_unfire_count};
pub struct StateLoadingError;
pub struct PetriNetInfo(Net);
impl Deref for PetriNetInfo {
type Target = Net;
fn deref(&self) -> &Net {
&self.0
}
}
impl DerefMut for PetriNetInfo {
fn deref_mut(&mut self) -> &mut Net {
&mut self.0
}
}
impl From<Net> for PetriNetInfo {
fn from(net: Net) -> Self {
Self(net)
}
}
impl From<PetriNetInfo> for Net {
fn from(val: PetriNetInfo) -> Self {
val.0
}
}
impl SimulationInfo for PetriNetInfo {
type StateLoadingError = StateInitializationError;
type State = State;
type AccessData = [usize];
type LoadData = Vec<u32>;
type Event = Tid;
type EventContainer<'a> = TransitionView<'a>;
#[inline]
fn default_state(&self) -> State {
State::new(self)
}
#[inline]
fn load_state(&self, data: Vec<u32>) -> Result<State, StateInitializationError> {
State::from_values(self, &data)
}
#[inline]
unsafe fn clone_state(&self, state: &State) -> State {
state.clone(self)
}
#[inline]
unsafe fn data<'a>(&self, state: &'a State) -> &'a [usize] {
state.call_counts(self)
}
#[inline]
fn callables(state: &State) -> TransitionView<'_> {
state.fireable()
}
#[inline]
fn callable(state: &State, tid: Tid) -> bool {
state.fireable().contains(tid)
}
unsafe fn call(&self, state: &mut State, tid: Tid) {
state.fire_unchecked(self, tid);
}
#[inline]
fn revertables(state: &State) -> TransitionView<'_> {
state.unfireable()
}
#[inline]
fn revertable(state: &State, tid: Tid) -> bool {
state.unfireable().contains(tid)
}
unsafe fn revert(&self, state: &mut State, tid: Tid) {
state.unfire_unchecked(self, tid);
}
}
impl EditableSimulationInfo for PetriNetInfo {
type Edit<'a> = EditNet<'a>;
#[inline]
unsafe fn edit(&mut self) -> EditNet<'_> {
EditNet::new(self)
}
#[inline]
unsafe fn refresh_state(&self, state: &mut Self::State) {
state.refresh(self)
}
}
pub trait SimulationExtensions {
fn token_count(&self, pid: Pid) -> usize;
}
impl SimulationExtensions for PetriNetSimulation {
fn token_count(&self, pid: Pid) -> usize {
unsafe { self.state.token_count(self, pid) }
}
}
impl SimulationExtensions for BorrowedPetriNetSimulation<'_> {
fn token_count(&self, pid: Pid) -> usize {
unsafe { self.state.token_count(self, pid) }
}
}
impl<R: Deref<Target = State>> SimulationExtensions
for GenericSimulationBorrow<'_, PetriNetInfo, R>
{
fn token_count(&self, pid: Pid) -> usize {
unsafe { self.state.token_count(self, pid) }
}
}
pub type PetriNetSimulation = OwnedSimulation<PetriNetInfo>;
pub type BorrowedPetriNetSimulation<'a> = BorrowedSimulation<'a, PetriNetInfo>;
pub type MultiPetriNetSimulation = MultiSimulation<PetriNetInfo>;
pub type PetriNetSimulationBorrow<'a> = SimulationBorrow<'a, PetriNetInfo>;
pub type PetriNetSimulationBorrowMut<'a> = SimulationBorrowMut<'a, PetriNetInfo>;
pub type PetriNetEdit<'a> = OwnedSimulationEdit<'a, PetriNetInfo>;
pub type MultiPetriNetEdit<'a> = MultiSimulationEdit<'a, PetriNetInfo>;