use std::f64::INFINITY;
use serde::{Deserialize, Serialize};
use sim::input_modeling::ContinuousRandomVariable;
use sim::models::model_trait::{DevsModel, Reportable, ReportableModel, SerializableModel};
use sim::models::{Generator, Model, ModelMessage, ModelRecord};
use sim::simulator::{Connector, Message, Services, Simulation, WebSimulation};
use sim::utils::errors::SimulationError;
use sim_derive::{register, SerializableModel};
use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};
#[cfg(feature = "simx")]
use simx::event_rules;
wasm_bindgen_test_configure!(run_in_browser);
#[derive(Debug, Clone, Serialize, Deserialize, SerializableModel)]
#[serde(rename_all = "camelCase")]
pub struct Passive {
ports_in: PortsIn,
#[serde(default)]
state: State,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct PortsIn {
job: String,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
struct State {
records: Vec<ModelRecord>,
}
#[cfg_attr(feature = "simx", event_rules)]
impl Passive {
pub fn new(job_port: String) -> Self {
Self {
ports_in: PortsIn { job: job_port },
state: State {
records: Vec::new(),
},
}
}
}
#[cfg_attr(feature = "simx", event_rules)]
impl DevsModel for Passive {
fn events_ext(
&mut self,
_incoming_message: &ModelMessage,
_services: &mut Services,
) -> Result<(), SimulationError> {
Ok(())
}
fn events_int(
&mut self,
_services: &mut Services,
) -> Result<Vec<ModelMessage>, SimulationError> {
Ok(Vec::new())
}
fn time_advance(&mut self, _time_delta: f64) {
}
fn until_next_event(&self) -> f64 {
INFINITY
}
}
impl Reportable for Passive {
fn status(&self) -> String {
"Passive".into()
}
fn records(&self) -> &Vec<ModelRecord> {
&self.state.records
}
}
impl ReportableModel for Passive {}
#[test]
fn step_n_with_custom_passive_model() -> Result<(), SimulationError> {
let models = [
Model::new(
String::from("generator-01"),
Box::new(Generator::new(
ContinuousRandomVariable::Exp { lambda: 0.5 },
None,
String::from("job"),
false,
)),
),
Model::new(
String::from("passive-01"),
Box::new(Passive::new(String::from("job"))),
),
];
let connectors = [Connector::new(
String::from("connector-01"),
String::from("generator-01"),
String::from("passive-01"),
String::from("job"),
String::from("job"),
)];
let mut simulation = Simulation::post(models.to_vec(), connectors.to_vec());
let messages = simulation.step_n(9)?;
let generations_count = messages.len();
let expected = 4; assert_eq!(generations_count, expected);
Ok(())
}
#[test]
#[wasm_bindgen_test]
fn step_n_with_custom_passive_model_wasm() {
let models = r#"
- type: "Generator"
id: "generator-01"
portsIn: {}
portsOut:
job: "job"
messageInterdepartureTime:
exp:
lambda: 0.5
- type: "Passive"
id: "passive-01"
portsIn:
job: "job"
"#;
let connectors = r#"
- id: "connector-01"
sourceID: "generator-01"
targetID: "passive-01"
sourcePort: "job"
targetPort: "job"
"#;
register![Passive];
let mut simulation = WebSimulation::post_yaml(&models, &connectors);
let messages: Vec<Message> = serde_json::from_str(&simulation.step_n_json(9)).unwrap();
let generations_count = messages.len();
let expected = 4; assert_eq!(generations_count, expected);
}