continue mode tree
This commit is contained in:
parent
3a02fcf77a
commit
a6aa20d09b
@ -317,6 +317,7 @@ pub mod alloc_mod {
|
|||||||
&mut self,
|
&mut self,
|
||||||
sender_id: ComponentId,
|
sender_id: ComponentId,
|
||||||
reported_mode_and_submode: Option<ModeAndSubmode>,
|
reported_mode_and_submode: Option<ModeAndSubmode>,
|
||||||
|
handle_reply_awaition: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut still_awating_replies = false;
|
let mut still_awating_replies = false;
|
||||||
self.0.iter_mut().for_each(|val| {
|
self.0.iter_mut().for_each(|val| {
|
||||||
@ -324,9 +325,11 @@ pub mod alloc_mod {
|
|||||||
if let Some(mode_and_submode) = reported_mode_and_submode {
|
if let Some(mode_and_submode) = reported_mode_and_submode {
|
||||||
val.mode_and_submode = mode_and_submode;
|
val.mode_and_submode = mode_and_submode;
|
||||||
}
|
}
|
||||||
val.awaiting_reply = false;
|
if handle_reply_awaition {
|
||||||
|
val.awaiting_reply = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if val.awaiting_reply {
|
if handle_reply_awaition && val.awaiting_reply {
|
||||||
still_awating_replies = true;
|
still_awating_replies = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -108,6 +108,7 @@ pub struct SubsystemCommandingHelper {
|
|||||||
pub current_mode: ModeAndSubmode,
|
pub current_mode: ModeAndSubmode,
|
||||||
pub state: ModeTreeHelperState,
|
pub state: ModeTreeHelperState,
|
||||||
pub children_mode_store: ModeStoreVec,
|
pub children_mode_store: ModeStoreVec,
|
||||||
|
pub active_request_id: Option<RequestId>,
|
||||||
pub target_tables: TargetModeTables,
|
pub target_tables: TargetModeTables,
|
||||||
pub sequence_tables: SequenceModeTables,
|
pub sequence_tables: SequenceModeTables,
|
||||||
pub helper: SequenceExecutionHelper,
|
pub helper: SequenceExecutionHelper,
|
||||||
@ -119,6 +120,7 @@ impl Default for SubsystemCommandingHelper {
|
|||||||
current_mode: UNKNOWN_MODE,
|
current_mode: UNKNOWN_MODE,
|
||||||
state: Default::default(),
|
state: Default::default(),
|
||||||
children_mode_store: Default::default(),
|
children_mode_store: Default::default(),
|
||||||
|
active_request_id: None,
|
||||||
target_tables: Default::default(),
|
target_tables: Default::default(),
|
||||||
sequence_tables: Default::default(),
|
sequence_tables: Default::default(),
|
||||||
helper: Default::default(),
|
helper: Default::default(),
|
||||||
@ -136,6 +138,7 @@ impl SubsystemCommandingHelper {
|
|||||||
current_mode: UNKNOWN_MODE,
|
current_mode: UNKNOWN_MODE,
|
||||||
state: ModeTreeHelperState::Idle,
|
state: ModeTreeHelperState::Idle,
|
||||||
children_mode_store,
|
children_mode_store,
|
||||||
|
active_request_id: None,
|
||||||
target_tables,
|
target_tables,
|
||||||
sequence_tables,
|
sequence_tables,
|
||||||
helper: Default::default(),
|
helper: Default::default(),
|
||||||
@ -206,6 +209,7 @@ impl SubsystemCommandingHelper {
|
|||||||
// mode after an executed sequence.
|
// mode after an executed sequence.
|
||||||
if let ModeCommandingResult::CommandingDone = result {
|
if let ModeCommandingResult::CommandingDone = result {
|
||||||
self.state = ModeTreeHelperState::TargetKeeping;
|
self.state = ModeTreeHelperState::TargetKeeping;
|
||||||
|
self.active_request_id = None;
|
||||||
self.current_mode = ModeAndSubmode::new(self.helper.target_mode().unwrap(), 0);
|
self.current_mode = ModeAndSubmode::new(self.helper.target_mode().unwrap(), 0);
|
||||||
}
|
}
|
||||||
Ok(result.into())
|
Ok(result.into())
|
||||||
@ -219,9 +223,21 @@ impl SubsystemCommandingHelper {
|
|||||||
}
|
}
|
||||||
let mut generic_mode_reply_handler =
|
let mut generic_mode_reply_handler =
|
||||||
|sender_id, mode_and_submode: Option<ModeAndSubmode>| {
|
|sender_id, mode_and_submode: Option<ModeAndSubmode>| {
|
||||||
let still_awating_replies = self
|
// Tying the reply awaition to the request ID ensures that something like replies
|
||||||
.children_mode_store
|
// belonging to older requests do not interfere with the completion handling of
|
||||||
.generic_reply_handler(sender_id, mode_and_submode);
|
// the mode commanding. This is important for forced mode commands.
|
||||||
|
let mut handle_awaition = false;
|
||||||
|
if self.state == ModeTreeHelperState::ModeCommanding
|
||||||
|
&& self.active_request_id.is_some()
|
||||||
|
&& reply.request_id() == self.active_request_id.unwrap()
|
||||||
|
{
|
||||||
|
handle_awaition = true;
|
||||||
|
}
|
||||||
|
let still_awating_replies = self.children_mode_store.generic_reply_handler(
|
||||||
|
sender_id,
|
||||||
|
mode_and_submode,
|
||||||
|
handle_awaition,
|
||||||
|
);
|
||||||
if self.state == ModeTreeHelperState::ModeCommanding && !still_awating_replies {
|
if self.state == ModeTreeHelperState::ModeCommanding && !still_awating_replies {
|
||||||
self.helper.confirm_sequence_done();
|
self.helper.confirm_sequence_done();
|
||||||
}
|
}
|
||||||
@ -655,6 +671,8 @@ pub struct AssemblyCommandingHelper {
|
|||||||
pub children_mode_store: ModeStoreVec,
|
pub children_mode_store: ModeStoreVec,
|
||||||
/// Target mode used for mode commanding.
|
/// Target mode used for mode commanding.
|
||||||
pub target_mode: Option<ModeAndSubmode>,
|
pub target_mode: Option<ModeAndSubmode>,
|
||||||
|
/// Request ID of active mode commanding request.
|
||||||
|
pub active_request_id: Option<RequestId>,
|
||||||
pub state: ModeTreeHelperState,
|
pub state: ModeTreeHelperState,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,6 +696,7 @@ impl AssemblyCommandingHelper {
|
|||||||
)?;
|
)?;
|
||||||
child.awaiting_reply = true;
|
child.awaiting_reply = true;
|
||||||
}
|
}
|
||||||
|
self.active_request_id = Some(request_id);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,9 +723,21 @@ impl AssemblyCommandingHelper {
|
|||||||
return AssemblyHelperResult::Idle;
|
return AssemblyHelperResult::Idle;
|
||||||
}
|
}
|
||||||
let mut generic_mode_reply_handler = |mode_and_submode: Option<ModeAndSubmode>| {
|
let mut generic_mode_reply_handler = |mode_and_submode: Option<ModeAndSubmode>| {
|
||||||
let still_awating_replies = self
|
// Tying the reply awaition to the request ID ensures that something like replies
|
||||||
.children_mode_store
|
// belonging to older requests do not interfere with the completion handling of
|
||||||
.generic_reply_handler(mode_reply.sender_id(), mode_and_submode);
|
// the mode commanding. This is important for forced mode commands.
|
||||||
|
let mut handle_awaition = false;
|
||||||
|
if self.state == ModeTreeHelperState::ModeCommanding
|
||||||
|
&& self.active_request_id.is_some()
|
||||||
|
&& mode_reply.request_id() == self.active_request_id.unwrap()
|
||||||
|
{
|
||||||
|
handle_awaition = true;
|
||||||
|
}
|
||||||
|
let still_awating_replies = self.children_mode_store.generic_reply_handler(
|
||||||
|
mode_reply.sender_id(),
|
||||||
|
mode_and_submode,
|
||||||
|
handle_awaition,
|
||||||
|
);
|
||||||
if self.state == ModeTreeHelperState::TargetKeeping
|
if self.state == ModeTreeHelperState::TargetKeeping
|
||||||
&& mode_and_submode.is_some()
|
&& mode_and_submode.is_some()
|
||||||
&& self.target_mode.is_some()
|
&& self.target_mode.is_some()
|
||||||
@ -714,8 +745,12 @@ impl AssemblyCommandingHelper {
|
|||||||
{
|
{
|
||||||
return AssemblyHelperResult::TargetKeepingViolation(mode_reply.sender_id());
|
return AssemblyHelperResult::TargetKeepingViolation(mode_reply.sender_id());
|
||||||
}
|
}
|
||||||
if self.state == ModeTreeHelperState::ModeCommanding && !still_awating_replies {
|
if self.state == ModeTreeHelperState::ModeCommanding
|
||||||
|
&& handle_awaition
|
||||||
|
&& !still_awating_replies
|
||||||
|
{
|
||||||
self.state = ModeTreeHelperState::TargetKeeping;
|
self.state = ModeTreeHelperState::TargetKeeping;
|
||||||
|
self.active_request_id = None;
|
||||||
return AssemblyHelperResult::ModeCommandingDone;
|
return AssemblyHelperResult::ModeCommandingDone;
|
||||||
}
|
}
|
||||||
AssemblyHelperResult::Idle
|
AssemblyHelperResult::Idle
|
||||||
@ -760,6 +795,7 @@ impl MgmAssembly {
|
|||||||
self.check_mode_requests().expect("mode messaging error");
|
self.check_mode_requests().expect("mode messaging error");
|
||||||
self.check_mode_replies().expect("mode messaging error");
|
self.check_mode_replies().expect("mode messaging error");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_num_mode_requests(&mut self) -> usize {
|
pub fn get_num_mode_requests(&mut self) -> usize {
|
||||||
self.mode_req_mock.mode_messages_received()
|
self.mode_req_mock.mode_messages_received()
|
||||||
}
|
}
|
||||||
@ -829,6 +865,8 @@ impl ModeRequestHandler for MgmAssembly {
|
|||||||
forced: bool,
|
forced: bool,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
// Always accept forced commands and commands to mode OFF.
|
// Always accept forced commands and commands to mode OFF.
|
||||||
|
// TODO: Forced transitions are special because now we might receive a reply where the
|
||||||
|
// request ID is relevant!
|
||||||
if self.assembly_helper.target_mode.is_some()
|
if self.assembly_helper.target_mode.is_some()
|
||||||
&& !forced
|
&& !forced
|
||||||
&& mode_and_submode.mode() != DefaultMode::OFF as u32
|
&& mode_and_submode.mode() != DefaultMode::OFF as u32
|
||||||
|
Loading…
x
Reference in New Issue
Block a user