Add Small Event Support #18
@ -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();
|
||||
|
@ -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() {
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user