eryon_actors/operators/
mod.rs

1/*
2    Appellation: actors <module>
3    Contrib: @FL03
4*/
5//! This module focuses on implementing various operators for the [VNode](crate::vnode::VNode).
6//! Each operator is a specialized actor that can be used to perform specific tasks.
7//!
8#[doc(inline)]
9pub use self::{agent::Agent, observer::Observer};
10
11pub mod agent;
12pub mod observer;
13
14pub(crate) mod prelude {
15    pub use super::agent::*;
16    pub use super::observer::*;
17    pub use super::{Operator, OperatorKind};
18}
19
20use crate::drivers::RawDriver;
21use crate::mem::TopoLedger;
22use crate::traits::Actor;
23use rstmt::nrt::Triad;
24
25use num_traits::{Float, FromPrimitive, NumAssign};
26
27/// Enumerates the varios operators for the nodes, reducing the number of generics needed.
28#[derive(Clone, Debug, Eq, PartialEq, strum::EnumDiscriminants, strum::EnumIs)]
29#[strum_discriminants(
30    name(OperatorKind),
31    derive(
32        Hash,
33        Ord,
34        PartialOrd,
35        strum::AsRefStr,
36        strum::Display,
37        strum::EnumCount,
38        strum::EnumIs,
39        strum::EnumIter,
40        strum::EnumString,
41        strum::VariantArray,
42        strum::VariantNames
43    ),
44    strum(serialize_all = "snake_case")
45)]
46pub enum Operator<T> {
47    Agent(Agent<T>),
48    Observer(Observer<T>),
49}
50
51impl<T> Operator<T> {
52    /// Get the current active operator as Actor trait object
53    pub fn active_operator<D>(&self) -> &dyn Actor<D, T>
54    where
55        D: RawDriver<Triad>,
56        T: core::iter::Sum + Float + FromPrimitive + NumAssign,
57    {
58        match self {
59            Operator::Observer(observer) => observer,
60            Operator::Agent(agent) => agent,
61        }
62    }
63
64    /// Get the current active operator as Actor trait object (mutable)
65    pub fn active_operator_mut<D>(&mut self) -> &mut dyn Actor<D, T>
66    where
67        D: RawDriver<Triad>,
68        T: core::iter::Sum + Float + FromPrimitive + NumAssign,
69    {
70        match self {
71            Operator::Observer(observer) => observer,
72            Operator::Agent(agent) => agent,
73        }
74    }
75}
76
77impl<D, T> Actor<D, T> for Operator<T>
78where
79    D: RawDriver<Triad>,
80    T: core::iter::Sum + Float + FromPrimitive + NumAssign,
81{
82    fn kind(&self) -> &'static str {
83        self.active_operator::<D>().kind()
84    }
85
86    fn initialize(&mut self) -> crate::Result<()> {
87        self.active_operator_mut::<D>().initialize()
88    }
89
90    fn process_transform(
91        &mut self,
92        transform: crate::nrt::LPR,
93        driver: &mut D,
94        memory: &mut TopoLedger<T>,
95    ) -> crate::Result<bool> {
96        self.active_operator_mut::<D>()
97            .process_transform(transform, driver, memory)
98    }
99
100    fn process_message(
101        &mut self,
102        source: rshyper::EdgeId,
103        message: &[u8],
104        memory: &mut TopoLedger<T>,
105    ) -> crate::Result<()> {
106        self.active_operator_mut::<D>()
107            .process_message(source, message, memory)
108    }
109
110    fn on_activate(&mut self, driver: &D, memory: &mut TopoLedger<T>) -> crate::Result<()> {
111        self.active_operator_mut::<D>().on_activate(driver, memory)
112    }
113
114    fn on_deactivate(&mut self, driver: &D, memory: &mut TopoLedger<T>) -> crate::Result<()> {
115        self.active_operator_mut::<D>()
116            .on_deactivate(driver, memory)
117    }
118
119    fn resource_requirements(&self) -> (usize, usize) {
120        self.active_operator::<D>().resource_requirements()
121    }
122
123    fn allows_pattern_sharing(&self) -> bool {
124        self.active_operator::<D>().allows_pattern_sharing()
125    }
126
127    fn contextualize(
128        &self,
129        driver: &D,
130        memory: &TopoLedger<T>,
131    ) -> crate::Result<crate::ActorContext<T>> {
132        self.active_operator::<D>().contextualize(driver, memory)
133    }
134}
135
136impl<T> Default for Operator<T>
137where
138    T: Default + FromPrimitive,
139{
140    fn default() -> Self {
141        Operator::Agent(Agent::default())
142    }
143}
144
145impl<T> core::hash::Hash for Operator<T> {
146    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
147        match self {
148            Operator::Agent(agent) => agent.hash(state),
149            Operator::Observer(observer) => observer.hash(state),
150        }
151    }
152}