trying to make this generic

This commit is contained in:
Robin Müller 2022-10-23 15:58:54 +02:00
parent b26703e0a9
commit 2004155b7b
No known key found for this signature in database
GPG Key ID: FC76078F520434A5
3 changed files with 187 additions and 110 deletions

View File

@ -1,5 +1,5 @@
//! [Event][crate::events::Event] management and forwarding //! [Event][crate::events::Event] management and forwarding
use crate::events::{Event, EventRaw, GroupId}; use crate::events::{Event, EventProvider, EventSmall};
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::vec; use alloc::vec;
use alloc::vec::Vec; use alloc::vec::Vec;
@ -7,63 +7,85 @@ use hashbrown::HashMap;
#[derive(PartialEq, Eq, Hash, Copy, Clone)] #[derive(PartialEq, Eq, Hash, Copy, Clone)]
enum ListenerType { enum ListenerType {
Single(EventRaw), Single(u32),
Group(GroupId), Group(u16),
} }
pub trait EventListener { pub trait EventListener<Provider: EventProvider = Event> {
type Error; type Error;
fn id(&self) -> u32; fn id(&self) -> u32;
fn send_to(&mut self, event: Event) -> Result<(), Self::Error>; fn send_to(&mut self, event: Provider) -> Result<(), Self::Error>;
} }
struct Listener<E> { struct Listener<E, Provider: EventProvider = Event> {
ltype: ListenerType, ltype: ListenerType,
dest: Box<dyn EventListener<Error = E>>, dest: Box<dyn EventListener<Provider, Error = E>>,
} }
pub trait ReceivesAllEvent { pub trait ReceivesAllEvent<Provider: EventProvider = Event> {
fn receive(&mut self) -> Option<Event>; fn receive(&mut self) -> Option<Provider>;
} }
pub struct EventManager<E> { pub struct EventManager<E, Provider: EventProvider = Event> {
listeners: HashMap<ListenerType, Vec<Listener<E>>>, listeners: HashMap<ListenerType, Vec<Listener<E, Provider>>>,
event_receiver: Box<dyn ReceivesAllEvent>, event_receiver: Box<dyn ReceivesAllEvent<Provider>>,
} }
pub enum HandlerResult { pub enum HandlerResult<Provider: EventProvider = Event> {
Empty, Empty,
Handled(u32, Event), Handled(u32, Provider),
} }
impl<E> EventManager<E> { impl<E> EventManager<E, Event> {
pub fn new(event_receiver: Box<dyn ReceivesAllEvent>) -> Self { pub fn new(event_receiver: Box<dyn ReceivesAllEvent<Event>>) -> Self {
EventManager { EventManager {
listeners: HashMap::new(), listeners: HashMap::new(),
event_receiver, event_receiver,
} }
} }
}
impl<E> EventManager<E, Event> {
pub fn subscribe_single( pub fn subscribe_single(
&mut self, &mut self,
event: Event, event: Event,
dest: impl EventListener<Error = E> + 'static, dest: impl EventListener<Event, Error = E> + 'static,
) { ) {
self.update_listeners(ListenerType::Single(event.raw()), dest); self.update_listeners(ListenerType::Single(event.raw_as_u32()), dest);
} }
pub fn subscribe_group( pub fn subscribe_group(
&mut self, &mut self,
group_id: GroupId, group_id: <Event as EventProvider>::GroupId,
dest: impl EventListener<Error = E> + 'static, dest: impl EventListener<Event, Error = E> + 'static,
) { ) {
self.update_listeners(ListenerType::Group(group_id), dest); self.update_listeners(ListenerType::Group(group_id), dest);
} }
}
impl<E> EventManager<E, EventSmall> {
pub fn subscribe_single(
&mut self,
event: EventSmall,
dest: impl EventListener<Event, Error = E> + 'static,
) {
self.update_listeners(ListenerType::Single(event.raw_as_u32()), dest);
}
pub fn subscribe_group(
&mut self,
group_id: <EventSmall as EventProvider>::GroupId,
dest: impl EventListener<EventSmall, Error = E> + 'static,
) {
self.update_listeners(ListenerType::Group(group_id.into()), dest);
}
}
impl<E, Provider: EventProvider> EventManager<E, Provider> {
fn update_listeners( fn update_listeners(
&mut self, &mut self,
key: ListenerType, key: ListenerType,
dest: impl EventListener<Error = E> + 'static, dest: impl EventListener<Provider, Error = E> + 'static,
) { ) {
if !self.listeners.contains_key(&key) { if !self.listeners.contains_key(&key) {
self.listeners.insert( self.listeners.insert(
@ -88,10 +110,10 @@ impl<E> EventManager<E> {
} }
} }
pub fn try_event_handling(&mut self) -> Result<HandlerResult, E> { pub fn try_event_handling(&mut self) -> Result<HandlerResult<Provider>, E> {
let mut err_status = None; let mut err_status = None;
let mut num_recipients = 0; let mut num_recipients = 0;
let mut send_handler = |event, llist: &mut Vec<Listener<E>>| { let mut send_handler = |event: Provider, llist: &mut Vec<Listener<E, Provider>>| {
for listener in llist.iter_mut() { for listener in llist.iter_mut() {
if let Err(e) = listener.dest.send_to(event) { if let Err(e) = listener.dest.send_to(event) {
err_status = Some(Err(e)); err_status = Some(Err(e));
@ -101,11 +123,11 @@ impl<E> EventManager<E> {
} }
}; };
if let Some(event) = self.event_receiver.receive() { if let Some(event) = self.event_receiver.receive() {
let single_key = ListenerType::Single(event.raw()); let single_key = ListenerType::Single(event.raw_as_u32());
if self.listeners.contains_key(&single_key) { if self.listeners.contains_key(&single_key) {
send_handler(event, self.listeners.get_mut(&single_key).unwrap()); send_handler(event, self.listeners.get_mut(&single_key).unwrap());
} }
let group_key = ListenerType::Group(event.group_id()); let group_key = ListenerType::Group(event.group_id_as_u16());
if self.listeners.contains_key(&group_key) { if self.listeners.contains_key(&group_key) {
send_handler(event, self.listeners.get_mut(&group_key).unwrap()); send_handler(event, self.listeners.get_mut(&group_key).unwrap());
} }
@ -122,7 +144,7 @@ impl<E> EventManager<E> {
mod tests { mod tests {
use super::{EventListener, HandlerResult, ReceivesAllEvent}; use super::{EventListener, HandlerResult, ReceivesAllEvent};
use crate::event_man::EventManager; use crate::event_man::EventManager;
use crate::events::{Event, Severity}; use crate::events::{Event, EventProvider, Severity};
use alloc::boxed::Box; use alloc::boxed::Box;
use std::sync::mpsc::{channel, Receiver, SendError, Sender}; use std::sync::mpsc::{channel, Receiver, SendError, Sender};
use std::thread; use std::thread;
@ -131,7 +153,7 @@ mod tests {
struct EventReceiver { struct EventReceiver {
mpsc_receiver: Receiver<Event>, mpsc_receiver: Receiver<Event>,
} }
impl ReceivesAllEvent for EventReceiver { impl ReceivesAllEvent<Event> for EventReceiver {
fn receive(&mut self) -> Option<Event> { fn receive(&mut self) -> Option<Event> {
self.mpsc_receiver.try_recv().ok() self.mpsc_receiver.try_recv().ok()
} }
@ -143,7 +165,7 @@ mod tests {
mpsc_sender: Sender<Event>, mpsc_sender: Sender<Event>,
} }
impl EventListener for MpscEventSenderQueue { impl EventListener<Event> for MpscEventSenderQueue {
type Error = SendError<Event>; type Error = SendError<Event>;
fn id(&self) -> u32 { fn id(&self) -> u32 {
@ -178,7 +200,7 @@ mod tests {
let event_man_receiver = EventReceiver { let event_man_receiver = EventReceiver {
mpsc_receiver: manager_queue, mpsc_receiver: manager_queue,
}; };
let mut event_man: EventManager<SendError<Event>> = let mut event_man: EventManager<SendError<Event>, Event> =
EventManager::new(Box::new(event_man_receiver)); EventManager::new(Box::new(event_man_receiver));
let event_grp_0 = Event::new(Severity::INFO, 0, 0).unwrap(); let event_grp_0 = Event::new(Severity::INFO, 0, 0).unwrap();
let event_grp_1_0 = Event::new(Severity::HIGH, 1, 0).unwrap(); let event_grp_1_0 = Event::new(Severity::HIGH, 1, 0).unwrap();
@ -221,7 +243,7 @@ mod tests {
let event_man_receiver = EventReceiver { let event_man_receiver = EventReceiver {
mpsc_receiver: manager_queue, mpsc_receiver: manager_queue,
}; };
let mut event_man: EventManager<SendError<Event>> = let mut event_man: EventManager<SendError<Event>, Event> =
EventManager::new(Box::new(event_man_receiver)); EventManager::new(Box::new(event_man_receiver));
let res = event_man.try_event_handling(); let res = event_man.try_event_handling();
assert!(res.is_ok()); assert!(res.is_ok());
@ -263,7 +285,7 @@ mod tests {
let event_man_receiver = EventReceiver { let event_man_receiver = EventReceiver {
mpsc_receiver: manager_queue, mpsc_receiver: manager_queue,
}; };
let mut event_man: EventManager<SendError<Event>> = let mut event_man: EventManager<SendError<Event>, Event> =
EventManager::new(Box::new(event_man_receiver)); EventManager::new(Box::new(event_man_receiver));
let event_0 = Event::new(Severity::INFO, 0, 5).unwrap(); let event_0 = Event::new(Severity::INFO, 0, 5).unwrap();
let event_1 = Event::new(Severity::HIGH, 1, 0).unwrap(); let event_1 = Event::new(Severity::HIGH, 1, 0).unwrap();

View File

@ -3,9 +3,14 @@
use spacepackets::ecss::EcssEnumeration; use spacepackets::ecss::EcssEnumeration;
use spacepackets::{ByteConversionError, SizeMissmatch}; use spacepackets::{ByteConversionError, SizeMissmatch};
pub type EventRaw = u32;
pub type SmallEventRaw = u16;
pub type GroupId = u16; pub type GroupId = u16;
pub type UniqueId = u16; pub type UniqueId = u16;
pub type EventRaw = u32;
pub type GroupIdSmall = u8;
pub type UniqueIdSmall = u8;
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum Severity { pub enum Severity {
@ -15,6 +20,20 @@ pub enum Severity {
HIGH = 3, HIGH = 3,
} }
pub trait EventProvider: PartialEq + Eq + Copy + Clone {
type Raw;
type GroupId;
type UniqueId;
fn raw(&self) -> Self::Raw;
fn severity(&self) -> Severity;
fn group_id(&self) -> Self::GroupId;
fn unique_id(&self) -> Self::UniqueId;
fn raw_as_u32(&self) -> u32;
fn group_id_as_u16(&self) -> u16;
}
impl TryFrom<u8> for Severity { impl TryFrom<u8> for Severity {
type Error = (); type Error = ();
@ -32,8 +51,42 @@ impl TryFrom<u8> for Severity {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Event { pub struct Event {
severity: Severity, severity: Severity,
group_id: GroupId, group_id: u16,
unique_id: UniqueId, unique_id: u16,
}
impl EventProvider for Event {
type Raw = u32;
type GroupId = u16;
type UniqueId = u16;
fn raw(&self) -> Self::Raw {
(((self.severity as Self::Raw) << 30) as Self::Raw
| ((self.group_id as Self::Raw) << 16) as Self::Raw
| self.unique_id as u32) as Self::Raw
}
/// Retrieve the severity of an event. Returns None if that severity bit field of the raw event
/// ID is invalid
fn severity(&self) -> Severity {
self.severity
}
fn group_id(&self) -> Self::GroupId {
self.group_id
}
fn unique_id(&self) -> Self::UniqueId {
self.unique_id
}
fn raw_as_u32(&self) -> u32 {
self.raw()
}
fn group_id_as_u16(&self) -> u16 {
self.group_id()
}
} }
impl Event { impl Event {
@ -43,12 +96,16 @@ impl Event {
/// # Parameter /// # Parameter
/// ///
/// * `severity`: Each event has a [severity][Severity]. The raw value of the severity will /// * `severity`: Each event has a [severity][Severity]. The raw value of the severity will
/// be stored inside the uppermost 3 bits of the raw event ID /// be stored inside the uppermost 2 bits of the raw event ID
/// * `group_id`: Related events can be grouped using a group ID. The group ID will occupy the /// * `group_id`: Related events can be grouped using a group ID. The group ID will occupy the
/// next 13 bits after the severity. Therefore, the size is limited by dec 8191 hex 0x1FFF. /// next 14 bits after the severity. Therefore, the size is limited by dec 16383 hex 0x3FFF.
/// * `unique_id`: Each event has a unique 16 bit ID occupying the last 16 bits of the /// * `unique_id`: Each event has a unique 16 bit ID occupying the last 16 bits of the
/// raw event ID /// raw event ID
pub fn new(severity: Severity, group_id: GroupId, unique_id: UniqueId) -> Option<Self> { pub fn new(
severity: Severity,
group_id: <Self as EventProvider>::GroupId,
unique_id: <Self as EventProvider>::UniqueId,
) -> Option<Self> {
if group_id > (2u16.pow(14) - 1) { if group_id > (2u16.pow(14) - 1) {
return None; return None;
} }
@ -58,29 +115,9 @@ impl Event {
unique_id, unique_id,
}) })
} }
/// Retrieve the severity of an event. Returns None if that severity bit field of the raw event
/// ID is invalid
pub fn severity(&self) -> Severity {
self.severity
} }
pub fn group_id(&self) -> GroupId { impl TryFrom<u32> for Event {
self.group_id
}
pub fn unique_id(&self) -> UniqueId {
self.unique_id
}
pub fn raw(&self) -> EventRaw {
(((self.severity as u32) << 30) as u32
| ((self.group_id as u32) << 16) as u32
| self.unique_id as u32) as EventRaw
}
}
impl TryFrom<EventRaw> for Event {
type Error = (); type Error = ();
fn try_from(raw: u32) -> Result<Self, Self::Error> { fn try_from(raw: u32) -> Result<Self, Self::Error> {
@ -94,56 +131,6 @@ impl TryFrom<EventRaw> for Event {
} }
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct EventSmall {
severity: Severity,
group_id: u8,
unique_id: u8,
}
impl EventSmall {
/// Generate an event. The raw representation of an event has 32 bits.
/// If the passed group ID is invalid (too large), None wil be returned
///
/// # Parameter
///
/// * `severity`: Each event has a [severity][Severity]. The raw value of the severity will
/// be stored inside the uppermost 3 bits of the raw event ID
/// * `group_id`: Related events can be grouped using a group ID. The group ID will occupy the
/// next 13 bits after the severity. Therefore, the size is limited by dec 8191 hex 0x1FFF.
/// * `unique_id`: Each event has a unique 16 bit ID occupying the last 16 bits of the
/// raw event ID
pub fn new(severity: Severity, group_id: u8, unique_id: u8) -> Option<Self> {
if group_id > (2u8.pow(5) - 1) {
return None;
}
Some(Self {
severity,
group_id,
unique_id,
})
}
/// Retrieve the severity of an event. Returns None if that severity bit field of the raw event
/// ID is invalid
pub fn severity(&self) -> Severity {
self.severity
}
pub fn group_id(&self) -> u8 {
self.group_id
}
pub fn unique_id(&self) -> u8 {
self.unique_id
}
pub fn raw(&self) -> u16 {
(((self.severity as u16) << 12) as u16
| ((self.group_id as u16) << 8) as u16
| self.unique_id as u16) as u16
}
}
impl EcssEnumeration for Event { impl EcssEnumeration for Event {
fn pfc(&self) -> u8 { fn pfc(&self) -> u8 {
32 32
@ -161,10 +148,78 @@ impl EcssEnumeration for Event {
} }
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct EventSmall {
severity: Severity,
group_id: u8,
unique_id: u8,
}
impl EventProvider for EventSmall {
type Raw = u16;
type GroupId = u8;
type UniqueId = u8;
fn raw(&self) -> Self::Raw {
(((self.severity as Self::Raw) << 14) as Self::Raw
| ((self.group_id as Self::Raw) << 8) as Self::Raw
| self.unique_id as Self::Raw) as Self::Raw
}
/// Retrieve the severity of an event. Returns None if that severity bit field of the raw event
/// ID is invalid
fn severity(&self) -> Severity {
self.severity
}
fn group_id(&self) -> Self::GroupId {
self.group_id.into()
}
fn unique_id(&self) -> Self::UniqueId {
self.unique_id.into()
}
fn raw_as_u32(&self) -> u32 {
self.raw().into()
}
fn group_id_as_u16(&self) -> u16 {
self.group_id().into()
}
}
impl EventSmall {
/// Generate a small event. The raw representation of a small event has 16 bits.
/// If the passed group ID is invalid (too large), [None] wil be returned
///
/// # Parameter
///
/// * `severity`: Each event has a [severity][Severity]. The raw value of the severity will
/// be stored inside the uppermost 2 bits of the raw event ID
/// * `group_id`: Related events can be grouped using a group ID. The group ID will occupy the
/// next 6 bits after the severity. Therefore, the size is limited by dec 63 hex 0x3F.
/// * `unique_id`: Each event has a unique 8 bit ID occupying the last 8 bits of the
/// raw event ID
pub fn new(
severity: Severity,
group_id: <Self as EventProvider>::GroupId,
unique_id: <Self as EventProvider>::UniqueId,
) -> Option<Self> {
if group_id > (2u8.pow(6) - 1) {
return None;
}
Some(Self {
severity,
group_id,
unique_id,
})
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::Event; use super::Event;
use crate::events::Severity; use crate::events::{EventProvider, Severity};
#[test] #[test]
fn test_events() { fn test_events() {

View File

@ -50,7 +50,7 @@ impl PusEventMgmtBackendProvider for DefaultPusMgmtBackendProvider {
#[cfg(feature = "heapless")] #[cfg(feature = "heapless")]
pub mod heapless_mod { pub mod heapless_mod {
use super::*; use super::*;
use crate::events::EventRaw; use crate::events::{EventProvider, EventRaw};
// TODO: After a new version of heapless is released which uses hash32 version 0.3, try using // TODO: After a new version of heapless is released which uses hash32 version 0.3, try using
// regular Event type again. // regular Event type again.