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 {}
|