cu29_runtime/app.rs
1use crate::config::CuConfig;
2use crate::simulation::SimOverride;
3use cu29_clock::RobotClock;
4use cu29_traits::CuResult;
5use cu29_unifiedlog::UnifiedLoggerWrite;
6use std::sync::{Arc, Mutex};
7
8/// A trait that defines the structure and behavior of a CuApplication.
9///
10/// CuApplication is the normal, running on robot version of an application and its runtime.
11///
12/// The `CuApplication` trait outlines the necessary functions required for managing an application lifecycle,
13/// including configuration management, initialization, task execution, and runtime control. It is meant to be
14/// implemented by types that represent specific applications, providing them with unified control and execution features.
15///
16pub trait CuApplication {
17 /// Returns the original configuration as a string, typically loaded from a RON file.
18 /// This configuration represents the default settings for the application before any overrides.
19 fn get_original_config() -> String;
20
21 /// Creates a new application.
22 ///
23 /// # Arguments
24 ///
25 /// * `clock` - A `RobotClock` instance to be used for time-related operations in the implementing struct.
26 /// * `unified_logger` - A thread-safe, shared reference to `UnifiedLoggerWrite`, enabling logging functionalities.
27 /// * `config_override` - An optional `CuConfig` instance that allows overriding the default configuration values.
28 /// - If `Some`, the provided configuration will be used.
29 /// - If `None`, the default configuration will be applied.
30 ///
31 /// # Returns
32 ///
33 /// A result containing either:
34 /// - An instantiated object of the implementing type (`Self`), or
35 /// - A `CuResult` error in case of failure during initialization.
36 ///
37 fn new(
38 clock: RobotClock,
39 unified_logger: Arc<Mutex<UnifiedLoggerWrite>>,
40 config_override: Option<CuConfig>,
41 ) -> CuResult<Self>
42 where
43 Self: Sized;
44
45 /// Starts all tasks managed by the application/runtime.
46 ///
47 /// # Returns
48 /// * `Ok(())` - If all tasks are started successfully.
49 /// * `Err(CuResult)` - If an error occurs while attempting to start one
50 /// or more tasks.
51 fn start_all_tasks(&mut self) -> CuResult<()>;
52
53 /// Executes a single iteration of copper-generated runtime (generating and logging one copperlist)
54 ///
55 /// # Returns
56 ///
57 /// * `CuResult<()>` - Returns `Ok(())` if the iteration completes successfully, or an error
58 /// wrapped in `CuResult` if something goes wrong during execution.
59 ///
60 fn run_one_iteration(&mut self) -> CuResult<()>;
61
62 /// Runs indefinitely looping over run_one_iteration
63 ///
64 /// # Returns
65 ///
66 /// Returns a `CuResult<()>`, which indicates the success or failure of the
67 /// operation.
68 /// - On success, the result is `Ok(())`.
69 /// - On failure, an appropriate error wrapped in `CuResult` is returned.
70 fn run(&mut self) -> CuResult<()>;
71
72 /// Stops all tasks managed by the application/runtime.
73 ///
74 /// # Returns
75 ///
76 /// Returns a `CuResult<()>`, which indicates the success or failure of the
77 /// operation.
78 /// - On success, the result is `Ok(())`.
79 /// - On failure, an appropriate error wrapped in `CuResult` is returned.
80 ///
81 fn stop_all_tasks(&mut self) -> CuResult<()>;
82}
83
84/// A trait that defines the structure and behavior of a simulation-enabled CuApplication.
85///
86/// CuSimApplication is the simulation version of an application and its runtime, allowing
87/// overriding of steps with simulated behavior.
88///
89/// The `CuSimApplication` trait outlines the necessary functions required for managing an application lifecycle
90/// in simulation mode, including configuration management, initialization, task execution, and runtime control.
91pub trait CuSimApplication {
92 /// The type representing a simulation step that can be overridden
93 type Step<'z>;
94
95 /// Returns the original configuration as a string, typically loaded from a RON file.
96 /// This configuration represents the default settings for the application before any overrides.
97 fn get_original_config() -> String;
98
99 /// Creates a new simulation-enabled application.
100 ///
101 /// # Arguments
102 ///
103 /// * `clock` - A `RobotClock` instance to be used for time-related operations in the implementing struct.
104 /// * `unified_logger` - A thread-safe, shared reference to `UnifiedLoggerWrite`, enabling logging functionalities.
105 /// * `config_override` - An optional `CuConfig` instance that allows overriding the default configuration values.
106 /// - If `Some`, the provided configuration will be used.
107 /// - If `None`, the default configuration will be applied.
108 /// * `sim_callback` - A mutable function reference that allows overriding individual simulation steps.
109 /// The callback receives a Step parameter and returns a SimOverride indicating how to handle the step.
110 ///
111 /// # Returns
112 ///
113 /// A result containing either:
114 /// - An instantiated object of the implementing type (`Self`), or
115 /// - A `CuResult` error in case of failure during initialization.
116 fn new(
117 clock: RobotClock,
118 unified_logger: Arc<Mutex<UnifiedLoggerWrite>>,
119 config_override: Option<CuConfig>,
120 sim_callback: &mut impl for<'z> FnMut(Self::Step<'z>) -> SimOverride,
121 ) -> CuResult<Self>
122 where
123 Self: Sized;
124
125 /// Starts all tasks managed by the application/runtime in simulation mode.
126 ///
127 /// # Arguments
128 /// * `sim_callback` - A mutable function reference that allows overriding individual simulation steps.
129 ///
130 /// # Returns
131 /// * `Ok(())` - If all tasks are started successfully.
132 /// * `Err(CuResult)` - If an error occurs while attempting to start one
133 /// or more tasks.
134 fn start_all_tasks(
135 &mut self,
136 sim_callback: &mut impl for<'z> FnMut(Self::Step<'z>) -> SimOverride,
137 ) -> CuResult<()>;
138
139 /// Executes a single iteration of copper-generated runtime in simulation mode.
140 ///
141 /// # Arguments
142 /// * `sim_callback` - A mutable function reference that allows overriding individual simulation steps.
143 ///
144 /// # Returns
145 ///
146 /// * `CuResult<()>` - Returns `Ok(())` if the iteration completes successfully, or an error
147 /// wrapped in `CuResult` if something goes wrong during execution.
148 fn run_one_iteration(
149 &mut self,
150 sim_callback: &mut impl for<'z> FnMut(Self::Step<'z>) -> SimOverride,
151 ) -> CuResult<()>;
152
153 /// Runs indefinitely looping over run_one_iteration in simulation mode
154 ///
155 /// # Arguments
156 /// * `sim_callback` - A mutable function reference that allows overriding individual simulation steps.
157 ///
158 /// # Returns
159 ///
160 /// Returns a `CuResult<()>`, which indicates the success or failure of the
161 /// operation.
162 /// - On success, the result is `Ok(())`.
163 /// - On failure, an appropriate error wrapped in `CuResult` is returned.
164 fn run(
165 &mut self,
166 sim_callback: &mut impl for<'z> FnMut(Self::Step<'z>) -> SimOverride,
167 ) -> CuResult<()>;
168
169 /// Stops all tasks managed by the application/runtime in simulation mode.
170 ///
171 /// # Arguments
172 /// * `sim_callback` - A mutable function reference that allows overriding individual simulation steps.
173 ///
174 /// # Returns
175 ///
176 /// Returns a `CuResult<()>`, which indicates the success or failure of the
177 /// operation.
178 /// - On success, the result is `Ok(())`.
179 /// - On failure, an appropriate error wrapped in `CuResult` is returned.
180 fn stop_all_tasks(
181 &mut self,
182 sim_callback: &mut impl for<'z> FnMut(Self::Step<'z>) -> SimOverride,
183 ) -> CuResult<()>;
184}