agent_tk/
module.rs

1//! This module contains the definition for an agent_tk module.
2
3/// Define an agent module. Each module can receive message as inputs and send via its outputs. All the messages are broadcasted. Each module has a single thread used for handling the messages. If longer computation are needed, they can spawn other modules.
4pub trait Module
5{
6  /// Type of the input message for this module
7  type InputMessage;
8  /// Type of the output message for this module
9  type OutputMessage;
10  /// Type of the private interface
11  type ModulePrivateInterface: ModulePrivateInterface<Self::InputMessage, Self::OutputMessage>;
12
13  /// This function is called ahead
14  fn prepare_interfaces(
15    cap: usize,
16  ) -> (
17    ModuleInterface<Self::InputMessage, Self::OutputMessage>,
18    Self::ModulePrivateInterface,
19  )
20  {
21    let (input_sender, input_receiver) = async_broadcast::broadcast::<Self::InputMessage>(cap);
22    let (output_sender, output_receiver) = async_broadcast::broadcast::<Self::OutputMessage>(cap);
23
24    (
25      ModuleInterface::<Self::InputMessage, Self::OutputMessage>::new(
26        input_sender,
27        output_receiver.deactivate(),
28      ),
29      ModulePrivateInterface::new(input_receiver.deactivate(), output_sender),
30    )
31  }
32}
33
34/// Private interface for modules. Created outside of the module, but passed in constructor.
35pub trait ModulePrivateInterface<InputMessage, OutputMessage>
36{
37  /// Create a new private interface
38  fn new(
39    input_receiver: async_broadcast::InactiveReceiver<InputMessage>,
40    output_sender: async_broadcast::Sender<OutputMessage>,
41  ) -> Self;
42}
43
44/// Public module interface
45#[derive(Clone)]
46pub struct ModuleInterface<InputMessage, OutputMessage>
47{
48  input_sender: async_broadcast::Sender<InputMessage>,
49  output_receiver: async_broadcast::InactiveReceiver<OutputMessage>,
50}
51
52impl<InputMessage, OutputMessage> ModuleInterface<InputMessage, OutputMessage>
53{
54  fn new(
55    input_sender: async_broadcast::Sender<InputMessage>,
56    output_receiver: async_broadcast::InactiveReceiver<OutputMessage>,
57  ) -> Self
58  {
59    Self {
60      output_receiver,
61      input_sender,
62    }
63  }
64
65  pub(crate) fn output_receiver(&self) -> async_broadcast::Receiver<OutputMessage>
66  {
67    self.output_receiver.activate_cloned()
68  }
69  pub(crate) fn input_sender(&self) -> async_broadcast::Sender<InputMessage>
70  {
71    self.input_sender.clone()
72  }
73}
74
75macro_rules! create_module_private_interface {
76  ($name:ident, $input_message:ty, $output_message:ty) => {
77    #[allow(missing_docs)]
78    pub struct $name
79    {
80      input_receiver: async_broadcast::InactiveReceiver<$input_message>,
81      output_sender: async_broadcast::Sender<$output_message>,
82    }
83    impl $crate::module::ModulePrivateInterface<$input_message, $output_message> for $name
84    {
85      fn new(
86        input_receiver: async_broadcast::InactiveReceiver<$input_message>,
87        output_sender: async_broadcast::Sender<$output_message>,
88      ) -> Self
89      {
90        Self {
91          input_receiver,
92          output_sender,
93        }
94      }
95    }
96  };
97}
98
99pub(crate) use create_module_private_interface;