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}