started event abstraction
This commit is contained in:
+111
-2
@@ -1,3 +1,112 @@
|
||||
pub struct Event {
|
||||
pub event_id: u32,
|
||||
use num::pow;
|
||||
|
||||
#[derive (Copy, Clone, PartialEq, Debug)]
|
||||
pub enum Severity {
|
||||
INFO = 1,
|
||||
LOW = 2,
|
||||
MEDIUM = 3,
|
||||
HIGH = 4
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for Severity {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
x if x == Severity::INFO as u8 => Ok(Severity::INFO),
|
||||
x if x == Severity::LOW as u8 => Ok(Severity::LOW),
|
||||
x if x == Severity::MEDIUM as u8 => Ok(Severity::MEDIUM),
|
||||
x if x == Severity::HIGH as u8 => Ok(Severity::HIGH),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive (Copy, Clone, Debug)]
|
||||
pub struct Event {
|
||||
severity: Severity,
|
||||
group_id: u16,
|
||||
unique_id: u16,
|
||||
}
|
||||
|
||||
impl Event {
|
||||
|
||||
/// 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: u16, unique_id: u16) -> Option<Event> {
|
||||
if group_id > (pow::pow(2u8 as u16, 13) - 1) {
|
||||
return None
|
||||
}
|
||||
Some(Event {
|
||||
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) -> u16 {
|
||||
self.group_id
|
||||
}
|
||||
|
||||
pub fn unique_id(&self) -> u16 {
|
||||
self.unique_id
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> u32 {
|
||||
(((self.severity as u32) << 29) as u32 | ((self.group_id as u32) << 16) as u32 | self.unique_id as u32) as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for Event {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(raw: u32) -> Result<Self, Self::Error> {
|
||||
let severity: Option<Severity> = (((raw >> 29) & 0b111) as u8).try_into().ok();
|
||||
if severity.is_none() {
|
||||
return Err(())
|
||||
}
|
||||
let group_id = ((raw >> 16) & 0x1FFF) as u16;
|
||||
let unique_id = (raw & 0xFFFF) as u16;
|
||||
Event::new(severity.unwrap(), group_id, unique_id).ok_or(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::core::events::Severity;
|
||||
use super::Event;
|
||||
|
||||
#[test]
|
||||
fn test_events() {
|
||||
let event = Event::new(Severity::INFO, 0, 0).unwrap();
|
||||
assert_eq!(event.severity(), Severity::INFO);
|
||||
assert_eq!(event.unique_id(), 0);
|
||||
assert_eq!(event.group_id(), 0);
|
||||
|
||||
let raw_event = event.raw();
|
||||
assert_eq!(raw_event, 0x20000000);
|
||||
let conv_from_raw = Event::try_from(raw_event);
|
||||
assert!(conv_from_raw.is_ok());
|
||||
let opt_event = conv_from_raw.ok();
|
||||
assert!(opt_event.is_some());
|
||||
let event_conv_back = opt_event.unwrap();
|
||||
assert_eq!(event_conv_back.severity(), Severity::INFO);
|
||||
assert_eq!(event_conv_back.unique_id(), 0);
|
||||
assert_eq!(event_conv_back.group_id(), 0);
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ pub fn exec_sched_single<
|
||||
///
|
||||
/// * `executable_vec`: Vector of executable objects
|
||||
/// * `task_freq`: Optional frequency of task. Required for periodic and fixed cycle tasks
|
||||
/// * `op_code`: Operation code which is passed to the executable task periodic_op call
|
||||
/// * `op_code`: Operation code which is passed to the executable task [operation call][Executable::periodic_op]
|
||||
/// * `termination`: Optional termination handler which can cancel threads with a broadcast
|
||||
pub fn exec_sched_multi<
|
||||
T: Executable<Error = E> + Send + 'static + ?Sized,
|
||||
|
||||
+19
-1
@@ -8,6 +8,8 @@ pub struct ObjectId {
|
||||
name: &'static str,
|
||||
}
|
||||
|
||||
/// Each object which is stored inside the [object manager][ObjectManager] needs to implemented
|
||||
/// this trait
|
||||
pub trait SystemObject {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn get_object_id(&self) -> &ObjectId;
|
||||
@@ -16,7 +18,21 @@ pub trait SystemObject {
|
||||
|
||||
pub trait ManagedSystemObject: SystemObject + Any {}
|
||||
|
||||
/// Helper module to manage multiple SystemObject by mapping them using an ObjectId
|
||||
/// Helper module to manage multiple [ManagedSystemObjects][ManagedSystemObject] by mapping them
|
||||
/// using an [object ID][ObjectId]
|
||||
///
|
||||
/// # Example
|
||||
/// ```rs
|
||||
/// let mut obj_manager = ObjectManager::default();
|
||||
/// let expl_obj_id = ObjectId {
|
||||
/// id: 0,
|
||||
/// name: "Example 0",
|
||||
/// };
|
||||
/// let example_obj = ExampleSysObj::new(expl_obj_id, 42);
|
||||
/// obj_manager.insert(Box::new(example_obj))
|
||||
/// let obj_back_casted: Option<&ExampleSysObj> = obj_manager.get(&expl_obj_id);
|
||||
/// let expl_obj_back_casted = obj_back_casted.unwrap();
|
||||
/// ```
|
||||
pub struct ObjectManager {
|
||||
obj_map: HashMap<ObjectId, Box<dyn ManagedSystemObject>>,
|
||||
}
|
||||
@@ -53,6 +69,8 @@ impl ObjectManager {
|
||||
Ok(init_success)
|
||||
}
|
||||
|
||||
/// Retrieve an object stored inside the manager. The type to retrieve needs to be explicitly
|
||||
/// passed as a generic parameter
|
||||
pub fn get<T: Any>(&self, key: &ObjectId) -> Option<&T> {
|
||||
self.obj_map
|
||||
.get(key)
|
||||
|
||||
Reference in New Issue
Block a user