diff --git a/src/models/exclusive_gateway.rs b/src/models/exclusive_gateway.rs index 5806325..00e852b 100644 --- a/src/models/exclusive_gateway.rs +++ b/src/models/exclusive_gateway.rs @@ -48,8 +48,6 @@ struct PortsOut { #[serde(rename_all = "camelCase")] struct State { event_list: Vec, - #[serde(default)] - global_time: f64, } impl Default for State { @@ -60,7 +58,6 @@ impl Default for State { }; State { event_list: vec![initalization_event], - global_time: 0.0, } } } @@ -134,6 +131,7 @@ impl AsModel for ExclusiveGateway { &mut self, uniform_rng: &mut UniformRNG, incoming_message: ModelMessage, + global_time: f64, ) -> Result, SimulationError> { let mut outgoing_messages: Vec = Vec::new(); let port_number = self.port_weights.random_variate(uniform_rng)?; @@ -142,7 +140,7 @@ impl AsModel for ExclusiveGateway { self.snapshot.last_job = Some(( self.ports_out.flow_paths[port_number].clone(), incoming_message.content.clone(), - self.state.global_time, + global_time, )); } if self.need_historical_metrics() { @@ -159,6 +157,7 @@ impl AsModel for ExclusiveGateway { fn events_int( &mut self, _uniform_rng: &mut UniformRNG, + _global_time: f64, ) -> Result, SimulationError> { let events = self.state.event_list.clone(); self.state.event_list = self @@ -184,7 +183,6 @@ impl AsModel for ExclusiveGateway { .for_each(|scheduled_event| { scheduled_event.time -= time_delta; }); - self.state.global_time += time_delta; } fn until_next_event(&self) -> f64 { diff --git a/src/models/gate.rs b/src/models/gate.rs index 8c9c2a9..b300207 100644 --- a/src/models/gate.rs +++ b/src/models/gate.rs @@ -49,8 +49,6 @@ struct State { event_list: Vec, jobs: Vec, phase: Phase, - #[serde(default)] - global_time: f64, } impl Default for State { @@ -63,7 +61,6 @@ impl Default for State { event_list: vec![initalization_event], jobs: Vec::new(), phase: Phase::Open, - global_time: 0.0, } } } @@ -162,13 +159,14 @@ impl AsModel for Gate { &mut self, _uniform_rng: &mut UniformRNG, incoming_message: ModelMessage, + global_time: f64, ) -> Result, SimulationError> { let incoming_port: &str = &incoming_message.port_name; match &self.ports_in { PortsIn { activation, .. } if activation == incoming_port => { // Possible metrics updates if self.need_snapshot_metrics() { - self.snapshot.last_activation = Some(self.state.global_time); + self.snapshot.last_activation = Some(global_time); self.snapshot.is_open = Some(true); } if self.need_historical_metrics() { @@ -180,7 +178,7 @@ impl AsModel for Gate { PortsIn { deactivation, .. } if deactivation == incoming_port => { // Possible metrics updates if self.need_snapshot_metrics() { - self.snapshot.last_deactivation = Some(self.state.global_time); + self.snapshot.last_deactivation = Some(global_time); self.snapshot.is_open = Some(false); } if self.need_historical_metrics() { @@ -193,7 +191,7 @@ impl AsModel for Gate { // Possible metrics updates if self.need_snapshot_metrics() { self.snapshot.last_received = - Some((incoming_message.content.clone(), self.state.global_time)); + Some((incoming_message.content.clone(), global_time)); } if self.need_historical_metrics() { self.history.push(self.snapshot.clone()); @@ -219,6 +217,7 @@ impl AsModel for Gate { fn events_int( &mut self, _uniform_rng: &mut UniformRNG, + _global_time: f64, ) -> Result, SimulationError> { let mut outgoing_messages: Vec = Vec::new(); let events = self.state.event_list.clone(); @@ -270,7 +269,6 @@ impl AsModel for Gate { .for_each(|scheduled_event| { scheduled_event.time -= time_delta; }); - self.state.global_time += time_delta; } fn until_next_event(&self) -> f64 { diff --git a/src/models/generator.rs b/src/models/generator.rs index 8442aab..d12b5bf 100644 --- a/src/models/generator.rs +++ b/src/models/generator.rs @@ -55,8 +55,6 @@ struct State { event_list: Vec, until_message_interdeparture: f64, job_counter: usize, - #[serde(default)] - global_time: f64, } impl Default for State { @@ -69,7 +67,6 @@ impl Default for State { event_list: vec![initalization_event], until_message_interdeparture: INFINITY, job_counter: 0, - global_time: 0.0, } } } @@ -147,6 +144,7 @@ impl AsModel for Generator { &mut self, _uniform_rng: &mut UniformRNG, _incoming_message: ModelMessage, + _global_time: f64, ) -> Result, SimulationError> { Ok(Vec::new()) } @@ -154,6 +152,7 @@ impl AsModel for Generator { fn events_int( &mut self, uniform_rng: &mut UniformRNG, + global_time: f64, ) -> Result, SimulationError> { let mut outgoing_messages: Vec = Vec::new(); let events = self.state.event_list.clone(); @@ -185,8 +184,7 @@ impl AsModel for Generator { event: Event::BeginGeneration, }); if let Some(thinning) = self.thinning.clone() { - let thinning_threshold = - thinning.evaluate(self.state.global_time)?; + let thinning_threshold = thinning.evaluate(global_time)?; let uniform_rn = uniform_rng.rn(); if uniform_rn < thinning_threshold { self.state.event_list.push(ScheduledEvent { @@ -214,8 +212,7 @@ impl AsModel for Generator { }); // Possible metrics updates if self.need_snapshot_metrics() { - self.snapshot.last_generation = - Some((generated, self.state.global_time)); + self.snapshot.last_generation = Some((generated, global_time)); } if self.need_historical_metrics() { self.history.push(self.snapshot.clone()); @@ -236,7 +233,6 @@ impl AsModel for Generator { .for_each(|scheduled_event| { scheduled_event.time -= time_delta; }); - self.state.global_time += time_delta; } fn until_next_event(&self) -> f64 { diff --git a/src/models/load_balancer.rs b/src/models/load_balancer.rs index 5ef2b60..d24ed45 100644 --- a/src/models/load_balancer.rs +++ b/src/models/load_balancer.rs @@ -44,8 +44,6 @@ struct State { event_list: Vec, jobs: Vec, next_port_out: usize, - #[serde(default)] - global_time: f64, } impl Default for State { @@ -58,7 +56,6 @@ impl Default for State { event_list: vec![initalization_event], jobs: Vec::new(), next_port_out: 0, - global_time: 0.0, } } } @@ -131,6 +128,7 @@ impl AsModel for LoadBalancer { &mut self, _uniform_rng: &mut UniformRNG, incoming_message: ModelMessage, + _global_time: f64, ) -> Result, SimulationError> { self.state.jobs.push(incoming_message.content); self.state.event_list.push(ScheduledEvent { @@ -143,6 +141,7 @@ impl AsModel for LoadBalancer { fn events_int( &mut self, _uniform_rng: &mut UniformRNG, + global_time: f64, ) -> Result, SimulationError> { let mut outgoing_messages: Vec = Vec::new(); let events = self.state.event_list.clone(); @@ -164,7 +163,7 @@ impl AsModel for LoadBalancer { self.snapshot.last_job = Some(( self.ports_out.flow_paths[self.state.next_port_out].clone(), self.state.jobs[0].clone(), - self.state.global_time, + global_time, )); } if self.need_historical_metrics() { @@ -189,7 +188,6 @@ impl AsModel for LoadBalancer { .for_each(|scheduled_event| { scheduled_event.time -= time_delta; }); - self.state.global_time += time_delta; } fn until_next_event(&self) -> f64 { diff --git a/src/models/model.rs b/src/models/model.rs index fa8c2f2..d1aa6f1 100644 --- a/src/models/model.rs +++ b/src/models/model.rs @@ -42,15 +42,18 @@ impl AsModel for Model { &mut self, uniform_rng: &mut UniformRNG, incoming_message: ModelMessage, + global_time: f64, ) -> Result, SimulationError> { - self.inner.events_ext(uniform_rng, incoming_message) + self.inner + .events_ext(uniform_rng, incoming_message, global_time) } fn events_int( &mut self, uniform_rng: &mut UniformRNG, + global_time: f64, ) -> Result, SimulationError> { - self.inner.events_int(uniform_rng) + self.inner.events_int(uniform_rng, global_time) } fn time_advance(&mut self, time_delta: f64) { @@ -90,10 +93,12 @@ pub trait AsModel { &mut self, uniform_rng: &mut UniformRNG, incoming_message: ModelMessage, + global_time: f64, ) -> Result, SimulationError>; fn events_int( &mut self, uniform_rng: &mut UniformRNG, + global_time: f64, ) -> Result, SimulationError>; fn time_advance(&mut self, time_delta: f64); fn until_next_event(&self) -> f64; diff --git a/src/models/parallel_gateway.rs b/src/models/parallel_gateway.rs index 07e9b07..8828f82 100644 --- a/src/models/parallel_gateway.rs +++ b/src/models/parallel_gateway.rs @@ -47,8 +47,6 @@ struct PortsOut { struct State { event_list: Vec, collections: HashMap, - #[serde(default)] - global_time: f64, } impl Default for State { @@ -60,7 +58,6 @@ impl Default for State { State { event_list: vec![initalization_event], collections: HashMap::new(), - global_time: 0.0, } } } @@ -137,11 +134,11 @@ impl AsModel for ParallelGateway { &mut self, _uniform_rng: &mut UniformRNG, incoming_message: ModelMessage, + global_time: f64, ) -> Result, SimulationError> { // Possible metrics updates if self.need_snapshot_metrics() { - self.snapshot.last_arrival = - Some((incoming_message.content.clone(), self.state.global_time)); + self.snapshot.last_arrival = Some((incoming_message.content.clone(), global_time)); } if self.need_historical_metrics() { self.history.push(self.snapshot.clone()); @@ -165,6 +162,7 @@ impl AsModel for ParallelGateway { fn events_int( &mut self, _uniform_rng: &mut UniformRNG, + global_time: f64, ) -> Result, SimulationError> { let mut outgoing_messages: Vec = Vec::new(); let events = self.state.event_list.clone(); @@ -200,7 +198,7 @@ impl AsModel for ParallelGateway { // Possible metrics updates if self.need_snapshot_metrics() { self.snapshot.last_departure = - Some((completed_collection, self.state.global_time)); + Some((completed_collection, global_time)); } if self.need_historical_metrics() { self.history.push(self.snapshot.clone()); diff --git a/src/models/processor.rs b/src/models/processor.rs index 867d761..c6e5064 100644 --- a/src/models/processor.rs +++ b/src/models/processor.rs @@ -61,8 +61,6 @@ struct State { until_job_completion: f64, queue: Vec, phase: Phase, - #[serde(default)] - global_time: f64, } impl Default for State { @@ -76,7 +74,6 @@ impl Default for State { until_job_completion: INFINITY, queue: Vec::new(), phase: Phase::Passive, - global_time: 0.0, } } } @@ -174,6 +171,7 @@ impl AsModel for Processor { &mut self, _uniform_rng: &mut UniformRNG, incoming_message: ModelMessage, + global_time: f64, ) -> Result, SimulationError> { let mut outgoing_messages: Vec = Vec::new(); let incoming_port: String = incoming_message.port_name; @@ -183,8 +181,7 @@ impl AsModel for Processor { // Possible metrics updates if self.need_snapshot_metrics() { self.snapshot.queue_size = self.state.queue.len(); - self.snapshot.last_arrival = - Some((incoming_message.content, self.state.global_time)); + self.snapshot.last_arrival = Some((incoming_message.content, global_time)); } if self.need_historical_metrics() { self.history.push(self.snapshot.clone()); @@ -241,6 +238,7 @@ impl AsModel for Processor { fn events_int( &mut self, uniform_rng: &mut UniformRNG, + global_time: f64, ) -> Result, SimulationError> { let mut outgoing_messages: Vec = Vec::new(); let events = self.state.event_list.clone(); @@ -284,7 +282,7 @@ impl AsModel for Processor { .first() .ok_or_else(|| SimulationError::InvalidModelState)? .to_string(), - self.state.global_time, + global_time, )); self.snapshot.is_utilized = true; } @@ -304,7 +302,7 @@ impl AsModel for Processor { .first() .ok_or_else(|| SimulationError::InvalidModelState)? .to_string(), - self.state.global_time, + global_time, )); } // Use just the job ID from the input message - transform job type @@ -351,7 +349,6 @@ impl AsModel for Processor { .for_each(|scheduled_event| { scheduled_event.time -= time_delta; }); - self.state.global_time += time_delta; } fn until_next_event(&self) -> f64 { diff --git a/src/models/stochastic_gate.rs b/src/models/stochastic_gate.rs index e71f9f6..34c9c98 100644 --- a/src/models/stochastic_gate.rs +++ b/src/models/stochastic_gate.rs @@ -47,8 +47,6 @@ struct State { event_list: Vec, jobs: Vec, phase: Phase, - #[serde(default)] - global_time: f64, } impl Default for State { @@ -61,7 +59,6 @@ impl Default for State { event_list: vec![initalization_event], jobs: Vec::new(), phase: Phase::Open, - global_time: 0.0, } } } @@ -150,6 +147,7 @@ impl AsModel for StochasticGate { &mut self, uniform_rng: &mut UniformRNG, incoming_message: ModelMessage, + _global_time: f64, ) -> Result, SimulationError> { let incoming_port: &str = &incoming_message.port_name; match &self.ports_in { @@ -176,6 +174,7 @@ impl AsModel for StochasticGate { fn events_int( &mut self, _uniform_rng: &mut UniformRNG, + global_time: f64, ) -> Result, SimulationError> { let mut outgoing_messages: Vec = Vec::new(); let events = self.state.event_list.clone(); @@ -194,8 +193,7 @@ impl AsModel for StochasticGate { Event::DropJob => { // Possible metrics updates if self.need_snapshot_metrics() { - self.snapshot.last_block = - Some((self.state.jobs[0].clone(), self.state.global_time)); + self.snapshot.last_block = Some((self.state.jobs[0].clone(), global_time)); } if self.need_historical_metrics() { self.history.push(self.snapshot.clone()); @@ -206,8 +204,7 @@ impl AsModel for StochasticGate { Event::SendJob => { // Possible metrics updates if self.need_snapshot_metrics() { - self.snapshot.last_pass = - Some((self.state.jobs[0].clone(), self.state.global_time)); + self.snapshot.last_pass = Some((self.state.jobs[0].clone(), global_time)); } if self.need_historical_metrics() { self.history.push(self.snapshot.clone()); @@ -229,7 +226,6 @@ impl AsModel for StochasticGate { .for_each(|scheduled_event| { scheduled_event.time -= time_delta; }); - self.state.global_time += time_delta; } fn until_next_event(&self) -> f64 { diff --git a/src/models/storage.rs b/src/models/storage.rs index d0a6b2d..e6062cc 100644 --- a/src/models/storage.rs +++ b/src/models/storage.rs @@ -43,8 +43,6 @@ struct PortsOut { struct State { event_list: Vec, job: Option, - #[serde(default)] - global_time: f64, } impl Default for State { @@ -56,7 +54,6 @@ impl Default for State { State { event_list: vec![initalization_event], job: None, - global_time: 0.0, } } } @@ -137,6 +134,7 @@ impl AsModel for Storage { &mut self, _uniform_rng: &mut UniformRNG, incoming_message: ModelMessage, + global_time: f64, ) -> Result, SimulationError> { let mut outgoing_messages: Vec = Vec::new(); let incoming_port: &str = &incoming_message.port_name; @@ -145,7 +143,7 @@ impl AsModel for Storage { // Possible metrics updates if self.need_snapshot_metrics() { self.snapshot.last_store = - Some((incoming_message.content.clone(), self.state.global_time)); + Some((incoming_message.content.clone(), global_time)); } if self.need_historical_metrics() { self.history.push(self.snapshot.clone()); @@ -160,8 +158,7 @@ impl AsModel for Storage { Some(job) => { // Possible metrics updates if self.need_snapshot_metrics() { - self.snapshot.last_read = - Some((String::from(job), self.state.global_time)); + self.snapshot.last_read = Some((String::from(job), global_time)); } if self.need_historical_metrics() { self.history.push(self.snapshot.clone()); @@ -175,8 +172,7 @@ impl AsModel for Storage { None => { // Possible metrics updates if self.need_snapshot_metrics() { - self.snapshot.last_read = - Some((String::from(""), self.state.global_time)); + self.snapshot.last_read = Some((String::from(""), global_time)); } if self.need_historical_metrics() { self.history.push(self.snapshot.clone()); @@ -197,6 +193,7 @@ impl AsModel for Storage { fn events_int( &mut self, _uniform_rng: &mut UniformRNG, + _global_time: f64, ) -> Result, SimulationError> { // Currently, there is no events_int behavior except the initialization let events = self.state.event_list.clone(); @@ -223,7 +220,6 @@ impl AsModel for Storage { .for_each(|scheduled_event| { scheduled_event.time -= time_delta; }); - self.state.global_time += time_delta; } fn until_next_event(&self) -> f64 { diff --git a/src/simulator/mod.rs b/src/simulator/mod.rs index 67755da..d4608cb 100644 --- a/src/simulator/mod.rs +++ b/src/simulator/mod.rs @@ -260,6 +260,7 @@ impl Simulation { /// output. pub fn step(&mut self) -> Result, SimulationError> { let messages = self.messages.clone(); + let global_time = self.get_global_time(); let mut next_messages: Vec = Vec::new(); // Process external events and gather associated messages if !messages.is_empty() { @@ -282,7 +283,11 @@ impl Simulation { .iter() .map(|model_message| -> Result<(), SimulationError> { self.models[model_index] - .events_ext(&mut self.uniform_rng, model_message.clone())? + .events_ext( + &mut self.uniform_rng, + model_message.clone(), + global_time, + )? .iter() .for_each(|outgoing_message| { let target_ids = self.get_message_target_ids( @@ -331,7 +336,7 @@ impl Simulation { let errors: Result, SimulationError> = (0..self.models.len()) .map(|model_index| -> Result<(), SimulationError> { self.models[model_index] - .events_int(&mut self.uniform_rng)? + .events_int(&mut self.uniform_rng, global_time)? .iter() .for_each(|outgoing_message| { let target_ids = self.get_message_target_ids(