use std::fmt::Debug;
use dyn_clone::DynClone;
use rand::rngs::StdRng;
use crate::{
containers::{Bag, Mail, Outputs, Value},
time::Time,
};
impl Debug for Box<dyn Dynamic> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let val = self.state();
Debug::fmt(&val, f)
}
}
impl Default for Box<dyn Dynamic> {
fn default() -> Self {
Box::new(DefaultDynamic)
}
}
#[allow(unused_variables)]
pub trait Dynamic: DynClone + Send {
fn init(&mut self, init_time: Time, rng: &mut StdRng) {}
fn internal_transition(&mut self, sim_time: Time, rng: &mut StdRng) {}
fn external_transition(
&mut self,
sim_time: Time,
elapsed: Time,
x_bag: &Bag,
rng: &mut StdRng,
) {
}
fn external_mail_transition(
&mut self,
sim_time: Time,
elapsed: Time,
mail: &Mail,
rng: &mut StdRng,
) {
}
fn confluent_transition(&mut self, sim_time: Time, x_bag: &Bag, rng: &mut StdRng) {
unimplemented!("Simulation reaches confluent_transition, but it is not implemented!")
}
fn output(&self, sim_time: Time, outputs: &mut Outputs) {}
fn time_advance(&self, rng: &mut StdRng) -> Time;
fn state(&self) -> Value;
fn finish(&self, sim_time: Time) {}
}
impl Clone for Box<dyn Dynamic> {
fn clone(&self) -> Self {
dyn_clone::clone_box(&**self)
}
}
#[derive(Clone)]
pub struct DefaultDynamic;
impl Dynamic for DefaultDynamic {
fn time_advance(&self, _: &mut StdRng) -> Time {
Time::Inf
}
fn state(&self) -> Value {
Value::Null
}
}