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

View File

@ -3,9 +3,14 @@
use spacepackets::ecss::EcssEnumeration;
use spacepackets::{ByteConversionError, SizeMissmatch};
pub type EventRaw = u32;
pub type SmallEventRaw = u16;
pub type GroupId = u16;
pub type UniqueId = u16;
pub type EventRaw = u32;
pub type GroupIdSmall = u8;
pub type UniqueIdSmall = u8;
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum Severity {
@ -15,6 +20,20 @@ pub enum Severity {
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 {
type Error = ();
@ -32,8 +51,42 @@ impl TryFrom<u8> for Severity {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Event {
severity: Severity,
group_id: GroupId,
unique_id: UniqueId,
group_id: u16,
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 {
@ -43,12 +96,16 @@ impl Event {
/// # 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
/// 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 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
/// 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) {
return None;
}
@ -58,29 +115,9 @@ impl Event {
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 {
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 {
impl TryFrom<u32> for Event {
type 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 {
fn pfc(&self) -> u8 {
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)]
mod tests {
use super::Event;
use crate::events::Severity;
use crate::events::{EventProvider, Severity};
#[test]
fn test_events() {

View File

@ -50,7 +50,7 @@ impl PusEventMgmtBackendProvider for DefaultPusMgmtBackendProvider {
#[cfg(feature = "heapless")]
pub mod heapless_mod {
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
// regular Event type again.