xdevs/traits.rs
1use crate::simulator::Config;
2use core::future::Future;
3
4/// Trait that defines the methods that a DEVS event bag set must implement.
5///
6/// # Safety
7///
8/// This trait must be implemented via macros. Do not implement it manually.
9pub unsafe trait Bag {
10 /// Returns `true` if the ports are empty.
11 fn is_empty(&self) -> bool;
12
13 /// Clears the ports, removing all values.
14 fn clear(&mut self);
15}
16
17/// Interface for DEVS components. All DEVS components must implement this trait.
18///
19/// # Safety
20///
21/// This trait must be implemented via macros. Do not implement it manually.
22pub unsafe trait Component {
23 /// Input event bag of the model.
24 type Input: Bag;
25
26 /// Output event bag of the model.
27 type Output: Bag;
28
29 /// Returns the last time the component was updated.
30 fn get_t_last(&self) -> f64;
31
32 /// Sets the last time the component was updated.
33 fn set_t_last(&mut self, t_last: f64);
34
35 /// Returns the next time the component will be updated.
36 fn get_t_next(&self) -> f64;
37
38 /// Sets the next time the component will be updated.
39 fn set_t_next(&mut self, t_next: f64);
40
41 /// Returns a reference to the model's input event bag.
42 fn get_input(&self) -> &Self::Input;
43
44 /// Returns a mutable reference to the model's input event bag.
45 fn get_input_mut(&mut self) -> &mut Self::Input;
46
47 /// Returns a reference to the model's output event bag.
48 fn get_output(&self) -> &Self::Output;
49
50 /// Returns a mutable reference to the model's output event bag.
51 fn get_output_mut(&mut self) -> &mut Self::Output;
52
53 /// Clears the input bag, removing all values.
54 #[inline]
55 fn clear_input(&mut self) {
56 self.get_input_mut().clear()
57 }
58
59 /// Clears the output bag, removing all values.
60 #[inline]
61 fn clear_output(&mut self) {
62 self.get_output_mut().clear()
63 }
64}
65
66/// Partial interface for DEVS atomic models.
67/// It is used as a helper trait to implement the [`crate::Atomic`] trait.
68///
69/// # Safety
70///
71/// This trait must be implemented via macros. Do not implement it manually.
72pub unsafe trait PartialAtomic: Component {
73 /// The data type used to represent the state of the model.
74 type State;
75}
76
77/// Interface for simulating DEVS models. All DEVS models must implement this trait.
78///
79/// # Safety
80///
81/// This trait must be implemented via macros. Do not implement it manually.
82pub unsafe trait AbstractSimulator: Component {
83 /// It starts the simulation, setting the initial time to t_start.
84 /// It returns the time for the next state transition of the inner DEVS model.
85 fn start(&mut self, t_start: f64) -> f64;
86
87 /// It stops the simulation, setting the last time to t_stop.
88 fn stop(&mut self, t_stop: f64);
89
90 /// Executes output functions and propagates messages according to EOCs.
91 /// Internally, it checks that the model is imminent before executing.
92 fn lambda(&mut self, t: f64);
93
94 /// Propagates messages according to ICs and EICs and executes model transition functions.
95 /// It also clears all the input and output ports.
96 /// Internally, it checks that the model is imminent before executing.
97 /// Finally, it returns the time for the next state transition of the inner DEVS model.
98 fn delta(&mut self, t: f64) -> f64;
99}
100
101/// Interface for handling input events in an asynchronous DEVS simulation.
102///
103/// Unlike other traits, this trait must be implemented by the user, as it is not generated by macros.
104/// It allows the model to handle input events asynchronously, waiting for external events without blocking the simulation.
105pub trait AsyncInput {
106 /// Set this to the input event bag type of your model under study.
107 type Input: Bag;
108
109 /// Handles input events asynchronously.
110 ///
111 /// It receives the time interval `[t_from, t_until]` and a mutable reference to the input event bag.
112 /// It returns the time of the next event, which is usually the time of the next state transition.
113 /// If an external event occurs, it should inject the event to the input and return the time at which the event happened.
114 fn handle(
115 &mut self,
116 config: &Config,
117 t_from: f64,
118 t_until: f64,
119 input: &mut Self::Input,
120 ) -> impl Future<Output = f64>;
121}