sat-rs/satrs/src/subsystem.rs

189 lines
5.6 KiB
Rust
Raw Normal View History

2024-11-21 18:35:16 +01:00
use crate::{
mode::{Mode, ModeAndSubmode, ModeRequest, ModeRequestSender},
2024-12-09 17:28:28 +01:00
mode_tree::{ModeStoreVec, SequenceModeTables, SequenceTableMapTable, SequenceTablesMapValue},
2024-11-21 18:35:16 +01:00
queue::GenericTargetedMessagingError,
request::RequestId,
ComponentId,
};
2024-12-03 21:08:26 +01:00
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
2024-11-21 18:35:16 +01:00
pub enum SequenceExecutionHelperStates {
Idle,
AwaitingCheckSuccess,
Done,
}
2024-12-03 21:08:26 +01:00
pub trait CheckSuccessProvider {
fn mode_request_requires_success_check(
&mut self,
target_id: ComponentId,
target_mode: ModeAndSubmode,
);
}
2024-12-09 17:28:28 +01:00
#[derive(Debug)]
pub enum TargetKeepingResult {
Ok,
Violated { fallback_mode: Option<Mode> },
}
2024-12-03 21:08:26 +01:00
#[derive(Debug)]
pub enum SequenceHandlerResult {
SequenceDone,
SequenceStepDone,
AwaitingSuccessCheck,
}
#[derive(Debug, thiserror::Error)]
#[error("Mode {0} does not exist")]
pub struct ModeDoesNotExistError(Mode);
2024-11-21 18:35:16 +01:00
#[derive(Debug)]
pub struct SequenceExecutionHelper {
target_mode: Mode,
state: SequenceExecutionHelperStates,
request_id: RequestId,
current_sequence_index: Option<usize>,
}
2024-12-03 17:37:17 +01:00
impl Default for SequenceExecutionHelper {
fn default() -> Self {
Self {
target_mode: 0,
state: SequenceExecutionHelperStates::Idle,
request_id: 0,
2024-12-03 21:08:26 +01:00
current_sequence_index: None,
2024-12-03 17:37:17 +01:00
}
}
}
2024-11-21 18:35:16 +01:00
impl SequenceExecutionHelper {
2024-12-03 17:37:17 +01:00
pub fn load(
&mut self,
2024-11-21 18:35:16 +01:00
mode: Mode,
request_id: RequestId,
2024-11-26 10:25:56 +01:00
sequence_tables: &SequenceModeTables,
2024-12-03 21:08:26 +01:00
) -> Result<(), ModeDoesNotExistError> {
2024-11-26 10:25:56 +01:00
if !sequence_tables.0.contains_key(&mode) {
2024-12-03 21:08:26 +01:00
return Err(ModeDoesNotExistError(mode));
2024-11-21 18:35:16 +01:00
}
2024-12-03 17:37:17 +01:00
self.target_mode = mode;
self.request_id = request_id;
self.current_sequence_index = None;
Ok(())
2024-11-21 18:35:16 +01:00
}
pub fn confirm_sequence_done(&mut self) {
if let SequenceExecutionHelperStates::AwaitingCheckSuccess = self.state {
self.state = SequenceExecutionHelperStates::Idle;
}
}
2024-12-03 21:08:26 +01:00
pub fn state(&self) -> SequenceExecutionHelperStates {
self.state
}
pub fn awaiting_check_success(&self) -> bool {
matches!(
self.state,
SequenceExecutionHelperStates::AwaitingCheckSuccess
)
}
pub fn current_sequence_index(&self) -> Option<usize> {
self.current_sequence_index
}
2024-11-21 18:35:16 +01:00
pub fn run(
&mut self,
2024-11-26 10:25:56 +01:00
table: &SequenceModeTables,
2024-11-21 18:35:16 +01:00
sender: &impl ModeRequestSender,
2024-12-09 17:28:28 +01:00
mode_store_vec: &mut ModeStoreVec,
2024-11-21 18:35:16 +01:00
) -> Result<SequenceHandlerResult, GenericTargetedMessagingError> {
if self.state == SequenceExecutionHelperStates::AwaitingCheckSuccess {
return Ok(SequenceHandlerResult::AwaitingSuccessCheck);
}
match self.current_sequence_index {
Some(idx) => {
// Execute the sequence.
let seq_table_value = table.0.get(&self.target_mode).unwrap();
2024-12-09 17:28:28 +01:00
self.execute_sequence_and_map_to_result(
seq_table_value,
idx,
sender,
mode_store_vec,
)
2024-11-21 18:35:16 +01:00
}
None => {
// Find the first sequence
let seq_table_value = table.0.get(&self.target_mode).unwrap();
if seq_table_value.entries.is_empty() {
Ok(SequenceHandlerResult::SequenceDone)
} else {
self.current_sequence_index = Some(0);
2024-12-09 17:28:28 +01:00
self.execute_sequence_and_map_to_result(
seq_table_value,
0,
sender,
mode_store_vec,
)
2024-11-21 18:35:16 +01:00
}
}
}
}
pub fn execute_sequence_and_map_to_result(
&mut self,
2024-11-28 12:36:43 +01:00
seq_table_value: &SequenceTablesMapValue,
2024-11-21 18:35:16 +01:00
sequence_idx: usize,
sender: &impl ModeRequestSender,
2024-12-09 17:28:28 +01:00
mode_store_vec: &mut ModeStoreVec,
2024-11-21 18:35:16 +01:00
) -> Result<SequenceHandlerResult, GenericTargetedMessagingError> {
if Self::execute_sequence(
self.request_id,
&seq_table_value.entries[sequence_idx],
sender,
2024-12-09 17:28:28 +01:00
mode_store_vec,
2024-11-21 18:35:16 +01:00
)? {
self.state = SequenceExecutionHelperStates::AwaitingCheckSuccess;
Ok(SequenceHandlerResult::AwaitingSuccessCheck)
} else if seq_table_value.entries.len() - 1 == sequence_idx {
return Ok(SequenceHandlerResult::SequenceDone);
} else {
self.current_sequence_index = Some(sequence_idx + 1);
return Ok(SequenceHandlerResult::SequenceStepDone);
}
}
pub fn execute_sequence(
request_id: RequestId,
map_table: &SequenceTableMapTable,
sender: &impl ModeRequestSender,
2024-12-09 17:28:28 +01:00
mode_store_vec: &mut ModeStoreVec,
2024-11-21 18:35:16 +01:00
) -> Result<bool, GenericTargetedMessagingError> {
let mut some_succes_check_required = false;
for entry in &map_table.entries {
sender.send_mode_request(
request_id,
entry.common.target_id,
2025-01-16 13:56:49 +01:00
ModeRequest::SetMode {
mode_and_submode: entry.common.mode_submode,
forced: false,
},
2024-11-21 18:35:16 +01:00
)?;
2024-12-09 17:28:28 +01:00
mode_store_vec.0.iter_mut().for_each(|val| {
if val.id() == entry.common.target_id {
val.awaiting_reply = true;
}
});
2024-11-21 18:35:16 +01:00
if entry.check_success {
some_succes_check_required = true;
}
}
Ok(some_succes_check_required)
}
}
#[cfg(test)]
2024-11-26 10:25:56 +01:00
mod tests {}