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}