WIP: Mode Sequence and Tables #211
@ -36,15 +36,16 @@ pub mod pus;
|
|||||||
pub mod queue;
|
pub mod queue;
|
||||||
pub mod request;
|
pub mod request;
|
||||||
pub mod res_code;
|
pub mod res_code;
|
||||||
pub mod time;
|
|
||||||
pub mod tmtc;
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub mod scheduling;
|
pub mod scheduling;
|
||||||
|
pub mod time;
|
||||||
|
pub mod tmtc;
|
||||||
|
|
||||||
pub mod action;
|
pub mod action;
|
||||||
pub mod hk;
|
pub mod hk;
|
||||||
pub mod mode;
|
pub mod mode;
|
||||||
pub mod params;
|
pub mod params;
|
||||||
|
pub mod subsystem;
|
||||||
|
|
||||||
pub use spacepackets;
|
pub use spacepackets;
|
||||||
|
|
||||||
|
@ -12,7 +12,9 @@ pub use std_mod::*;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
queue::GenericTargetedMessagingError,
|
queue::GenericTargetedMessagingError,
|
||||||
request::{GenericMessage, MessageMetadata, MessageReceiver, MessageReceiverWithId, RequestId},
|
request::{
|
||||||
|
GenericMessage, MessageMetadata, MessageReceiverProvider, MessageReceiverWithId, RequestId,
|
||||||
|
},
|
||||||
ComponentId,
|
ComponentId,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -127,6 +129,8 @@ pub struct TargetedModeRequest {
|
|||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
pub enum ModeReply {
|
pub enum ModeReply {
|
||||||
|
/// Mode information. Can be used to notify other components of changed modes.
|
||||||
|
ModeInfo(ModeAndSubmode),
|
||||||
/// Reply to a mode request to confirm the commanded mode was reached.
|
/// Reply to a mode request to confirm the commanded mode was reached.
|
||||||
ModeReply(ModeAndSubmode),
|
ModeReply(ModeAndSubmode),
|
||||||
// Can not reach the commanded mode. Contains a reason as a [ResultU16].
|
// Can not reach the commanded mode. Contains a reason as a [ResultU16].
|
||||||
@ -156,7 +160,7 @@ pub trait ModeRequestReceiver {
|
|||||||
) -> Result<Option<GenericMessage<ModeRequest>>, GenericTargetedMessagingError>;
|
) -> Result<Option<GenericMessage<ModeRequest>>, GenericTargetedMessagingError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: MessageReceiver<ModeRequest>> ModeRequestReceiver
|
impl<R: MessageReceiverProvider<ModeRequest>> ModeRequestReceiver
|
||||||
for MessageReceiverWithId<ModeRequest, R>
|
for MessageReceiverWithId<ModeRequest, R>
|
||||||
{
|
{
|
||||||
fn try_recv_mode_request(
|
fn try_recv_mode_request(
|
||||||
@ -248,7 +252,9 @@ pub trait ModeReplyReceiver {
|
|||||||
) -> Result<Option<GenericMessage<ModeReply>>, GenericTargetedMessagingError>;
|
) -> Result<Option<GenericMessage<ModeReply>>, GenericTargetedMessagingError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: MessageReceiver<ModeReply>> ModeReplyReceiver for MessageReceiverWithId<ModeReply, R> {
|
impl<R: MessageReceiverProvider<ModeReply>> ModeReplyReceiver
|
||||||
|
for MessageReceiverWithId<ModeReply, R>
|
||||||
|
{
|
||||||
fn try_recv_mode_reply(
|
fn try_recv_mode_reply(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Option<GenericMessage<ModeReply>>, GenericTargetedMessagingError> {
|
) -> Result<Option<GenericMessage<ModeReply>>, GenericTargetedMessagingError> {
|
||||||
@ -270,12 +276,13 @@ pub trait ModeReplySender {
|
|||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub mod alloc_mod {
|
pub mod alloc_mod {
|
||||||
use crate::request::{
|
use crate::request::{
|
||||||
MessageSender, MessageSenderAndReceiver, MessageSenderMap, RequestAndReplySenderAndReceiver,
|
MessageSenderAndReceiver, MessageSenderMap, MessageSenderProvider,
|
||||||
|
MessageSenderStoreProvider, RequestAndReplySenderAndReceiver,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl<S: MessageSender<ModeReply>> MessageSenderMap<ModeReply, S> {
|
impl<S: MessageSenderProvider<ModeReply>> MessageSenderMap<ModeReply, S> {
|
||||||
pub fn send_mode_reply(
|
pub fn send_mode_reply(
|
||||||
&self,
|
&self,
|
||||||
requestor_info: MessageMetadata,
|
requestor_info: MessageMetadata,
|
||||||
@ -290,8 +297,13 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FROM, S: MessageSender<ModeReply>, R: MessageReceiver<FROM>> ModeReplySender
|
impl<
|
||||||
for MessageSenderAndReceiver<ModeReply, FROM, S, R>
|
From,
|
||||||
|
Sender: MessageSenderProvider<ModeReply>,
|
||||||
|
Receiver: MessageReceiverProvider<From>,
|
||||||
|
SenderStore: MessageSenderStoreProvider<ModeReply, Sender>,
|
||||||
|
> ModeReplySender
|
||||||
|
for MessageSenderAndReceiver<ModeReply, From, Sender, Receiver, SenderStore>
|
||||||
{
|
{
|
||||||
fn local_channel_id(&self) -> ComponentId {
|
fn local_channel_id(&self) -> ComponentId {
|
||||||
self.local_channel_id_generic()
|
self.local_channel_id_generic()
|
||||||
@ -302,7 +314,7 @@ pub mod alloc_mod {
|
|||||||
requestor_info: MessageMetadata,
|
requestor_info: MessageMetadata,
|
||||||
request: ModeReply,
|
request: ModeReply,
|
||||||
) -> Result<(), GenericTargetedMessagingError> {
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
self.message_sender_map.send_mode_reply(
|
self.message_sender_store.send_message(
|
||||||
MessageMetadata::new(requestor_info.request_id(), self.local_channel_id()),
|
MessageMetadata::new(requestor_info.request_id(), self.local_channel_id()),
|
||||||
requestor_info.sender_id(),
|
requestor_info.sender_id(),
|
||||||
request,
|
request,
|
||||||
@ -310,8 +322,13 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TO, S: MessageSender<TO>, R: MessageReceiver<ModeReply>> ModeReplyReceiver
|
impl<
|
||||||
for MessageSenderAndReceiver<TO, ModeReply, S, R>
|
To,
|
||||||
|
Sender: MessageSenderProvider<To>,
|
||||||
|
Receiver: MessageReceiverProvider<ModeReply>,
|
||||||
|
SenderStore: MessageSenderStoreProvider<To, Sender>,
|
||||||
|
> ModeReplyReceiver
|
||||||
|
for MessageSenderAndReceiver<To, ModeReply, Sender, Receiver, SenderStore>
|
||||||
{
|
{
|
||||||
fn try_recv_mode_reply(
|
fn try_recv_mode_reply(
|
||||||
&self,
|
&self,
|
||||||
@ -321,26 +338,51 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
REQUEST,
|
Request,
|
||||||
S0: MessageSender<REQUEST>,
|
ReqSender: MessageSenderProvider<Request>,
|
||||||
R0: MessageReceiver<ModeReply>,
|
ReqReceiver: MessageReceiverProvider<Request>,
|
||||||
S1: MessageSender<ModeReply>,
|
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||||
R1: MessageReceiver<REQUEST>,
|
Reply,
|
||||||
> RequestAndReplySenderAndReceiver<REQUEST, ModeReply, S0, R0, S1, R1>
|
ReplySender: MessageSenderProvider<Reply>,
|
||||||
|
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||||
|
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||||
|
>
|
||||||
|
RequestAndReplySenderAndReceiver<
|
||||||
|
Request,
|
||||||
|
ReqSender,
|
||||||
|
ReqReceiver,
|
||||||
|
ReqSenderStore,
|
||||||
|
Reply,
|
||||||
|
ReplySender,
|
||||||
|
ReplyReceiver,
|
||||||
|
ReplySenderStore,
|
||||||
|
>
|
||||||
{
|
{
|
||||||
pub fn add_reply_target(&mut self, target_id: ComponentId, reply_sender: S1) {
|
pub fn add_reply_target(&mut self, target_id: ComponentId, reply_sender: ReplySender) {
|
||||||
self.reply_sender_map
|
self.reply_sender_store
|
||||||
.add_message_target(target_id, reply_sender)
|
.add_message_target(target_id, reply_sender)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
REQUEST,
|
Request,
|
||||||
S0: MessageSender<REQUEST>,
|
ReqSender: MessageSenderProvider<Request>,
|
||||||
R0: MessageReceiver<ModeReply>,
|
ReqReceiver: MessageReceiverProvider<Request>,
|
||||||
S1: MessageSender<ModeReply>,
|
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||||
R1: MessageReceiver<REQUEST>,
|
ReplySender: MessageSenderProvider<ModeReply>,
|
||||||
> ModeReplySender for RequestAndReplySenderAndReceiver<REQUEST, ModeReply, S0, R0, S1, R1>
|
ReplyReceiver: MessageReceiverProvider<ModeReply>,
|
||||||
|
ReplySenderStore: MessageSenderStoreProvider<ModeReply, ReplySender>,
|
||||||
|
> ModeReplySender
|
||||||
|
for RequestAndReplySenderAndReceiver<
|
||||||
|
Request,
|
||||||
|
ReqSender,
|
||||||
|
ReqReceiver,
|
||||||
|
ReqSenderStore,
|
||||||
|
ModeReply,
|
||||||
|
ReplySender,
|
||||||
|
ReplyReceiver,
|
||||||
|
ReplySenderStore,
|
||||||
|
>
|
||||||
{
|
{
|
||||||
fn local_channel_id(&self) -> ComponentId {
|
fn local_channel_id(&self) -> ComponentId {
|
||||||
self.local_channel_id_generic()
|
self.local_channel_id_generic()
|
||||||
@ -349,24 +391,35 @@ pub mod alloc_mod {
|
|||||||
fn send_mode_reply(
|
fn send_mode_reply(
|
||||||
&self,
|
&self,
|
||||||
requestor_info: MessageMetadata,
|
requestor_info: MessageMetadata,
|
||||||
request: ModeReply,
|
reply: ModeReply,
|
||||||
) -> Result<(), GenericTargetedMessagingError> {
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
self.reply_sender_map.send_mode_reply(
|
self.reply_sender_store.send_message(
|
||||||
MessageMetadata::new(requestor_info.request_id(), self.local_channel_id()),
|
MessageMetadata::new(requestor_info.request_id(), self.local_channel_id()),
|
||||||
requestor_info.sender_id(),
|
requestor_info.sender_id(),
|
||||||
request,
|
reply,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
REQUEST,
|
Request,
|
||||||
S0: MessageSender<REQUEST>,
|
ReqSender: MessageSenderProvider<Request>,
|
||||||
R0: MessageReceiver<ModeReply>,
|
ReqReceiver: MessageReceiverProvider<Request>,
|
||||||
S1: MessageSender<ModeReply>,
|
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||||
R1: MessageReceiver<REQUEST>,
|
ReplySender: MessageSenderProvider<ModeReply>,
|
||||||
|
ReplyReceiver: MessageReceiverProvider<ModeReply>,
|
||||||
|
ReplySenderStore: MessageSenderStoreProvider<ModeReply, ReplySender>,
|
||||||
> ModeReplyReceiver
|
> ModeReplyReceiver
|
||||||
for RequestAndReplySenderAndReceiver<REQUEST, ModeReply, S0, R0, S1, R1>
|
for RequestAndReplySenderAndReceiver<
|
||||||
|
Request,
|
||||||
|
ReqSender,
|
||||||
|
ReqReceiver,
|
||||||
|
ReqSenderStore,
|
||||||
|
ModeReply,
|
||||||
|
ReplySender,
|
||||||
|
ReplyReceiver,
|
||||||
|
ReplySenderStore,
|
||||||
|
>
|
||||||
{
|
{
|
||||||
fn try_recv_mode_reply(
|
fn try_recv_mode_reply(
|
||||||
&self,
|
&self,
|
||||||
@ -376,11 +429,14 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Helper type definition for a mode handler which can handle mode requests.
|
/// Helper type definition for a mode handler which can handle mode requests.
|
||||||
pub type ModeRequestHandlerInterface<S, R> =
|
pub type ModeRequestHandlerInterface<Sender, Receiver, ReplySenderStore> =
|
||||||
MessageSenderAndReceiver<ModeReply, ModeRequest, S, R>;
|
MessageSenderAndReceiver<ModeReply, ModeRequest, Sender, Receiver, ReplySenderStore>;
|
||||||
|
|
||||||
impl<S: MessageSender<ModeReply>, R: MessageReceiver<ModeRequest>>
|
impl<
|
||||||
ModeRequestHandlerInterface<S, R>
|
Sender: MessageSenderProvider<ModeReply>,
|
||||||
|
Receiver: MessageReceiverProvider<ModeRequest>,
|
||||||
|
ReplySenderStore: MessageSenderStoreProvider<ModeReply, Sender>,
|
||||||
|
> ModeRequestHandlerInterface<Sender, Receiver, ReplySenderStore>
|
||||||
{
|
{
|
||||||
pub fn try_recv_mode_request(
|
pub fn try_recv_mode_request(
|
||||||
&self,
|
&self,
|
||||||
@ -403,9 +459,15 @@ pub mod alloc_mod {
|
|||||||
|
|
||||||
/// Helper type defintion for a mode handler object which can send mode requests and receive
|
/// Helper type defintion for a mode handler object which can send mode requests and receive
|
||||||
/// mode replies.
|
/// mode replies.
|
||||||
pub type ModeRequestorInterface<S, R> = MessageSenderAndReceiver<ModeRequest, ModeReply, S, R>;
|
pub type ModeRequestorInterface<Sender, Receiver, RequestSenderStore> =
|
||||||
|
MessageSenderAndReceiver<ModeRequest, ModeReply, Sender, Receiver, RequestSenderStore>;
|
||||||
|
|
||||||
impl<S: MessageSender<ModeRequest>, R: MessageReceiver<ModeReply>> ModeRequestorInterface<S, R> {
|
impl<
|
||||||
|
Sender: MessageSenderProvider<ModeRequest>,
|
||||||
|
Receiver: MessageReceiverProvider<ModeReply>,
|
||||||
|
RequestSenderStore: MessageSenderStoreProvider<ModeRequest, Sender>,
|
||||||
|
> ModeRequestorInterface<Sender, Receiver, RequestSenderStore>
|
||||||
|
{
|
||||||
pub fn try_recv_mode_reply(
|
pub fn try_recv_mode_reply(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Option<GenericMessage<ModeReply>>, GenericTargetedMessagingError> {
|
) -> Result<Option<GenericMessage<ModeReply>>, GenericTargetedMessagingError> {
|
||||||
@ -424,10 +486,25 @@ pub mod alloc_mod {
|
|||||||
|
|
||||||
/// Helper type defintion for a mode handler object which can both send mode requests and
|
/// Helper type defintion for a mode handler object which can both send mode requests and
|
||||||
/// process mode requests.
|
/// process mode requests.
|
||||||
pub type ModeInterface<S0, R0, S1, R1> =
|
pub type ModeInterface<
|
||||||
RequestAndReplySenderAndReceiver<ModeRequest, ModeReply, S0, R0, S1, R1>;
|
ReqSender,
|
||||||
|
ReqReceiver,
|
||||||
|
ReqSenderStore,
|
||||||
|
ReplySender,
|
||||||
|
ReplyReceiver,
|
||||||
|
ReplySenderStore,
|
||||||
|
> = RequestAndReplySenderAndReceiver<
|
||||||
|
ModeRequest,
|
||||||
|
ReqSender,
|
||||||
|
ReqReceiver,
|
||||||
|
ReqSenderStore,
|
||||||
|
ModeReply,
|
||||||
|
ReplySender,
|
||||||
|
ReplyReceiver,
|
||||||
|
ReplySenderStore,
|
||||||
|
>;
|
||||||
|
|
||||||
impl<S: MessageSender<ModeRequest>> MessageSenderMap<ModeRequest, S> {
|
impl<S: MessageSenderProvider<ModeRequest>> MessageSenderMap<ModeRequest, S> {
|
||||||
pub fn send_mode_request(
|
pub fn send_mode_request(
|
||||||
&self,
|
&self,
|
||||||
requestor_info: MessageMetadata,
|
requestor_info: MessageMetadata,
|
||||||
@ -442,25 +519,13 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
impl<
|
||||||
impl<S: MessageSender<ModeRequest>> ModeRequestSender for MessageSenderMapWithId<ModeRequest, S> {
|
To,
|
||||||
fn local_channel_id(&self) -> ComponentId {
|
Sender: MessageSenderProvider<To>,
|
||||||
self.local_channel_id
|
Receiver: MessageReceiverProvider<ModeRequest>,
|
||||||
}
|
SenderStore: MessageSenderStoreProvider<To, Sender>,
|
||||||
|
> ModeRequestReceiver
|
||||||
fn send_mode_request(
|
for MessageSenderAndReceiver<To, ModeRequest, Sender, Receiver, SenderStore>
|
||||||
&self,
|
|
||||||
request_id: RequestId,
|
|
||||||
target_id: ComponentId,
|
|
||||||
request: ModeRequest,
|
|
||||||
) -> Result<(), GenericTargetedMessagingError> {
|
|
||||||
self.send_message(request_id, target_id, request)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
impl<TO, S: MessageSender<TO>, R: MessageReceiver<ModeRequest>> ModeRequestReceiver
|
|
||||||
for MessageSenderAndReceiver<TO, ModeRequest, S, R>
|
|
||||||
{
|
{
|
||||||
fn try_recv_mode_request(
|
fn try_recv_mode_request(
|
||||||
&self,
|
&self,
|
||||||
@ -469,8 +534,13 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FROM, S: MessageSender<ModeRequest>, R: MessageReceiver<FROM>> ModeRequestSender
|
impl<
|
||||||
for MessageSenderAndReceiver<ModeRequest, FROM, S, R>
|
From,
|
||||||
|
Sender: MessageSenderProvider<ModeRequest>,
|
||||||
|
Receiver: MessageReceiverProvider<From>,
|
||||||
|
SenderStore: MessageSenderStoreProvider<ModeRequest, Sender>,
|
||||||
|
> ModeRequestSender
|
||||||
|
for MessageSenderAndReceiver<ModeRequest, From, Sender, Receiver, SenderStore>
|
||||||
{
|
{
|
||||||
fn local_channel_id(&self) -> ComponentId {
|
fn local_channel_id(&self) -> ComponentId {
|
||||||
self.local_channel_id_generic()
|
self.local_channel_id_generic()
|
||||||
@ -482,7 +552,7 @@ pub mod alloc_mod {
|
|||||||
target_id: ComponentId,
|
target_id: ComponentId,
|
||||||
request: ModeRequest,
|
request: ModeRequest,
|
||||||
) -> Result<(), GenericTargetedMessagingError> {
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
self.message_sender_map.send_mode_request(
|
self.message_sender_store.send_message(
|
||||||
MessageMetadata::new(request_id, self.local_channel_id()),
|
MessageMetadata::new(request_id, self.local_channel_id()),
|
||||||
target_id,
|
target_id,
|
||||||
request,
|
request,
|
||||||
@ -491,27 +561,50 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
REPLY,
|
ReqSender: MessageSenderProvider<ModeRequest>,
|
||||||
S0: MessageSender<ModeRequest>,
|
ReqReceiver: MessageReceiverProvider<ModeRequest>,
|
||||||
R0: MessageReceiver<REPLY>,
|
ReqSenderStore: MessageSenderStoreProvider<ModeRequest, ReqSender>,
|
||||||
S1: MessageSender<REPLY>,
|
Reply,
|
||||||
R1: MessageReceiver<ModeRequest>,
|
ReplySender: MessageSenderProvider<Reply>,
|
||||||
> RequestAndReplySenderAndReceiver<ModeRequest, REPLY, S0, R0, S1, R1>
|
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||||
|
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||||
|
>
|
||||||
|
RequestAndReplySenderAndReceiver<
|
||||||
|
ModeRequest,
|
||||||
|
ReqSender,
|
||||||
|
ReqReceiver,
|
||||||
|
ReqSenderStore,
|
||||||
|
Reply,
|
||||||
|
ReplySender,
|
||||||
|
ReplyReceiver,
|
||||||
|
ReplySenderStore,
|
||||||
|
>
|
||||||
{
|
{
|
||||||
pub fn add_request_target(&mut self, target_id: ComponentId, request_sender: S0) {
|
pub fn add_request_target(&mut self, target_id: ComponentId, request_sender: ReqSender) {
|
||||||
self.request_sender_map
|
self.request_sender_store
|
||||||
.add_message_target(target_id, request_sender)
|
.add_message_target(target_id, request_sender)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
REPLY,
|
ReqSender: MessageSenderProvider<ModeRequest>,
|
||||||
S0: MessageSender<ModeRequest>,
|
ReqReceiver: MessageReceiverProvider<ModeRequest>,
|
||||||
R0: MessageReceiver<REPLY>,
|
ReqSenderStore: MessageSenderStoreProvider<ModeRequest, ReqSender>,
|
||||||
S1: MessageSender<REPLY>,
|
Reply,
|
||||||
R1: MessageReceiver<ModeRequest>,
|
ReplySender: MessageSenderProvider<Reply>,
|
||||||
|
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||||
|
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||||
> ModeRequestSender
|
> ModeRequestSender
|
||||||
for RequestAndReplySenderAndReceiver<ModeRequest, REPLY, S0, R0, S1, R1>
|
for RequestAndReplySenderAndReceiver<
|
||||||
|
ModeRequest,
|
||||||
|
ReqSender,
|
||||||
|
ReqReceiver,
|
||||||
|
ReqSenderStore,
|
||||||
|
Reply,
|
||||||
|
ReplySender,
|
||||||
|
ReplyReceiver,
|
||||||
|
ReplySenderStore,
|
||||||
|
>
|
||||||
{
|
{
|
||||||
fn local_channel_id(&self) -> ComponentId {
|
fn local_channel_id(&self) -> ComponentId {
|
||||||
self.local_channel_id_generic()
|
self.local_channel_id_generic()
|
||||||
@ -523,7 +616,7 @@ pub mod alloc_mod {
|
|||||||
target_id: ComponentId,
|
target_id: ComponentId,
|
||||||
request: ModeRequest,
|
request: ModeRequest,
|
||||||
) -> Result<(), GenericTargetedMessagingError> {
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
self.request_sender_map.send_mode_request(
|
self.request_sender_store.send_message(
|
||||||
MessageMetadata::new(request_id, self.local_channel_id()),
|
MessageMetadata::new(request_id, self.local_channel_id()),
|
||||||
target_id,
|
target_id,
|
||||||
request,
|
request,
|
||||||
@ -532,13 +625,24 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
REPLY,
|
ReqSender: MessageSenderProvider<ModeRequest>,
|
||||||
S0: MessageSender<ModeRequest>,
|
ReqReceiver: MessageReceiverProvider<ModeRequest>,
|
||||||
R0: MessageReceiver<REPLY>,
|
ReqSenderStore: MessageSenderStoreProvider<ModeRequest, ReqSender>,
|
||||||
S1: MessageSender<REPLY>,
|
Reply,
|
||||||
R1: MessageReceiver<ModeRequest>,
|
ReplySender: MessageSenderProvider<Reply>,
|
||||||
|
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||||
|
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||||
> ModeRequestReceiver
|
> ModeRequestReceiver
|
||||||
for RequestAndReplySenderAndReceiver<ModeRequest, REPLY, S0, R0, S1, R1>
|
for RequestAndReplySenderAndReceiver<
|
||||||
|
ModeRequest,
|
||||||
|
ReqSender,
|
||||||
|
ReqReceiver,
|
||||||
|
ReqSenderStore,
|
||||||
|
Reply,
|
||||||
|
ReplySender,
|
||||||
|
ReplyReceiver,
|
||||||
|
ReplySenderStore,
|
||||||
|
>
|
||||||
{
|
{
|
||||||
fn try_recv_mode_request(
|
fn try_recv_mode_request(
|
||||||
&self,
|
&self,
|
||||||
@ -552,37 +656,57 @@ pub mod alloc_mod {
|
|||||||
pub mod std_mod {
|
pub mod std_mod {
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
|
use crate::request::{MessageSenderList, OneMessageSender};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub type ModeRequestHandlerMpsc = ModeRequestHandlerInterface<
|
pub type ModeRequestHandlerMpsc = ModeRequestHandlerInterface<
|
||||||
mpsc::Sender<GenericMessage<ModeReply>>,
|
mpsc::Sender<GenericMessage<ModeReply>>,
|
||||||
mpsc::Receiver<GenericMessage<ModeRequest>>,
|
mpsc::Receiver<GenericMessage<ModeRequest>>,
|
||||||
|
MessageSenderList<ModeReply, mpsc::Sender<GenericMessage<ModeReply>>>,
|
||||||
>;
|
>;
|
||||||
pub type ModeRequestHandlerMpscBounded = ModeRequestHandlerInterface<
|
pub type ModeRequestHandlerMpscBounded = ModeRequestHandlerInterface<
|
||||||
mpsc::SyncSender<GenericMessage<ModeReply>>,
|
mpsc::SyncSender<GenericMessage<ModeReply>>,
|
||||||
mpsc::Receiver<GenericMessage<ModeRequest>>,
|
mpsc::Receiver<GenericMessage<ModeRequest>>,
|
||||||
|
MessageSenderList<ModeReply, mpsc::SyncSender<GenericMessage<ModeReply>>>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub type ModeRequestorMpsc = ModeRequestorInterface<
|
pub type ModeRequestorOneChildMpsc = ModeRequestorInterface<
|
||||||
mpsc::Sender<GenericMessage<ModeRequest>>,
|
mpsc::Sender<GenericMessage<ModeRequest>>,
|
||||||
mpsc::Receiver<GenericMessage<ModeReply>>,
|
mpsc::Receiver<GenericMessage<ModeReply>>,
|
||||||
|
OneMessageSender<ModeRequest, mpsc::Sender<GenericMessage<ModeRequest>>>,
|
||||||
>;
|
>;
|
||||||
pub type ModeRequestorBoundedMpsc = ModeRequestorInterface<
|
pub type ModeRequestorOneChildBoundedMpsc = ModeRequestorInterface<
|
||||||
mpsc::SyncSender<GenericMessage<ModeRequest>>,
|
mpsc::SyncSender<GenericMessage<ModeRequest>>,
|
||||||
mpsc::Receiver<GenericMessage<ModeReply>>,
|
mpsc::Receiver<GenericMessage<ModeReply>>,
|
||||||
|
OneMessageSender<ModeRequest, mpsc::SyncSender<GenericMessage<ModeRequest>>>,
|
||||||
|
>;
|
||||||
|
pub type ModeRequestorChildListMpsc = ModeRequestorInterface<
|
||||||
|
mpsc::Sender<GenericMessage<ModeRequest>>,
|
||||||
|
mpsc::Receiver<GenericMessage<ModeReply>>,
|
||||||
|
MessageSenderList<ModeRequest, mpsc::Sender<GenericMessage<ModeRequest>>>,
|
||||||
|
>;
|
||||||
|
pub type ModeRequestorChildListBoundedMpsc = ModeRequestorInterface<
|
||||||
|
mpsc::SyncSender<GenericMessage<ModeRequest>>,
|
||||||
|
mpsc::Receiver<GenericMessage<ModeReply>>,
|
||||||
|
MessageSenderList<ModeRequest, mpsc::SyncSender<GenericMessage<ModeRequest>>>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub type ModeRequestorAndHandlerMpsc = ModeInterface<
|
pub type ModeRequestorAndHandlerMpsc = ModeInterface<
|
||||||
mpsc::Sender<GenericMessage<ModeRequest>>,
|
mpsc::Sender<GenericMessage<ModeRequest>>,
|
||||||
mpsc::Receiver<GenericMessage<ModeReply>>,
|
|
||||||
mpsc::Sender<GenericMessage<ModeReply>>,
|
|
||||||
mpsc::Receiver<GenericMessage<ModeRequest>>,
|
mpsc::Receiver<GenericMessage<ModeRequest>>,
|
||||||
|
MessageSenderList<ModeRequest, mpsc::Sender<GenericMessage<ModeRequest>>>,
|
||||||
|
mpsc::Sender<GenericMessage<ModeReply>>,
|
||||||
|
mpsc::Receiver<GenericMessage<ModeReply>>,
|
||||||
|
MessageSenderList<ModeReply, mpsc::Sender<GenericMessage<ModeReply>>>,
|
||||||
>;
|
>;
|
||||||
pub type ModeRequestorAndHandlerMpscBounded = ModeInterface<
|
pub type ModeRequestorAndHandlerMpscBounded = ModeInterface<
|
||||||
mpsc::SyncSender<GenericMessage<ModeRequest>>,
|
mpsc::SyncSender<GenericMessage<ModeRequest>>,
|
||||||
mpsc::Receiver<GenericMessage<ModeReply>>,
|
|
||||||
mpsc::SyncSender<GenericMessage<ModeReply>>,
|
|
||||||
mpsc::Receiver<GenericMessage<ModeRequest>>,
|
mpsc::Receiver<GenericMessage<ModeRequest>>,
|
||||||
|
MessageSenderList<ModeRequest, mpsc::SyncSender<GenericMessage<ModeRequest>>>,
|
||||||
|
mpsc::SyncSender<GenericMessage<ModeReply>>,
|
||||||
|
mpsc::Receiver<GenericMessage<ModeReply>>,
|
||||||
|
MessageSenderList<ModeReply, mpsc::SyncSender<GenericMessage<ModeReply>>>,
|
||||||
>;
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,57 @@ use alloc::vec::Vec;
|
|||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
mode::{Mode, ModeAndSubmode, Submode},
|
mode::{Mode, ModeAndSubmode, ModeReply, ModeRequest, Submode},
|
||||||
|
request::MessageSenderProvider,
|
||||||
ComponentId,
|
ComponentId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
pub use alloc_mod::*;
|
||||||
|
|
||||||
|
/// Common trait for node modes which can have mode parents or mode children.
|
||||||
|
pub trait ModeNode {
|
||||||
|
fn id(&self) -> ComponentId;
|
||||||
|
}
|
||||||
|
/// Trait which denotes that an object is a parent in a mode tree.
|
||||||
|
///
|
||||||
|
/// A mode parent is capable of sending mode requests to child objects and has a unique component
|
||||||
|
/// ID.
|
||||||
|
pub trait ModeParent: ModeNode {
|
||||||
|
type Sender: MessageSenderProvider<ModeRequest>;
|
||||||
|
|
||||||
|
fn add_mode_child(&mut self, id: ComponentId, request_sender: Self::Sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Trait which denotes that an object is a child in a mode tree.
|
||||||
|
///
|
||||||
|
/// A child is capable of sending mode replies to parent objects and has a unique component ID.
|
||||||
|
pub trait ModeChild: ModeNode {
|
||||||
|
type Sender: MessageSenderProvider<ModeReply>;
|
||||||
|
|
||||||
|
fn add_mode_parent(&mut self, id: ComponentId, reply_sender: Self::Sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Utility method which connects a mode tree parent object to a child object by calling
|
||||||
|
/// [ModeParent::add_mode_child] on the [parent][ModeParent] and calling
|
||||||
|
/// [ModeChild::add_mode_parent] on the [child][ModeChild].
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `parent` - The parent object which implements [ModeParent].
|
||||||
|
/// * `request_sender` - Sender object to send mode requests to the child.
|
||||||
|
/// * `child` - The child object which implements [ModeChild].
|
||||||
|
/// * `reply_sender` - Sender object to send mode replies to the parent.
|
||||||
|
pub fn connect_mode_nodes<ReqSender, ReplySender>(
|
||||||
|
parent: &mut impl ModeParent<Sender = ReqSender>,
|
||||||
|
request_sender: ReqSender,
|
||||||
|
child: &mut impl ModeChild<Sender = ReplySender>,
|
||||||
|
reply_sender: ReplySender,
|
||||||
|
) {
|
||||||
|
parent.add_mode_child(child.id(), request_sender);
|
||||||
|
child.add_mode_parent(parent.id(), reply_sender);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum TableEntryType {
|
pub enum TableEntryType {
|
||||||
/// Target table containing information of the expected children modes for given mode.
|
/// Target table containing information of the expected children modes for given mode.
|
||||||
@ -15,23 +62,279 @@ pub enum TableEntryType {
|
|||||||
Sequence,
|
Sequence,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ModeTableEntry {
|
/// Common fields required for both target and sequence table entries.
|
||||||
|
///
|
||||||
|
/// The most important parameters here are the target ID which this entry belongs to, and the mode
|
||||||
|
/// and submode the entry either will be commanded to for sequence table entries or which will be
|
||||||
|
/// monitored for target table entries.
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct ModeTableEntryCommon {
|
||||||
/// Name of respective table entry.
|
/// Name of respective table entry.
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
/// Target channel ID.
|
/// Target component ID.
|
||||||
pub channel_id: ComponentId,
|
pub target_id: ComponentId,
|
||||||
|
/// Has a different meaning depending on whether this is a sequence table or a target table.
|
||||||
|
///
|
||||||
|
/// - For sequence tables, this denotes the mode which will be commanded
|
||||||
|
/// - For target tables, this is the mode which the target children should have and which
|
||||||
|
/// might be monitored depending on configuration.
|
||||||
pub mode_submode: ModeAndSubmode,
|
pub mode_submode: ModeAndSubmode,
|
||||||
|
/// This mask allows to specify multiple allowed submodes for a given mode.
|
||||||
pub allowed_submode_mask: Option<Submode>,
|
pub allowed_submode_mask: Option<Submode>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModeTableEntryCommon {
|
||||||
|
pub fn set_allowed_submode_mask(&mut self, mask: Submode) {
|
||||||
|
self.allowed_submode_mask = Some(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn allowed_submode_mask(&self) -> Option<Submode> {
|
||||||
|
self.allowed_submode_mask
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An entry for the target tables.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TargetTableEntry {
|
||||||
|
pub common: ModeTableEntryCommon,
|
||||||
|
pub monitor_state: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TargetTableEntry {
|
||||||
|
pub fn new(
|
||||||
|
name: &'static str,
|
||||||
|
target_id: ComponentId,
|
||||||
|
mode_submode: ModeAndSubmode,
|
||||||
|
monitor_state: bool,
|
||||||
|
allowed_submode_mask: Option<Submode>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
common: ModeTableEntryCommon {
|
||||||
|
name,
|
||||||
|
target_id,
|
||||||
|
mode_submode,
|
||||||
|
allowed_submode_mask,
|
||||||
|
},
|
||||||
|
monitor_state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_precise_submode(
|
||||||
|
name: &'static str,
|
||||||
|
target_id: ComponentId,
|
||||||
|
mode_submode: ModeAndSubmode,
|
||||||
|
monitor_state: bool,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
common: ModeTableEntryCommon {
|
||||||
|
name,
|
||||||
|
target_id,
|
||||||
|
mode_submode,
|
||||||
|
allowed_submode_mask: None,
|
||||||
|
},
|
||||||
|
monitor_state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate::delegate! {
|
||||||
|
to self.common {
|
||||||
|
pub fn set_allowed_submode_mask(&mut self, mask: Submode);
|
||||||
|
pub fn allowed_submode_mask(&self) -> Option<Submode>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An entry for the sequence tables.
|
||||||
|
///
|
||||||
|
/// The `check_success` field instructs the mode sequence executor to verify that the
|
||||||
|
/// target mode was actually reached before executing the next sequence.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SequenceTableEntry {
|
||||||
|
pub common: ModeTableEntryCommon,
|
||||||
pub check_success: bool,
|
pub check_success: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ModeTableMapValue {
|
impl SequenceTableEntry {
|
||||||
/// Name for a given mode table entry.
|
pub fn new(
|
||||||
pub name: &'static str,
|
name: &'static str,
|
||||||
pub entries: Vec<ModeTableEntry>,
|
target_id: ComponentId,
|
||||||
|
mode_submode: ModeAndSubmode,
|
||||||
|
check_success: bool,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
common: ModeTableEntryCommon {
|
||||||
|
name,
|
||||||
|
target_id,
|
||||||
|
mode_submode,
|
||||||
|
allowed_submode_mask: None,
|
||||||
|
},
|
||||||
|
check_success,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate::delegate! {
|
||||||
|
to self.common {
|
||||||
|
pub fn set_allowed_submode_mask(&mut self, mask: Submode);
|
||||||
|
pub fn allowed_submode_mask(&self) -> Option<Submode>;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ModeTable = HashMap<Mode, ModeTableMapValue>;
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
#[error("target {0} not in mode store")]
|
||||||
|
pub struct TargetNotInModeStoreError(pub ComponentId);
|
||||||
|
|
||||||
|
pub trait ModeStoreProvider {
|
||||||
|
fn add_component(&mut self, target_id: ComponentId, mode: ModeAndSubmode);
|
||||||
|
|
||||||
|
fn has_component(&self, target_id: ComponentId) -> bool;
|
||||||
|
|
||||||
|
fn get_mode(&self, target_id: ComponentId) -> Option<ModeAndSubmode>;
|
||||||
|
|
||||||
|
fn set_mode_for_contained_component(&mut self, target_id: ComponentId, mode: ModeAndSubmode);
|
||||||
|
|
||||||
|
fn set_mode(
|
||||||
|
&mut self,
|
||||||
|
target_id: ComponentId,
|
||||||
|
mode: ModeAndSubmode,
|
||||||
|
) -> Result<(), TargetNotInModeStoreError> {
|
||||||
|
if !self.has_component(target_id) {
|
||||||
|
return Err(TargetNotInModeStoreError(target_id));
|
||||||
|
}
|
||||||
|
self.set_mode_for_contained_component(target_id, mode);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
pub mod alloc_mod {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TargetTablesMapValue {
|
||||||
|
/// Name for a given mode table entry.
|
||||||
|
pub name: &'static str,
|
||||||
|
/// These are the rows of the a target table.
|
||||||
|
pub entries: Vec<TargetTableEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TargetTablesMapValue {
|
||||||
|
pub fn new(name: &'static str) -> Self {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
entries: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_entry(&mut self, entry: TargetTableEntry) {
|
||||||
|
self.entries.push(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SequenceTableMapTable {
|
||||||
|
/// Name for a given mode sequence.
|
||||||
|
pub name: &'static str,
|
||||||
|
/// These are the rows of the a sequence table.
|
||||||
|
pub entries: Vec<SequenceTableEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SequenceTableMapTable {
|
||||||
|
pub fn new(name: &'static str) -> Self {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
entries: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_entry(&mut self, entry: SequenceTableEntry) {
|
||||||
|
self.entries.push(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SequenceTablesMapValue {
|
||||||
|
/// Name for a given mode sequence.
|
||||||
|
pub name: &'static str,
|
||||||
|
/// Each sequence can consists of multiple sequences that are executed consecutively.
|
||||||
|
pub entries: Vec<SequenceTableMapTable>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SequenceTablesMapValue {
|
||||||
|
pub fn new(name: &'static str) -> Self {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
entries: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_sequence_table(&mut self, entry: SequenceTableMapTable) {
|
||||||
|
self.entries.push(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct TargetModeTables(pub HashMap<Mode, TargetTablesMapValue>);
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct SequenceModeTables(pub HashMap<Mode, SequenceTablesMapValue>);
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct ModeStoreVec(pub alloc::vec::Vec<(ComponentId, ModeAndSubmode)>);
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct ModeStoreMap(pub hashbrown::HashMap<ComponentId, ModeAndSubmode>);
|
||||||
|
|
||||||
|
impl ModeStoreProvider for ModeStoreVec {
|
||||||
|
fn add_component(&mut self, target_id: ComponentId, mode: ModeAndSubmode) {
|
||||||
|
self.0.push((target_id, mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_component(&self, target_id: ComponentId) -> bool {
|
||||||
|
self.0.iter().any(|(id, _)| *id == target_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mode(&self, target_id: ComponentId) -> Option<ModeAndSubmode> {
|
||||||
|
self.0.iter().find_map(|(id, mode)| {
|
||||||
|
if *id == target_id {
|
||||||
|
return Some(*mode);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_mode_for_contained_component(
|
||||||
|
&mut self,
|
||||||
|
target_id: ComponentId,
|
||||||
|
mode_to_set: ModeAndSubmode,
|
||||||
|
) {
|
||||||
|
self.0.iter_mut().for_each(|(id, mode)| {
|
||||||
|
if *id == target_id {
|
||||||
|
*mode = mode_to_set;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModeStoreProvider for ModeStoreMap {
|
||||||
|
fn add_component(&mut self, target_id: ComponentId, mode: ModeAndSubmode) {
|
||||||
|
self.0.insert(target_id, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_component(&self, target_id: ComponentId) -> bool {
|
||||||
|
self.0.contains_key(&target_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mode(&self, target_id: ComponentId) -> Option<ModeAndSubmode> {
|
||||||
|
self.0.get(&target_id).copied()
|
||||||
|
}
|
||||||
|
fn set_mode_for_contained_component(
|
||||||
|
&mut self,
|
||||||
|
target_id: ComponentId,
|
||||||
|
mode_to_set: ModeAndSubmode,
|
||||||
|
) {
|
||||||
|
self.0.insert(target_id, mode_to_set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {}
|
mod tests {}
|
||||||
|
@ -68,7 +68,8 @@ pub mod alloc_mod {
|
|||||||
action::ActionRequest,
|
action::ActionRequest,
|
||||||
queue::GenericTargetedMessagingError,
|
queue::GenericTargetedMessagingError,
|
||||||
request::{
|
request::{
|
||||||
GenericMessage, MessageReceiver, MessageSender, MessageSenderAndReceiver, RequestId,
|
GenericMessage, MessageReceiverProvider, MessageSenderAndReceiver,
|
||||||
|
MessageSenderProvider, MessageSenderStoreProvider, RequestId,
|
||||||
},
|
},
|
||||||
ComponentId,
|
ComponentId,
|
||||||
};
|
};
|
||||||
@ -76,11 +77,14 @@ pub mod alloc_mod {
|
|||||||
use super::ActionReplyPus;
|
use super::ActionReplyPus;
|
||||||
|
|
||||||
/// Helper type definition for a mode handler which can handle mode requests.
|
/// Helper type definition for a mode handler which can handle mode requests.
|
||||||
pub type ActionRequestHandlerInterface<S, R> =
|
pub type ActionRequestHandlerInterface<Sender, Receiver, ReplySenderStore> =
|
||||||
MessageSenderAndReceiver<ActionReplyPus, ActionRequest, S, R>;
|
MessageSenderAndReceiver<ActionReplyPus, ActionRequest, Sender, Receiver, ReplySenderStore>;
|
||||||
|
|
||||||
impl<S: MessageSender<ActionReplyPus>, R: MessageReceiver<ActionRequest>>
|
impl<
|
||||||
ActionRequestHandlerInterface<S, R>
|
Sender: MessageSenderProvider<ActionReplyPus>,
|
||||||
|
Receiver: MessageReceiverProvider<ActionRequest>,
|
||||||
|
ReplySender: MessageSenderStoreProvider<ActionReplyPus, Sender>,
|
||||||
|
> ActionRequestHandlerInterface<Sender, Receiver, ReplySender>
|
||||||
{
|
{
|
||||||
pub fn try_recv_action_request(
|
pub fn try_recv_action_request(
|
||||||
&self,
|
&self,
|
||||||
@ -100,11 +104,20 @@ pub mod alloc_mod {
|
|||||||
|
|
||||||
/// Helper type defintion for a mode handler object which can send mode requests and receive
|
/// Helper type defintion for a mode handler object which can send mode requests and receive
|
||||||
/// mode replies.
|
/// mode replies.
|
||||||
pub type ActionRequestorInterface<S, R> =
|
pub type ActionRequestorInterface<Sender, Receiver, RequestSenderStore> =
|
||||||
MessageSenderAndReceiver<ActionRequest, ActionReplyPus, S, R>;
|
MessageSenderAndReceiver<
|
||||||
|
ActionRequest,
|
||||||
|
ActionReplyPus,
|
||||||
|
Sender,
|
||||||
|
Receiver,
|
||||||
|
RequestSenderStore,
|
||||||
|
>;
|
||||||
|
|
||||||
impl<S: MessageSender<ActionRequest>, R: MessageReceiver<ActionReplyPus>>
|
impl<
|
||||||
ActionRequestorInterface<S, R>
|
Sender: MessageSenderProvider<ActionRequest>,
|
||||||
|
Receiver: MessageReceiverProvider<ActionReplyPus>,
|
||||||
|
RequestSenderStore: MessageSenderStoreProvider<ActionRequest, Sender>,
|
||||||
|
> ActionRequestorInterface<Sender, Receiver, RequestSenderStore>
|
||||||
{
|
{
|
||||||
pub fn try_recv_action_reply(
|
pub fn try_recv_action_reply(
|
||||||
&self,
|
&self,
|
||||||
@ -132,6 +145,7 @@ pub mod std_mod {
|
|||||||
verification::{self, TcStateToken},
|
verification::{self, TcStateToken},
|
||||||
ActivePusRequestStd, ActiveRequestProvider, DefaultActiveRequestMap,
|
ActivePusRequestStd, ActiveRequestProvider, DefaultActiveRequestMap,
|
||||||
},
|
},
|
||||||
|
request::{MessageSenderMap, OneMessageSender},
|
||||||
ComponentId,
|
ComponentId,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -174,22 +188,38 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
pub type DefaultActiveActionRequestMap = DefaultActiveRequestMap<ActivePusActionRequestStd>;
|
pub type DefaultActiveActionRequestMap = DefaultActiveRequestMap<ActivePusActionRequestStd>;
|
||||||
|
|
||||||
pub type ActionRequestHandlerMpsc = ActionRequestHandlerInterface<
|
pub type ActionRequestHandlerOneSenderMpsc = ActionRequestHandlerInterface<
|
||||||
mpsc::Sender<GenericMessage<ActionReplyPus>>,
|
mpsc::Sender<GenericMessage<ActionReplyPus>>,
|
||||||
mpsc::Receiver<GenericMessage<ActionRequest>>,
|
mpsc::Receiver<GenericMessage<ActionRequest>>,
|
||||||
|
OneMessageSender<
|
||||||
|
GenericMessage<ActionReplyPus>,
|
||||||
|
mpsc::Sender<GenericMessage<ActionReplyPus>>,
|
||||||
|
>,
|
||||||
>;
|
>;
|
||||||
pub type ActionRequestHandlerMpscBounded = ActionRequestHandlerInterface<
|
pub type ActionRequestHandlerOneSenderMpscBounded = ActionRequestHandlerInterface<
|
||||||
mpsc::SyncSender<GenericMessage<ActionReplyPus>>,
|
mpsc::SyncSender<GenericMessage<ActionReplyPus>>,
|
||||||
mpsc::Receiver<GenericMessage<ActionRequest>>,
|
mpsc::Receiver<GenericMessage<ActionRequest>>,
|
||||||
|
OneMessageSender<
|
||||||
|
GenericMessage<ActionReplyPus>,
|
||||||
|
mpsc::SyncSender<GenericMessage<ActionReplyPus>>,
|
||||||
|
>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub type ActionRequestorMpsc = ActionRequestorInterface<
|
pub type ActionRequestorWithSenderMapMpsc = ActionRequestorInterface<
|
||||||
mpsc::Sender<GenericMessage<ActionRequest>>,
|
mpsc::Sender<GenericMessage<ActionRequest>>,
|
||||||
mpsc::Receiver<GenericMessage<ActionReplyPus>>,
|
mpsc::Receiver<GenericMessage<ActionReplyPus>>,
|
||||||
|
MessageSenderMap<
|
||||||
|
GenericMessage<ActionRequest>,
|
||||||
|
mpsc::Sender<GenericMessage<ActionRequest>>,
|
||||||
|
>,
|
||||||
>;
|
>;
|
||||||
pub type ActionRequestorBoundedMpsc = ActionRequestorInterface<
|
pub type ActionRequestorWithSenderMapBoundedMpsc = ActionRequestorInterface<
|
||||||
mpsc::SyncSender<GenericMessage<ActionRequest>>,
|
mpsc::SyncSender<GenericMessage<ActionRequest>>,
|
||||||
mpsc::Receiver<GenericMessage<ActionReplyPus>>,
|
mpsc::Receiver<GenericMessage<ActionReplyPus>>,
|
||||||
|
MessageSenderMap<
|
||||||
|
GenericMessage<ActionRequest>,
|
||||||
|
mpsc::SyncSender<GenericMessage<ActionRequest>>,
|
||||||
|
>,
|
||||||
>;
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ mod tests {
|
|||||||
use crate::{
|
use crate::{
|
||||||
mode::{
|
mode::{
|
||||||
ModeAndSubmode, ModeReply, ModeReplySender, ModeRequest, ModeRequestSender,
|
ModeAndSubmode, ModeReply, ModeReplySender, ModeRequest, ModeRequestSender,
|
||||||
ModeRequestorAndHandlerMpsc, ModeRequestorMpsc,
|
ModeRequestorAndHandlerOneParentMpsc, ModeRequestorOneChildMpsc,
|
||||||
},
|
},
|
||||||
request::{GenericMessage, MessageMetadata},
|
request::{GenericMessage, MessageMetadata},
|
||||||
};
|
};
|
||||||
@ -52,7 +52,8 @@ mod tests {
|
|||||||
fn test_simple_mode_requestor() {
|
fn test_simple_mode_requestor() {
|
||||||
let (reply_sender, reply_receiver) = mpsc::channel();
|
let (reply_sender, reply_receiver) = mpsc::channel();
|
||||||
let (request_sender, request_receiver) = mpsc::channel();
|
let (request_sender, request_receiver) = mpsc::channel();
|
||||||
let mut mode_requestor = ModeRequestorMpsc::new(TEST_COMPONENT_ID_0, reply_receiver);
|
let mut mode_requestor =
|
||||||
|
ModeRequestorOneChildMpsc::new(TEST_COMPONENT_ID_0, reply_receiver);
|
||||||
mode_requestor.add_message_target(TEST_COMPONENT_ID_1, request_sender);
|
mode_requestor.add_message_target(TEST_COMPONENT_ID_1, request_sender);
|
||||||
|
|
||||||
// Send a request and verify it arrives at the receiver.
|
// Send a request and verify it arrives at the receiver.
|
||||||
@ -89,7 +90,7 @@ mod tests {
|
|||||||
|
|
||||||
let (request_sender_to_channel_1, request_receiver_channel_1) = mpsc::channel();
|
let (request_sender_to_channel_1, request_receiver_channel_1) = mpsc::channel();
|
||||||
//let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
//let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
||||||
let mut mode_connector = ModeRequestorAndHandlerMpsc::new(
|
let mut mode_connector = ModeRequestorAndHandlerOneParentMpsc::new(
|
||||||
TEST_COMPONENT_ID_0,
|
TEST_COMPONENT_ID_0,
|
||||||
request_receiver_of_connector,
|
request_receiver_of_connector,
|
||||||
reply_receiver_of_connector,
|
reply_receiver_of_connector,
|
||||||
@ -128,7 +129,7 @@ mod tests {
|
|||||||
let (_request_sender_to_connector, request_receiver_of_connector) = mpsc::channel();
|
let (_request_sender_to_connector, request_receiver_of_connector) = mpsc::channel();
|
||||||
|
|
||||||
let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
||||||
let mut mode_connector = ModeRequestorAndHandlerMpsc::new(
|
let mut mode_connector = ModeRequestorAndHandlerOneParentMpsc::new(
|
||||||
TEST_COMPONENT_ID_0,
|
TEST_COMPONENT_ID_0,
|
||||||
request_receiver_of_connector,
|
request_receiver_of_connector,
|
||||||
reply_receiver_of_connector,
|
reply_receiver_of_connector,
|
||||||
|
@ -140,24 +140,27 @@ impl<Message> GenericMessage<Message> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generic trait for objects which can send targeted messages.
|
/// Generic trait for objects which can send targeted messages.
|
||||||
pub trait MessageSender<MSG>: Send {
|
pub trait MessageSenderProvider<MSG>: Send {
|
||||||
fn send(&self, message: GenericMessage<MSG>) -> Result<(), GenericTargetedMessagingError>;
|
fn send(&self, message: GenericMessage<MSG>) -> Result<(), GenericTargetedMessagingError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic trait for objects which can receive targeted messages.
|
// Generic trait for objects which can receive targeted messages.
|
||||||
pub trait MessageReceiver<MSG> {
|
pub trait MessageReceiverProvider<MSG> {
|
||||||
fn try_recv(&self) -> Result<Option<GenericMessage<MSG>>, GenericTargetedMessagingError>;
|
fn try_recv(&self) -> Result<Option<GenericMessage<MSG>>, GenericTargetedMessagingError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MessageWithSenderIdReceiver<MSG, R: MessageReceiver<MSG>>(pub R, PhantomData<MSG>);
|
pub struct MessageWithSenderIdReceiver<Msg, Receiver: MessageReceiverProvider<Msg>>(
|
||||||
|
pub Receiver,
|
||||||
|
PhantomData<Msg>,
|
||||||
|
);
|
||||||
|
|
||||||
impl<MSG, R: MessageReceiver<MSG>> From<R> for MessageWithSenderIdReceiver<MSG, R> {
|
impl<MSG, R: MessageReceiverProvider<MSG>> From<R> for MessageWithSenderIdReceiver<MSG, R> {
|
||||||
fn from(receiver: R) -> Self {
|
fn from(receiver: R) -> Self {
|
||||||
MessageWithSenderIdReceiver(receiver, PhantomData)
|
MessageWithSenderIdReceiver(receiver, PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MSG, R: MessageReceiver<MSG>> MessageWithSenderIdReceiver<MSG, R> {
|
impl<MSG, R: MessageReceiverProvider<MSG>> MessageWithSenderIdReceiver<MSG, R> {
|
||||||
pub fn try_recv_message(
|
pub fn try_recv_message(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Option<GenericMessage<MSG>>, GenericTargetedMessagingError> {
|
) -> Result<Option<GenericMessage<MSG>>, GenericTargetedMessagingError> {
|
||||||
@ -165,12 +168,12 @@ impl<MSG, R: MessageReceiver<MSG>> MessageWithSenderIdReceiver<MSG, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MessageReceiverWithId<MSG, R: MessageReceiver<MSG>> {
|
pub struct MessageReceiverWithId<MSG, R: MessageReceiverProvider<MSG>> {
|
||||||
local_channel_id: ComponentId,
|
local_channel_id: ComponentId,
|
||||||
reply_receiver: MessageWithSenderIdReceiver<MSG, R>,
|
reply_receiver: MessageWithSenderIdReceiver<MSG, R>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MSG, R: MessageReceiver<MSG>> MessageReceiverWithId<MSG, R> {
|
impl<MSG, R: MessageReceiverProvider<MSG>> MessageReceiverWithId<MSG, R> {
|
||||||
pub fn new(local_channel_id: ComponentId, reply_receiver: R) -> Self {
|
pub fn new(local_channel_id: ComponentId, reply_receiver: R) -> Self {
|
||||||
Self {
|
Self {
|
||||||
local_channel_id,
|
local_channel_id,
|
||||||
@ -183,7 +186,7 @@ impl<MSG, R: MessageReceiver<MSG>> MessageReceiverWithId<MSG, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MSG, R: MessageReceiver<MSG>> MessageReceiverWithId<MSG, R> {
|
impl<MSG, R: MessageReceiverProvider<MSG>> MessageReceiverWithId<MSG, R> {
|
||||||
pub fn try_recv_message(
|
pub fn try_recv_message(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Option<GenericMessage<MSG>>, GenericTargetedMessagingError> {
|
) -> Result<Option<GenericMessage<MSG>>, GenericTargetedMessagingError> {
|
||||||
@ -191,34 +194,122 @@ impl<MSG, R: MessageReceiver<MSG>> MessageReceiverWithId<MSG, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait MessageSenderStoreProvider<Message, Sender>: Default {
|
||||||
|
fn add_message_target(&mut self, target_id: ComponentId, message_sender: Sender);
|
||||||
|
|
||||||
|
fn send_message(
|
||||||
|
&self,
|
||||||
|
requestor_info: MessageMetadata,
|
||||||
|
target_channel_id: ComponentId,
|
||||||
|
message: Message,
|
||||||
|
) -> Result<(), GenericTargetedMessagingError>;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub mod alloc_mod {
|
pub mod alloc_mod {
|
||||||
use crate::queue::GenericSendError;
|
use crate::queue::GenericSendError;
|
||||||
|
use std::convert::From;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
pub struct MessageSenderMap<MSG, S: MessageSender<MSG>>(
|
pub struct OneMessageSender<Msg, S: MessageSenderProvider<Msg>> {
|
||||||
pub HashMap<ComponentId, S>,
|
pub id_and_sender: Option<(ComponentId, S)>,
|
||||||
|
pub(crate) phantom: PhantomData<Msg>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Msg, S: MessageSenderProvider<Msg>> Default for OneMessageSender<Msg, S> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
id_and_sender: Default::default(),
|
||||||
|
phantom: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Msg, Sender: MessageSenderProvider<Msg>> MessageSenderStoreProvider<Msg, Sender>
|
||||||
|
for OneMessageSender<Msg, Sender>
|
||||||
|
{
|
||||||
|
fn add_message_target(&mut self, target_id: ComponentId, message_sender: Sender) {
|
||||||
|
if self.id_and_sender.is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.id_and_sender = Some((target_id, message_sender));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_message(
|
||||||
|
&self,
|
||||||
|
requestor_info: MessageMetadata,
|
||||||
|
target_channel_id: ComponentId,
|
||||||
|
message: Msg,
|
||||||
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
|
if let Some((current_id, sender)) = &self.id_and_sender {
|
||||||
|
if *current_id == target_channel_id {
|
||||||
|
sender.send(GenericMessage::new(requestor_info, message))?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(GenericSendError::TargetDoesNotExist(target_channel_id).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MessageSenderList<MSG, S: MessageSenderProvider<MSG>>(
|
||||||
|
pub alloc::vec::Vec<(ComponentId, S)>,
|
||||||
pub(crate) PhantomData<MSG>,
|
pub(crate) PhantomData<MSG>,
|
||||||
);
|
);
|
||||||
|
|
||||||
impl<MSG, S: MessageSender<MSG>> Default for MessageSenderMap<MSG, S> {
|
impl<MSG, S: MessageSenderProvider<MSG>> Default for MessageSenderList<MSG, S> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self(Default::default(), PhantomData)
|
Self(Default::default(), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MSG, S: MessageSender<MSG>> MessageSenderMap<MSG, S> {
|
impl<Msg, Sender: MessageSenderProvider<Msg>> MessageSenderStoreProvider<Msg, Sender>
|
||||||
pub fn add_message_target(&mut self, target_id: ComponentId, message_sender: S) {
|
for MessageSenderList<Msg, Sender>
|
||||||
self.0.insert(target_id, message_sender);
|
{
|
||||||
|
fn add_message_target(&mut self, target_id: ComponentId, message_sender: Sender) {
|
||||||
|
self.0.push((target_id, message_sender));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_message(
|
fn send_message(
|
||||||
&self,
|
&self,
|
||||||
requestor_info: MessageMetadata,
|
requestor_info: MessageMetadata,
|
||||||
target_channel_id: ComponentId,
|
target_channel_id: ComponentId,
|
||||||
message: MSG,
|
message: Msg,
|
||||||
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
|
for (current_id, sender) in &self.0 {
|
||||||
|
if *current_id == target_channel_id {
|
||||||
|
sender.send(GenericMessage::new(requestor_info, message))?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(GenericSendError::TargetDoesNotExist(target_channel_id).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MessageSenderMap<MSG, S: MessageSenderProvider<MSG>>(
|
||||||
|
pub HashMap<ComponentId, S>,
|
||||||
|
pub(crate) PhantomData<MSG>,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl<MSG, S: MessageSenderProvider<MSG>> Default for MessageSenderMap<MSG, S> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(Default::default(), PhantomData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Msg, Sender: MessageSenderProvider<Msg>> MessageSenderStoreProvider<Msg, Sender>
|
||||||
|
for MessageSenderMap<Msg, Sender>
|
||||||
|
{
|
||||||
|
fn add_message_target(&mut self, target_id: ComponentId, message_sender: Sender) {
|
||||||
|
self.0.insert(target_id, message_sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_message(
|
||||||
|
&self,
|
||||||
|
requestor_info: MessageMetadata,
|
||||||
|
target_channel_id: ComponentId,
|
||||||
|
message: Msg,
|
||||||
) -> Result<(), GenericTargetedMessagingError> {
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
if self.0.contains_key(&target_channel_id) {
|
if self.0.contains_key(&target_channel_id) {
|
||||||
return self
|
return self
|
||||||
@ -231,25 +322,38 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MessageSenderAndReceiver<TO, FROM, S: MessageSender<TO>, R: MessageReceiver<FROM>> {
|
pub struct MessageSenderAndReceiver<
|
||||||
|
To,
|
||||||
|
From,
|
||||||
|
Sender: MessageSenderProvider<To>,
|
||||||
|
Receiver: MessageReceiverProvider<From>,
|
||||||
|
SenderStore: MessageSenderStoreProvider<To, Sender>,
|
||||||
|
> {
|
||||||
pub local_channel_id: ComponentId,
|
pub local_channel_id: ComponentId,
|
||||||
pub message_sender_map: MessageSenderMap<TO, S>,
|
pub message_sender_store: SenderStore,
|
||||||
pub message_receiver: MessageWithSenderIdReceiver<FROM, R>,
|
pub message_receiver: MessageWithSenderIdReceiver<From, Receiver>,
|
||||||
|
pub(crate) phantom: PhantomData<(To, Sender)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TO, FROM, S: MessageSender<TO>, R: MessageReceiver<FROM>>
|
impl<
|
||||||
MessageSenderAndReceiver<TO, FROM, S, R>
|
To,
|
||||||
|
From,
|
||||||
|
Sender: MessageSenderProvider<To>,
|
||||||
|
Receiver: MessageReceiverProvider<From>,
|
||||||
|
SenderStore: MessageSenderStoreProvider<To, Sender>,
|
||||||
|
> MessageSenderAndReceiver<To, From, Sender, Receiver, SenderStore>
|
||||||
{
|
{
|
||||||
pub fn new(local_channel_id: ComponentId, message_receiver: R) -> Self {
|
pub fn new(local_channel_id: ComponentId, message_receiver: Receiver) -> Self {
|
||||||
Self {
|
Self {
|
||||||
local_channel_id,
|
local_channel_id,
|
||||||
message_sender_map: Default::default(),
|
message_sender_store: Default::default(),
|
||||||
message_receiver: MessageWithSenderIdReceiver::from(message_receiver),
|
message_receiver: MessageWithSenderIdReceiver::from(message_receiver),
|
||||||
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_message_target(&mut self, target_id: ComponentId, message_sender: S) {
|
pub fn add_message_target(&mut self, target_id: ComponentId, message_sender: Sender) {
|
||||||
self.message_sender_map
|
self.message_sender_store
|
||||||
.add_message_target(target_id, message_sender)
|
.add_message_target(target_id, message_sender)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,9 +366,9 @@ pub mod alloc_mod {
|
|||||||
&self,
|
&self,
|
||||||
request_id: RequestId,
|
request_id: RequestId,
|
||||||
target_id: ComponentId,
|
target_id: ComponentId,
|
||||||
message: TO,
|
message: To,
|
||||||
) -> Result<(), GenericTargetedMessagingError> {
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
self.message_sender_map.send_message(
|
self.message_sender_store.send_message(
|
||||||
MessageMetadata::new(request_id, self.local_channel_id_generic()),
|
MessageMetadata::new(request_id, self.local_channel_id_generic()),
|
||||||
target_id,
|
target_id,
|
||||||
message,
|
message,
|
||||||
@ -274,48 +378,64 @@ pub mod alloc_mod {
|
|||||||
/// Try to receive a message, which can be a reply or a request, depending on the generics.
|
/// Try to receive a message, which can be a reply or a request, depending on the generics.
|
||||||
pub fn try_recv_message(
|
pub fn try_recv_message(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Option<GenericMessage<FROM>>, GenericTargetedMessagingError> {
|
) -> Result<Option<GenericMessage<From>>, GenericTargetedMessagingError> {
|
||||||
self.message_receiver.try_recv_message()
|
self.message_receiver.try_recv_message()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RequestAndReplySenderAndReceiver<
|
pub struct RequestAndReplySenderAndReceiver<
|
||||||
REQUEST,
|
Request,
|
||||||
REPLY,
|
ReqSender: MessageSenderProvider<Request>,
|
||||||
S0: MessageSender<REQUEST>,
|
ReqReceiver: MessageReceiverProvider<Request>,
|
||||||
R0: MessageReceiver<REPLY>,
|
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||||
S1: MessageSender<REPLY>,
|
Reply,
|
||||||
R1: MessageReceiver<REQUEST>,
|
ReplySender: MessageSenderProvider<Reply>,
|
||||||
|
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||||
|
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||||
> {
|
> {
|
||||||
pub local_channel_id: ComponentId,
|
pub local_channel_id: ComponentId,
|
||||||
// These 2 are a functional group.
|
// These 2 are a functional group.
|
||||||
pub request_sender_map: MessageSenderMap<REQUEST, S0>,
|
pub request_sender_store: ReqSenderStore,
|
||||||
pub reply_receiver: MessageWithSenderIdReceiver<REPLY, R0>,
|
pub reply_receiver: MessageWithSenderIdReceiver<Reply, ReplyReceiver>,
|
||||||
// These 2 are a functional group.
|
// These 2 are a functional group.
|
||||||
pub request_receiver: MessageWithSenderIdReceiver<REQUEST, R1>,
|
pub request_receiver: MessageWithSenderIdReceiver<Request, ReqReceiver>,
|
||||||
pub reply_sender_map: MessageSenderMap<REPLY, S1>,
|
pub reply_sender_store: ReplySenderStore,
|
||||||
|
phantom: PhantomData<(ReqSender, ReplySender)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
REQUEST,
|
Request,
|
||||||
REPLY,
|
ReqSender: MessageSenderProvider<Request>,
|
||||||
S0: MessageSender<REQUEST>,
|
ReqReceiver: MessageReceiverProvider<Request>,
|
||||||
R0: MessageReceiver<REPLY>,
|
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||||
S1: MessageSender<REPLY>,
|
Reply,
|
||||||
R1: MessageReceiver<REQUEST>,
|
ReplySender: MessageSenderProvider<Reply>,
|
||||||
> RequestAndReplySenderAndReceiver<REQUEST, REPLY, S0, R0, S1, R1>
|
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||||
|
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||||
|
>
|
||||||
|
RequestAndReplySenderAndReceiver<
|
||||||
|
Request,
|
||||||
|
ReqSender,
|
||||||
|
ReqReceiver,
|
||||||
|
ReqSenderStore,
|
||||||
|
Reply,
|
||||||
|
ReplySender,
|
||||||
|
ReplyReceiver,
|
||||||
|
ReplySenderStore,
|
||||||
|
>
|
||||||
{
|
{
|
||||||
pub fn new(
|
pub fn new(
|
||||||
local_channel_id: ComponentId,
|
local_channel_id: ComponentId,
|
||||||
request_receiver: R1,
|
request_receiver: ReqReceiver,
|
||||||
reply_receiver: R0,
|
reply_receiver: ReplyReceiver,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
local_channel_id,
|
local_channel_id,
|
||||||
request_receiver: request_receiver.into(),
|
request_receiver: request_receiver.into(),
|
||||||
reply_receiver: reply_receiver.into(),
|
reply_receiver: reply_receiver.into(),
|
||||||
request_sender_map: Default::default(),
|
request_sender_store: Default::default(),
|
||||||
reply_sender_map: Default::default(),
|
reply_sender_store: Default::default(),
|
||||||
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,14 +453,14 @@ pub mod std_mod {
|
|||||||
|
|
||||||
use crate::queue::{GenericReceiveError, GenericSendError};
|
use crate::queue::{GenericReceiveError, GenericSendError};
|
||||||
|
|
||||||
impl<MSG: Send> MessageSender<MSG> for mpsc::Sender<GenericMessage<MSG>> {
|
impl<MSG: Send> MessageSenderProvider<MSG> for mpsc::Sender<GenericMessage<MSG>> {
|
||||||
fn send(&self, message: GenericMessage<MSG>) -> Result<(), GenericTargetedMessagingError> {
|
fn send(&self, message: GenericMessage<MSG>) -> Result<(), GenericTargetedMessagingError> {
|
||||||
self.send(message)
|
self.send(message)
|
||||||
.map_err(|_| GenericSendError::RxDisconnected)?;
|
.map_err(|_| GenericSendError::RxDisconnected)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<MSG: Send> MessageSender<MSG> for mpsc::SyncSender<GenericMessage<MSG>> {
|
impl<MSG: Send> MessageSenderProvider<MSG> for mpsc::SyncSender<GenericMessage<MSG>> {
|
||||||
fn send(&self, message: GenericMessage<MSG>) -> Result<(), GenericTargetedMessagingError> {
|
fn send(&self, message: GenericMessage<MSG>) -> Result<(), GenericTargetedMessagingError> {
|
||||||
if let Err(e) = self.try_send(message) {
|
if let Err(e) = self.try_send(message) {
|
||||||
return match e {
|
return match e {
|
||||||
@ -357,7 +477,7 @@ pub mod std_mod {
|
|||||||
pub type MessageSenderMapMpsc<MSG> = MessageReceiverWithId<MSG, mpsc::Sender<MSG>>;
|
pub type MessageSenderMapMpsc<MSG> = MessageReceiverWithId<MSG, mpsc::Sender<MSG>>;
|
||||||
pub type MessageSenderMapBoundedMpsc<MSG> = MessageReceiverWithId<MSG, mpsc::SyncSender<MSG>>;
|
pub type MessageSenderMapBoundedMpsc<MSG> = MessageReceiverWithId<MSG, mpsc::SyncSender<MSG>>;
|
||||||
|
|
||||||
impl<MSG> MessageReceiver<MSG> for mpsc::Receiver<GenericMessage<MSG>> {
|
impl<MSG> MessageReceiverProvider<MSG> for mpsc::Receiver<GenericMessage<MSG>> {
|
||||||
fn try_recv(&self) -> Result<Option<GenericMessage<MSG>>, GenericTargetedMessagingError> {
|
fn try_recv(&self) -> Result<Option<GenericMessage<MSG>>, GenericTargetedMessagingError> {
|
||||||
match self.try_recv() {
|
match self.try_recv() {
|
||||||
Ok(msg) => Ok(Some(msg)),
|
Ok(msg) => Ok(Some(msg)),
|
||||||
@ -386,7 +506,7 @@ mod tests {
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
queue::{GenericReceiveError, GenericSendError, GenericTargetedMessagingError},
|
queue::{GenericReceiveError, GenericSendError, GenericTargetedMessagingError},
|
||||||
request::{MessageMetadata, MessageSenderMap},
|
request::{MessageMetadata, MessageSenderMap, MessageSenderStoreProvider},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{GenericMessage, MessageReceiverWithId, UniqueApidTargetId};
|
use super::{GenericMessage, MessageReceiverWithId, UniqueApidTargetId};
|
||||||
|
160
satrs/src/subsystem.rs
Normal file
160
satrs/src/subsystem.rs
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
use crate::{
|
||||||
|
mode::{Mode, ModeAndSubmode, ModeRequest, ModeRequestSender},
|
||||||
|
mode_tree::{SequenceModeTables, SequenceTableMapTable, SequenceTablesMapValue},
|
||||||
|
queue::GenericTargetedMessagingError,
|
||||||
|
request::RequestId,
|
||||||
|
ComponentId,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
|
pub enum SequenceExecutionHelperStates {
|
||||||
|
Idle,
|
||||||
|
AwaitingCheckSuccess,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait CheckSuccessProvider {
|
||||||
|
fn mode_request_requires_success_check(
|
||||||
|
&mut self,
|
||||||
|
target_id: ComponentId,
|
||||||
|
target_mode: ModeAndSubmode,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum SequenceHandlerResult {
|
||||||
|
SequenceDone,
|
||||||
|
SequenceStepDone,
|
||||||
|
AwaitingSuccessCheck,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
#[error("Mode {0} does not exist")]
|
||||||
|
pub struct ModeDoesNotExistError(Mode);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SequenceExecutionHelper {
|
||||||
|
target_mode: Mode,
|
||||||
|
state: SequenceExecutionHelperStates,
|
||||||
|
request_id: RequestId,
|
||||||
|
current_sequence_index: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SequenceExecutionHelper {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
target_mode: 0,
|
||||||
|
state: SequenceExecutionHelperStates::Idle,
|
||||||
|
request_id: 0,
|
||||||
|
current_sequence_index: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SequenceExecutionHelper {
|
||||||
|
pub fn load(
|
||||||
|
&mut self,
|
||||||
|
mode: Mode,
|
||||||
|
request_id: RequestId,
|
||||||
|
sequence_tables: &SequenceModeTables,
|
||||||
|
) -> Result<(), ModeDoesNotExistError> {
|
||||||
|
if !sequence_tables.0.contains_key(&mode) {
|
||||||
|
return Err(ModeDoesNotExistError(mode));
|
||||||
|
}
|
||||||
|
self.target_mode = mode;
|
||||||
|
self.request_id = request_id;
|
||||||
|
self.current_sequence_index = None;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn confirm_sequence_done(&mut self) {
|
||||||
|
if let SequenceExecutionHelperStates::AwaitingCheckSuccess = self.state {
|
||||||
|
self.state = SequenceExecutionHelperStates::Idle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(
|
||||||
|
&mut self,
|
||||||
|
table: &SequenceModeTables,
|
||||||
|
sender: &impl ModeRequestSender,
|
||||||
|
) -> 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();
|
||||||
|
self.execute_sequence_and_map_to_result(seq_table_value, idx, sender)
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
self.execute_sequence_and_map_to_result(seq_table_value, 0, sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execute_sequence_and_map_to_result(
|
||||||
|
&mut self,
|
||||||
|
seq_table_value: &SequenceTablesMapValue,
|
||||||
|
sequence_idx: usize,
|
||||||
|
sender: &impl ModeRequestSender,
|
||||||
|
) -> Result<SequenceHandlerResult, GenericTargetedMessagingError> {
|
||||||
|
if Self::execute_sequence(
|
||||||
|
self.request_id,
|
||||||
|
&seq_table_value.entries[sequence_idx],
|
||||||
|
sender,
|
||||||
|
)? {
|
||||||
|
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,
|
||||||
|
) -> 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,
|
||||||
|
ModeRequest::SetMode(entry.common.mode_submode),
|
||||||
|
)?;
|
||||||
|
if entry.check_success {
|
||||||
|
some_succes_check_required = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(some_succes_check_required)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {}
|
@ -17,37 +17,37 @@ impl PusTmWithCdsShortHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub fn create_pus_tm_timestamp_now<'a>(
|
pub fn create_pus_tm_timestamp_now<'time, 'src_data>(
|
||||||
&'a mut self,
|
&'time mut self,
|
||||||
service: u8,
|
service: u8,
|
||||||
subservice: u8,
|
subservice: u8,
|
||||||
source_data: &'a [u8],
|
source_data: &'src_data [u8],
|
||||||
seq_count: u16,
|
seq_count: u16,
|
||||||
) -> PusTmCreator {
|
) -> PusTmCreator<'time, 'src_data> {
|
||||||
let time_stamp = CdsTime::now_with_u16_days().unwrap();
|
let time_stamp = CdsTime::now_with_u16_days().unwrap();
|
||||||
time_stamp.write_to_bytes(&mut self.cds_short_buf).unwrap();
|
time_stamp.write_to_bytes(&mut self.cds_short_buf).unwrap();
|
||||||
self.create_pus_tm_common(service, subservice, source_data, seq_count)
|
self.create_pus_tm_common(service, subservice, source_data, seq_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_pus_tm_with_stamper<'a>(
|
pub fn create_pus_tm_with_stamper<'time, 'src_data>(
|
||||||
&'a mut self,
|
&'time mut self,
|
||||||
service: u8,
|
service: u8,
|
||||||
subservice: u8,
|
subservice: u8,
|
||||||
source_data: &'a [u8],
|
source_data: &'src_data [u8],
|
||||||
stamper: &CdsTime,
|
stamper: &CdsTime,
|
||||||
seq_count: u16,
|
seq_count: u16,
|
||||||
) -> PusTmCreator {
|
) -> PusTmCreator<'time, 'src_data> {
|
||||||
stamper.write_to_bytes(&mut self.cds_short_buf).unwrap();
|
stamper.write_to_bytes(&mut self.cds_short_buf).unwrap();
|
||||||
self.create_pus_tm_common(service, subservice, source_data, seq_count)
|
self.create_pus_tm_common(service, subservice, source_data, seq_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_pus_tm_common<'a>(
|
fn create_pus_tm_common<'time, 'src_data>(
|
||||||
&'a self,
|
&'time self,
|
||||||
service: u8,
|
service: u8,
|
||||||
subservice: u8,
|
subservice: u8,
|
||||||
source_data: &'a [u8],
|
source_data: &'src_data [u8],
|
||||||
seq_count: u16,
|
seq_count: u16,
|
||||||
) -> PusTmCreator {
|
) -> PusTmCreator<'time, 'src_data> {
|
||||||
let reply_header = SpHeader::new_for_unseg_tm(self.apid, seq_count, 0);
|
let reply_header = SpHeader::new_for_unseg_tm(self.apid, seq_count, 0);
|
||||||
let tc_header = PusTmSecondaryHeader::new_simple(service, subservice, &self.cds_short_buf);
|
let tc_header = PusTmSecondaryHeader::new_simple(service, subservice, &self.cds_short_buf);
|
||||||
PusTmCreator::new(reply_header, tc_header, source_data, true)
|
PusTmCreator::new(reply_header, tc_header, source_data, true)
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user