ncomm_core/
executor.rs

1//!
2//! An executor handles the scheduling and execution of nodes.
3//!
4//! In all likelihood most users should use one of the executors provided
5//! in ncomm-executors.  This trait should, however, create a common interface
6//! for interfacing with any and all of the executors that are part of NComm
7//! and allows users to write their own executors if desired.
8//!
9
10use crate::node::Node;
11
12#[cfg(feature = "alloc")]
13use alloc::boxed::Box;
14#[cfg(feature = "std")]
15use std::boxed::Box;
16
17/// The current state an executor is in.
18///
19/// This should be taken into account whenever the start or update methods
20/// are called on an executor so that an executor may be put into the correct
21/// state before executing a method.
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23pub enum ExecutorState {
24    /// The nodes in the executor are currently stopped.
25    ///
26    /// This means the Nodes must be started before update can begin
27    Stopped,
28    /// The nodes in the executor have been started and can now be updated.
29    Started,
30    /// The nodes in the executor are current being updated
31    Running,
32}
33
34/// An executor handles the scheduling and execution of nodes
35///
36/// All nodes should have some unique ID that makes them identifiable
37/// as trait objects
38pub trait Executor<ID: PartialEq> {
39    /// Optional Context for adding nodes with specific conditions
40    type Context;
41
42    /// Starts the nodes contained by the executor
43    fn start(&mut self);
44
45    /// Run the update loop for a set amount of time (in milliseconds)
46    fn update_for_ms(&mut self, ms: u128);
47
48    /// Run the update loop until the executor's interrupt is called
49    fn update_loop(&mut self);
50
51    /// Check whether the program has been interrupted
52    ///
53    /// Note: This should be called between each Node execution
54    fn check_interrupt(&mut self) -> bool;
55
56    /// Add a node to the executor.
57    fn add_node(&mut self, node: Box<dyn Node<ID>>);
58
59    /// Add a node to the executor with some given context.
60    ///
61    /// Note: The context is mainly to allow for extra configuration when
62    /// adding nodes.
63    fn add_node_with_context(&mut self, node: Box<dyn Node<ID>>, _ctx: Self::Context) {
64        self.add_node(node);
65    }
66
67    /// Remove a node from the executor.
68    fn remove_node(&mut self, id: &ID) -> Option<Box<dyn Node<ID>>>;
69}