use core::pin::pin;
use odem_rs::{
prelude::*,
sync::chain::Chain,
tracing::{Level, debug},
};
#[derive(Config, Default)]
struct TrainSim {
platform: Chain, cabin: Chain, }
struct Passenger;
impl Behavior<TrainSim> for Passenger {
type Output = ();
async fn actions(&self, sim: &Sim<TrainSim>) {
let TrainSim { platform, cabin } = sim.global();
platform.fifo().await;
debug!("entering cabin");
sim.advance(1.0).await; platform.notify_one();
cabin.lifo().await;
debug!("leaving cabin");
sim.advance(1.0).await; cabin.notify_one(); }
}
struct Train;
impl Behavior<TrainSim> for Train {
type Output = ();
async fn actions(&self, sim: &Sim<TrainSim>) {
let TrainSim { platform, cabin } = sim.global();
sim.advance(1.0).await; debug!("arriving in source station");
platform.notify_one();
sim.advance(2.0).await;
debug!("departing source station");
sim.advance(1.0).await; debug!("arriving at destination");
cabin.notify_one(); sim.advance(2.0).await; }
}
async fn train_sim(sim: &Sim<TrainSim>) {
let passengers = pin!(Pool::dynamic().with(Agent::new));
let train = pin!(Agent::new(Train));
sim.activate(train);
for _ in 0..2 {
sim.activate(passengers.alloc(Passenger));
}
sim.advance(10.0).await;
}
fn main() {
tracing_subscriber::fmt()
.with_max_level(Level::DEBUG)
.with_target(false)
.with_timer(model_time!("[{time}]"))
.init();
simulation(train_sim).expect("no deadlock should be possible");
}