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