total_space/
reactions.rs

1// FILE MAYBE TESTED
2
3use crate::utilities::*;
4
5/// The maximal number of alternative actions in a reaction, payloads in an activity or emitted
6/// messages within an action.
7///
8/// Making this static allows us to avoid dynamic memory allocation when computing reactions which
9/// speeds things up a lot. As a result, the size of a reaction is pretty large, but we allocate it
10/// on the stack so that seems like an acceptable trade-off.
11pub const MAX_COUNT: usize = 6;
12
13/// A message sent by an agent as part of an alternative action triggered by some event.
14#[derive(PartialEq, Eq, Copy, Clone, Debug)]
15pub enum Emit<Payload: DataLike> {
16    /// Send a message that will be delivered immediately, before any other message is delivered.
17    Immediate(Payload, usize),
18
19    /// Send an unordered message, which will be delivered at any order relative to the other
20    /// unordered messages.
21    Unordered(Payload, usize),
22
23    /// Send an ordered message, which will be delivered after delivering all previous ordered
24    /// messages from this source agent to the same target agent.
25    Ordered(Payload, usize),
26
27    /// Send an immediate message that will replace the single in-flight message accepted by the
28    /// callback, or be created as a new message is the callback accepts `None`.
29    ImmediateReplacement(fn(Option<Payload>) -> bool, Payload, usize),
30
31    /// Send an unordered message that will replace the single in-flight message accepted by the
32    /// callback, or be created as a new message is the callback accepts `None`.
33    UnorderedReplacement(fn(Option<Payload>) -> bool, Payload, usize),
34
35    /// Send an ordered message that will replace the single in-flight message accepted by the
36    /// callback, or be created as a new message is the callback accepts `None`.
37    OrderedReplacement(fn(Option<Payload>) -> bool, Payload, usize),
38}
39
40/// Specify an action the agent may take when handling an event.
41#[derive(PartialEq, Eq, Copy, Clone, Debug)]
42pub enum Action<State: KeyLike, Payload: DataLike> {
43    /// Defer the event, keep the state the same, do not send any messages.
44    ///
45    /// This is only useful if it is needed to be listed as an alternative with other actions;
46    /// Otherwise, use the `Reaction.Defer` value.
47    ///
48    /// This is only allowed if the agent's `state_is_deferring`, waiting for
49    /// specific message(s) to resume normal operations.
50    Defer,
51
52    /// Consume (ignore) the event, keep the state the same, do not send any messages.
53    ///
54    /// This is only useful if it is needed to be listed as an alternative with other actions;
55    /// Otherwise, use the `Reaction.Ignore` value.
56    Ignore,
57
58    /// Consume (handle) the event, change the agent state, do not send any messages.
59    Change(State),
60
61    /// Consume (handle) the event, keep the state the same, send a single message.
62    Send1(Emit<Payload>),
63
64    /// Consume (handle) the event, change the agent state, send a single message.
65    ChangeAndSend1(State, Emit<Payload>),
66
67    /// Consume (handle) the event, keep the state the same, send multiple messages.
68    Sends([Option<Emit<Payload>>; MAX_COUNT]),
69
70    /// Consume (handle) the event, change the agent state, send multiple messages.
71    ChangeAndSends(State, [Option<Emit<Payload>>; MAX_COUNT]),
72}
73
74/// The reaction of an agent to time passing.
75#[derive(PartialEq, Eq, Debug)]
76pub enum Activity<Payload: DataLike> {
77    /// The agent is passive, will only respond to a message.
78    Passive,
79
80    /// The agent activity generates a message, to be delivered to it for processing.
81    Process1(Payload),
82
83    /// The agent activity generates one of several messages, to be delivered to it for processing.
84    Process1Of([Option<Payload>; MAX_COUNT]),
85}
86
87/// The reaction of an agent to receiving a message.
88#[derive(PartialEq, Eq, Debug)]
89pub enum Reaction<State: KeyLike, Payload: DataLike> {
90    /// Indicate an unexpected event.
91    Unexpected,
92
93    /// Defer handling the event.
94    ///
95    /// This has the same effect as `Do1(Action.Defer)`.
96    Defer,
97
98    /// Ignore the event.
99    ///
100    /// This has the same effect as `Do1(Action.Ignore)`.
101    Ignore,
102
103    /// A single action (deterministic).
104    Do1(Action<State, Payload>),
105
106    /// One of several alternative actions (non-deterministic).
107    Do1Of([Option<Action<State, Payload>>; MAX_COUNT]),
108}