From 3c1056d699c81d9a699594e1272a20c8f90e0068 Mon Sep 17 00:00:00 2001 From: Serge Barral Date: Fri, 15 Nov 2024 17:15:25 +0100 Subject: [PATCH] Remove the LineId API This was probably never used. --- asynchronix/src/ports.rs | 8 -- asynchronix/src/ports/output.rs | 82 +++++-------------- asynchronix/src/ports/output/broadcaster.rs | 86 ++++---------------- asynchronix/src/ports/source.rs | 71 +++-------------- asynchronix/src/ports/source/broadcaster.rs | 87 +++++---------------- asynchronix/src/simulation.rs | 41 ---------- 6 files changed, 64 insertions(+), 311 deletions(-) diff --git a/asynchronix/src/ports.rs b/asynchronix/src/ports.rs index dc23659..f57f93e 100644 --- a/asynchronix/src/ports.rs +++ b/asynchronix/src/ports.rs @@ -91,11 +91,3 @@ pub use sink::{ event_buffer::EventBuffer, event_slot::EventSlot, EventSink, EventSinkStream, EventSinkWriter, }; pub use source::{EventSource, QuerySource, ReplyReceiver}; - -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -/// Unique identifier for a connection between two ports. -pub struct LineId(u64); - -/// Error raised when the specified line cannot be found. -#[derive(Copy, Clone, Debug)] -pub struct LineError {} diff --git a/asynchronix/src/ports/output.rs b/asynchronix/src/ports/output.rs index 574f6bf..e8dff63 100644 --- a/asynchronix/src/ports/output.rs +++ b/asynchronix/src/ports/output.rs @@ -4,7 +4,7 @@ mod sender; use std::fmt; use crate::model::Model; -use crate::ports::{EventSink, LineError, LineId}; +use crate::ports::EventSink; use crate::ports::{InputFn, ReplierFn}; use crate::simulation::Address; use crate::util::cached_rw_lock::CachedRwLock; @@ -43,20 +43,20 @@ impl Output { /// The input port must be an asynchronous method of a model of type `M` /// taking as argument a value of type `T` plus, optionally, a scheduler /// reference. - pub fn connect(&mut self, input: F, address: impl Into>) -> LineId + pub fn connect(&mut self, input: F, address: impl Into>) where M: Model, F: for<'a> InputFn<'a, M, T, S> + Clone, S: Send + 'static, { let sender = Box::new(InputSender::new(input, address.into().0)); - self.broadcaster.write().unwrap().add(sender) + self.broadcaster.write().unwrap().add(sender); } /// Adds a connection to an event sink such as an /// [`EventSlot`](crate::ports::EventSlot) or /// [`EventBuffer`](crate::ports::EventBuffer). - pub fn connect_sink>(&mut self, sink: &S) -> LineId { + pub fn connect_sink>(&mut self, sink: &S) { let sender = Box::new(EventSinkSender::new(sink.writer())); self.broadcaster.write().unwrap().add(sender) } @@ -70,12 +70,7 @@ impl Output { /// The input port must be an asynchronous method of a model of type `M` /// taking as argument a value of the type returned by the mapping /// closure plus, optionally, a context reference. - pub fn map_connect( - &mut self, - map: C, - input: F, - address: impl Into>, - ) -> LineId + pub fn map_connect(&mut self, map: C, input: F, address: impl Into>) where M: Model, C: Fn(&T) -> U + Send + Sync + 'static, @@ -84,7 +79,7 @@ impl Output { S: Send + 'static, { let sender = Box::new(MapInputSender::new(map, input, address.into().0)); - self.broadcaster.write().unwrap().add(sender) + self.broadcaster.write().unwrap().add(sender); } /// Adds an auto-converting connection to an event sink such as an @@ -93,14 +88,14 @@ impl Output { /// /// Events are mapped to another type using the closure provided in /// argument. - pub fn map_connect_sink(&mut self, map: C, sink: &S) -> LineId + pub fn map_connect_sink(&mut self, map: C, sink: &S) where C: Fn(&T) -> U + Send + Sync + 'static, U: Send + 'static, S: EventSink, { let sender = Box::new(MapEventSinkSender::new(map, sink.writer())); - self.broadcaster.write().unwrap().add(sender) + self.broadcaster.write().unwrap().add(sender); } /// Adds an auto-converting, filtered connection to an input port of the @@ -117,8 +112,7 @@ impl Output { filter_map: C, input: F, address: impl Into>, - ) -> LineId - where + ) where M: Model, C: Fn(&T) -> Option + Send + Sync + 'static, F: for<'a> InputFn<'a, M, U, S> + Clone, @@ -130,7 +124,7 @@ impl Output { input, address.into().0, )); - self.broadcaster.write().unwrap().add(sender) + self.broadcaster.write().unwrap().add(sender); } /// Adds an auto-converting connection to an event sink such as an @@ -139,33 +133,14 @@ impl Output { /// /// Events are mapped to another type using the closure provided in /// argument. - pub fn filter_map_connect_sink(&mut self, filter_map: C, sink: &S) -> LineId + pub fn filter_map_connect_sink(&mut self, filter_map: C, sink: &S) where C: Fn(&T) -> Option + Send + Sync + 'static, U: Send + 'static, S: EventSink, { let sender = Box::new(FilterMapEventSinkSender::new(filter_map, sink.writer())); - self.broadcaster.write().unwrap().add(sender) - } - - /// Removes the connection specified by the `LineId` parameter. - /// - /// It is a logic error to specify a line identifier from another - /// [`Output`], [`Requestor`], [`EventSource`](crate::ports::EventSource) or - /// [`QuerySource`](crate::ports::QuerySource) instance and may result in - /// the disconnection of an arbitrary endpoint. - pub fn disconnect(&mut self, line_id: LineId) -> Result<(), LineError> { - if self.broadcaster.write().unwrap().remove(line_id) { - Ok(()) - } else { - Err(LineError {}) - } - } - - /// Removes all connections. - pub fn disconnect_all(&mut self) { - self.broadcaster.write().unwrap().clear(); + self.broadcaster.write().unwrap().add(sender); } /// Broadcasts an event to all connected input ports. @@ -219,14 +194,14 @@ impl Requestor { /// The replier port must be an asynchronous method of a model of type `M` /// returning a value of type `R` and taking as argument a value of type `T` /// plus, optionally, a context reference. - pub fn connect(&mut self, replier: F, address: impl Into>) -> LineId + pub fn connect(&mut self, replier: F, address: impl Into>) where M: Model, F: for<'a> ReplierFn<'a, M, T, R, S> + Clone, S: Send + 'static, { let sender = Box::new(ReplierSender::new(replier, address.into().0)); - self.broadcaster.write().unwrap().add(sender) + self.broadcaster.write().unwrap().add(sender); } /// Adds an auto-converting connection to a replier port of the model @@ -245,8 +220,7 @@ impl Requestor { reply_map: D, replier: F, address: impl Into>, - ) -> LineId - where + ) where M: Model, C: Fn(&T) -> U + Send + Sync + 'static, D: Fn(Q) -> R + Send + Sync + 'static, @@ -261,7 +235,7 @@ impl Requestor { replier, address.into().0, )); - self.broadcaster.write().unwrap().add(sender) + self.broadcaster.write().unwrap().add(sender); } /// Adds an auto-converting, filtered connection to a replier port of the @@ -280,8 +254,7 @@ impl Requestor { reply_map: D, replier: F, address: impl Into>, - ) -> LineId - where + ) where M: Model, C: Fn(&T) -> Option + Send + Sync + 'static, D: Fn(Q) -> R + Send + Sync + 'static, @@ -296,26 +269,7 @@ impl Requestor { replier, address.into().0, )); - self.broadcaster.write().unwrap().add(sender) - } - - /// Removes the connection specified by the `LineId` parameter. - /// - /// It is a logic error to specify a line identifier from another - /// [`Requestor`], [`Output`], [`EventSource`](crate::ports::EventSource) or - /// [`QuerySource`](crate::ports::QuerySource) instance and may result in - /// the disconnection of an arbitrary endpoint. - pub fn disconnect(&mut self, line_id: LineId) -> Result<(), LineError> { - if self.broadcaster.write().unwrap().remove(line_id) { - Ok(()) - } else { - Err(LineError {}) - } - } - - /// Removes all connections. - pub fn disconnect_all(&mut self) { - self.broadcaster.write().unwrap().clear(); + self.broadcaster.write().unwrap().add(sender); } /// Broadcasts a query to all connected replier ports. diff --git a/asynchronix/src/ports/output/broadcaster.rs b/asynchronix/src/ports/output/broadcaster.rs index 4b7a36b..f271414 100644 --- a/asynchronix/src/ports/output/broadcaster.rs +++ b/asynchronix/src/ports/output/broadcaster.rs @@ -6,7 +6,6 @@ use std::task::{Context, Poll}; use diatomic_waker::WakeSink; use super::sender::{RecycledFuture, SendError, Sender}; -use super::LineId; use crate::util::task_set::TaskSet; /// An object that can efficiently broadcast messages to several addresses. @@ -24,10 +23,8 @@ use crate::util::task_set::TaskSet; /// - the outputs of all sender futures are returned all at once rather than /// with an asynchronous iterator (a.k.a. async stream). pub(super) struct BroadcasterInner { - /// Line identifier for the next port to be connected. - next_line_id: u64, /// The list of senders with their associated line identifier. - senders: Vec<(LineId, Box>)>, + senders: Vec>>, /// Fields explicitly borrowed by the `BroadcastFuture`. shared: Shared, } @@ -38,42 +35,17 @@ impl BroadcasterInner { /// # Panics /// /// This method will panic if the total count of senders would reach - /// `u32::MAX - 1`. - pub(super) fn add(&mut self, sender: Box>) -> LineId { - assert!(self.next_line_id != u64::MAX); - let line_id = LineId(self.next_line_id); - self.next_line_id += 1; - - self.senders.push((line_id, sender)); + /// `u32::MAX - 1` due to limitations inherent to the task set + /// implementation. + pub(super) fn add(&mut self, sender: Box>) { + assert!(self.senders.len() < (u32::MAX as usize - 2)); + self.senders.push(sender); self.shared.outputs.push(None); // The storage is alway an empty vector so we just book some capacity. if let Some(storage) = self.shared.storage.as_mut() { let _ = storage.try_reserve(self.senders.len()); }; - - line_id - } - - /// Removes the first sender with the specified identifier, if any. - /// - /// Returns `true` if there was indeed a sender associated to the specified - /// identifier. - pub(super) fn remove(&mut self, id: LineId) -> bool { - if let Some(pos) = self.senders.iter().position(|s| s.0 == id) { - self.senders.swap_remove(pos); - self.shared.outputs.truncate(self.senders.len()); - - return true; - } - - false - } - - /// Removes all senders. - pub(super) fn clear(&mut self) { - self.senders.clear(); - self.shared.outputs.clear(); } /// Returns the number of connected senders. @@ -98,13 +70,13 @@ impl BroadcasterInner { while let Some(sender) = iter.next() { // Move the argument rather than clone it for the last future. if iter.len() == 0 { - if let Some(fut) = sender.1.send_owned(arg) { + if let Some(fut) = sender.send_owned(arg) { futures.push(fut); } break; } - if let Some(fut) = sender.1.send(&arg) { + if let Some(fut) = sender.send(&arg) { futures.push(fut); } } @@ -120,7 +92,6 @@ impl Default for BroadcasterInner { let wake_src = wake_sink.source(); Self { - next_line_id: 0, senders: Vec::new(), shared: Shared { wake_sink, @@ -135,7 +106,6 @@ impl Default for BroadcasterInner { impl Clone for BroadcasterInner { fn clone(&self) -> Self { Self { - next_line_id: self.next_line_id, senders: self.senders.clone(), shared: self.shared.clone(), } @@ -160,24 +130,12 @@ impl EventBroadcaster { /// # Panics /// /// This method will panic if the total count of senders would reach - /// `u32::MAX - 1`. - pub(super) fn add(&mut self, sender: Box>) -> LineId { + /// `u32::MAX - 1` due to limitations inherent to the task set + /// implementation. + pub(super) fn add(&mut self, sender: Box>) { self.inner.add(sender) } - /// Removes the first sender with the specified identifier, if any. - /// - /// Returns `true` if there was indeed a sender associated to the specified - /// identifier. - pub(super) fn remove(&mut self, id: LineId) -> bool { - self.inner.remove(id) - } - - /// Removes all senders. - pub(super) fn clear(&mut self) { - self.inner.clear(); - } - /// Returns the number of connected senders. pub(super) fn len(&self) -> usize { self.inner.len() @@ -190,7 +148,7 @@ impl EventBroadcaster { [] => Ok(()), // One sender at most. - [sender] => match sender.1.send_owned(arg) { + [sender] => match sender.send_owned(arg) { None => Ok(()), Some(fut) => fut.await.map_err(|_| BroadcastError {}), }, @@ -233,24 +191,12 @@ impl QueryBroadcaster { /// # Panics /// /// This method will panic if the total count of senders would reach - /// `u32::MAX - 1`. - pub(super) fn add(&mut self, sender: Box>) -> LineId { + /// `u32::MAX - 1` due to limitations inherent to the task set + /// implementation. + pub(super) fn add(&mut self, sender: Box>) { self.inner.add(sender) } - /// Removes the first sender with the specified identifier, if any. - /// - /// Returns `true` if there was indeed a sender associated to the specified - /// identifier. - pub(super) fn remove(&mut self, id: LineId) -> bool { - self.inner.remove(id) - } - - /// Removes all senders. - pub(super) fn clear(&mut self) { - self.inner.clear(); - } - /// Returns the number of connected senders. pub(super) fn len(&self) -> usize { self.inner.len() @@ -267,7 +213,7 @@ impl QueryBroadcaster { // One sender at most. [sender] => { - if let Some(fut) = sender.1.send_owned(arg) { + if let Some(fut) = sender.send_owned(arg) { let output = fut.await.map_err(|_| BroadcastError {})?; self.inner.shared.outputs[0] = Some(output); diff --git a/asynchronix/src/ports/source.rs b/asynchronix/src/ports/source.rs index 3a92481..53bbd44 100644 --- a/asynchronix/src/ports/source.rs +++ b/asynchronix/src/ports/source.rs @@ -7,7 +7,6 @@ use std::time::Duration; use crate::model::Model; use crate::ports::InputFn; -use crate::ports::{LineError, LineId}; use crate::simulation::{ Action, ActionKey, Address, KeyedOnceAction, KeyedPeriodicAction, OnceAction, PeriodicAction, }; @@ -43,14 +42,14 @@ impl EventSource { /// The input port must be an asynchronous method of a model of type `M` /// taking as argument a value of type `T` plus, optionally, a scheduler /// reference. - pub fn connect(&mut self, input: F, address: impl Into>) -> LineId + pub fn connect(&mut self, input: F, address: impl Into>) where M: Model, F: for<'a> InputFn<'a, M, T, S> + Clone, S: Send + 'static, { let sender = Box::new(InputSender::new(input, address.into().0)); - self.broadcaster.lock().unwrap().add(sender) + self.broadcaster.lock().unwrap().add(sender); } /// Adds an auto-converting connection to an input port of the model @@ -62,12 +61,7 @@ impl EventSource { /// The input port must be an asynchronous method of a model of type `M` /// taking as argument a value of the type returned by the mapping closure /// plus, optionally, a context reference. - pub fn map_connect( - &mut self, - map: C, - input: F, - address: impl Into>, - ) -> LineId + pub fn map_connect(&mut self, map: C, input: F, address: impl Into>) where M: Model, C: for<'a> Fn(&'a T) -> U + Send + 'static, @@ -76,7 +70,7 @@ impl EventSource { S: Send + 'static, { let sender = Box::new(MapInputSender::new(map, input, address.into().0)); - self.broadcaster.lock().unwrap().add(sender) + self.broadcaster.lock().unwrap().add(sender); } /// Adds an auto-converting, filtered connection to an input port of the @@ -93,8 +87,7 @@ impl EventSource { map: C, input: F, address: impl Into>, - ) -> LineId - where + ) where M: Model, C: for<'a> Fn(&'a T) -> Option + Send + 'static, F: for<'a> InputFn<'a, M, U, S> + Clone, @@ -102,26 +95,7 @@ impl EventSource { S: Send + 'static, { let sender = Box::new(FilterMapInputSender::new(map, input, address.into().0)); - self.broadcaster.lock().unwrap().add(sender) - } - - /// Removes the connection specified by the `LineId` parameter. - /// - /// It is a logic error to specify a line identifier from another - /// [`EventSource`], [`QuerySource`], [`Output`](crate::ports::Output) or - /// [`Requestor`](crate::ports::Requestor) instance and may result in the - /// disconnection of an arbitrary endpoint. - pub fn disconnect(&mut self, line_id: LineId) -> Result<(), LineError> { - if self.broadcaster.lock().unwrap().remove(line_id) { - Ok(()) - } else { - Err(LineError {}) - } - } - - /// Removes all connections. - pub fn disconnect_all(&mut self) { - self.broadcaster.lock().unwrap().clear(); + self.broadcaster.lock().unwrap().add(sender); } /// Returns an action which, when processed, broadcasts an event to all @@ -248,14 +222,14 @@ impl QuerySource { /// The replier port must be an asynchronous method of a model of type `M` /// returning a value of type `R` and taking as argument a value of type `T` /// plus, optionally, a context reference. - pub fn connect(&mut self, replier: F, address: impl Into>) -> LineId + pub fn connect(&mut self, replier: F, address: impl Into>) where M: Model, F: for<'a> ReplierFn<'a, M, T, R, S> + Clone, S: Send + 'static, { let sender = Box::new(ReplierSender::new(replier, address.into().0)); - self.broadcaster.lock().unwrap().add(sender) + self.broadcaster.lock().unwrap().add(sender); } /// Adds an auto-converting connection to a replier port of the model @@ -274,8 +248,7 @@ impl QuerySource { reply_map: D, replier: F, address: impl Into>, - ) -> LineId - where + ) where M: Model, C: for<'a> Fn(&'a T) -> U + Send + 'static, D: Fn(Q) -> R + Send + Sync + 'static, @@ -290,7 +263,7 @@ impl QuerySource { replier, address.into().0, )); - self.broadcaster.lock().unwrap().add(sender) + self.broadcaster.lock().unwrap().add(sender); } /// Adds an auto-converting, filtered connection to a replier port of the @@ -309,8 +282,7 @@ impl QuerySource { reply_map: D, replier: F, address: impl Into>, - ) -> LineId - where + ) where M: Model, C: for<'a> Fn(&'a T) -> Option + Send + 'static, D: Fn(Q) -> R + Send + Sync + 'static, @@ -325,26 +297,7 @@ impl QuerySource { replier, address.into().0, )); - self.broadcaster.lock().unwrap().add(sender) - } - - /// Removes the connection specified by the `LineId` parameter. - /// - /// It is a logic error to specify a line identifier from another - /// [`QuerySource`], [`EventSource`], [`Output`](crate::ports::Output) or - /// [`Requestor`](crate::ports::Requestor) instance and may result in the - /// disconnection of an arbitrary endpoint. - pub fn disconnect(&mut self, line_id: LineId) -> Result<(), LineError> { - if self.broadcaster.lock().unwrap().remove(line_id) { - Ok(()) - } else { - Err(LineError {}) - } - } - - /// Removes all connections. - pub fn disconnect_all(&mut self) { - self.broadcaster.lock().unwrap().clear(); + self.broadcaster.lock().unwrap().add(sender); } /// Returns an action which, when processed, broadcasts a query to all diff --git a/asynchronix/src/ports/source/broadcaster.rs b/asynchronix/src/ports/source/broadcaster.rs index 136cdfa..55cfe4d 100644 --- a/asynchronix/src/ports/source/broadcaster.rs +++ b/asynchronix/src/ports/source/broadcaster.rs @@ -10,7 +10,6 @@ use diatomic_waker::WakeSink; use super::sender::{Sender, SenderFuture}; -use crate::ports::LineId; use crate::util::task_set::TaskSet; /// An object that can efficiently broadcast messages to several addresses. @@ -24,10 +23,8 @@ use crate::util::task_set::TaskSet; /// does, but the outputs of all sender futures are returned all at once rather /// than with an asynchronous iterator (a.k.a. async stream). pub(super) struct BroadcasterInner { - /// Line identifier for the next port to be connected. - next_line_id: u64, /// The list of senders with their associated line identifier. - senders: Vec<(LineId, Box>)>, + senders: Vec>>, } impl BroadcasterInner { @@ -36,34 +33,11 @@ impl BroadcasterInner { /// # Panics /// /// This method will panic if the total count of senders would reach - /// `u32::MAX - 1`. - pub(super) fn add(&mut self, sender: Box>) -> LineId { - assert!(self.next_line_id != u64::MAX); - let line_id = LineId(self.next_line_id); - self.next_line_id += 1; - - self.senders.push((line_id, sender)); - - line_id - } - - /// Removes the first sender with the specified identifier, if any. - /// - /// Returns `true` if there was indeed a sender associated to the specified - /// identifier. - pub(super) fn remove(&mut self, id: LineId) -> bool { - if let Some(pos) = self.senders.iter().position(|s| s.0 == id) { - self.senders.swap_remove(pos); - - return true; - } - - false - } - - /// Removes all senders. - pub(super) fn clear(&mut self) { - self.senders.clear(); + /// `u32::MAX - 1` due to limitations inherent to the task set + /// implementation. + pub(super) fn add(&mut self, sender: Box>) { + assert!(self.senders.len() < (u32::MAX as usize - 2)); + self.senders.push(sender); } /// Returns the number of connected senders. @@ -81,12 +55,12 @@ impl BroadcasterInner { while let Some(sender) = iter.next() { // Move the argument for the last future to avoid undue cloning. if iter.len() == 0 { - if let Some(fut) = sender.1.send_owned(arg) { + if let Some(fut) = sender.send_owned(arg) { future_states.push(SenderFutureState::Pending(fut)); } break; } - if let Some(fut) = sender.1.send(&arg) { + if let Some(fut) = sender.send(&arg) { future_states.push(SenderFutureState::Pending(fut)); } } @@ -98,7 +72,6 @@ impl BroadcasterInner { impl Default for BroadcasterInner { fn default() -> Self { Self { - next_line_id: 0, senders: Vec::new(), } } @@ -121,22 +94,10 @@ impl EventBroadcaster { /// # Panics /// /// This method will panic if the total count of senders would reach - /// `u32::MAX - 1`. - pub(super) fn add(&mut self, sender: Box>) -> LineId { - self.inner.add(sender) - } - - /// Removes the first sender with the specified identifier, if any. - /// - /// Returns `true` if there was indeed a sender associated to the specified - /// identifier. - pub(super) fn remove(&mut self, id: LineId) -> bool { - self.inner.remove(id) - } - - /// Removes all senders. - pub(super) fn clear(&mut self) { - self.inner.clear(); + /// `u32::MAX - 1` due to limitations inherent to the task set + /// implementation. + pub(super) fn add(&mut self, sender: Box>) { + self.inner.add(sender); } /// Returns the number of connected senders. @@ -159,7 +120,7 @@ impl EventBroadcaster { // No sender. [] => Fut::Empty, // One sender at most. - [sender] => Fut::Single(sender.1.send_owned(arg)), + [sender] => Fut::Single(sender.send_owned(arg)), // Possibly multiple senders. _ => Fut::Multiple(self.inner.futures(arg)), }; @@ -209,22 +170,10 @@ impl QueryBroadcaster { /// # Panics /// /// This method will panic if the total count of senders would reach - /// `u32::MAX - 1`. - pub(super) fn add(&mut self, sender: Box>) -> LineId { - self.inner.add(sender) - } - - /// Removes the first sender with the specified identifier, if any. - /// - /// Returns `true` if there was indeed a sender associated to the specified - /// identifier. - pub(super) fn remove(&mut self, id: LineId) -> bool { - self.inner.remove(id) - } - - /// Removes all senders. - pub(super) fn clear(&mut self) { - self.inner.clear(); + /// `u32::MAX - 1` due to limitations inherent to the task set + /// implementation. + pub(super) fn add(&mut self, sender: Box>) { + self.inner.add(sender); } /// Returns the number of connected senders. @@ -247,7 +196,7 @@ impl QueryBroadcaster { // No sender. [] => Fut::Empty, // One sender at most. - [sender] => Fut::Single(sender.1.send_owned(arg)), + [sender] => Fut::Single(sender.send_owned(arg)), // Possibly multiple senders. _ => Fut::Multiple(self.inner.futures(arg)), }; diff --git a/asynchronix/src/simulation.rs b/asynchronix/src/simulation.rs index ee173a0..e3c949b 100644 --- a/asynchronix/src/simulation.rs +++ b/asynchronix/src/simulation.rs @@ -76,47 +76,6 @@ //! Any deadlocks will be reported as an [`ExecutionError::Deadlock`] error, //! which identifies all involved models and the amount of unprocessed messages //! (events or requests) in their mailboxes. -//! -//! ## Modifying connections during simulation -//! -//! Although uncommon, there is sometimes a need for connecting and/or -//! disconnecting models after they have been migrated to the simulation. -//! Likewise, one may want to connect or disconnect an -//! [`EventSlot`](crate::ports::EventSlot) or -//! [`EventBuffer`](crate::ports::EventBuffer) after the simulation has been -//! instantiated. -//! -//! There is actually a very simple solution to this problem: since the -//! [`InputFn`] trait also matches closures of type `FnOnce(&mut impl Model)`, -//! it is enough to invoke [`Simulation::process_event()`] with a closure that -//! connects or disconnects a port, such as: -//! -//! ``` -//! # use asynchronix::model::{Context, Model}; -//! # use asynchronix::ports::Output; -//! # use asynchronix::time::MonotonicTime; -//! # use asynchronix::simulation::{Mailbox, SimInit}; -//! # pub struct ModelA { -//! # pub output: Output, -//! # } -//! # impl Model for ModelA {}; -//! # pub struct ModelB {} -//! # impl ModelB { -//! # pub fn input(&mut self, value: i32) {} -//! # } -//! # impl Model for ModelB {}; -//! # let modelA_addr = Mailbox::::new().address(); -//! # let modelB_addr = Mailbox::::new().address(); -//! # let mut simu = SimInit::new().init(MonotonicTime::EPOCH)?.0; -//! simu.process_event( -//! |m: &mut ModelA| { -//! m.output.connect(ModelB::input, modelB_addr); -//! }, -//! (), -//! &modelA_addr -//! )?; -//! # Ok::<(), asynchronix::simulation::SimulationError>(()) -//! ``` mod mailbox; mod scheduler; mod sim_init;