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