use crate::private::ringq::{RingQ, Coalesce, QueueError};
use crate::devices::button::ButtonState;
use crate::devices::serialport::SerialState;
pub type OxideEventQueue = RingQ<OxideEvent,16>;
#[derive(Clone)]
pub enum OxideEvent {
MasterClockEvent(u16),
ButtonEvent(ButtonState),
SerialEvent(SerialState)
}
pub trait EventSink {
fn event(event: OxideEvent) -> ();
}
pub struct EventDevNull {
}
impl Coalesce for OxideEvent {
fn coalesce(&mut self, with: &Self) -> Result<(), QueueError> {
match self {
OxideEvent::MasterClockEvent(myticks) => {
match with {
OxideEvent::MasterClockEvent(ticks) => {
if (u16::MAX - *myticks) > *ticks {
*myticks += ticks;
Ok(())
} else {
Err(QueueError::CannotCoalesce)
}
},
_ => Err(QueueError::CannotCoalesce)
}
},
OxideEvent::SerialEvent(state) => {
match with {
OxideEvent::SerialEvent(with_state) => {
if state == with_state {
Ok(())
} else {
Err(QueueError::CannotCoalesce)
}
},
_ => Err(QueueError::CannotCoalesce)
}
},
_ => Err(QueueError::CannotCoalesce)
}
}
}
impl EventSink for EventDevNull {
fn event(_event: OxideEvent) -> () {
}
}
#[cfg(test)]
mod tests {
use crate::event::OxideEvent;
use crate::private::ringq::Coalesce;
use crate::event::OxideEvent::MasterClockEvent;
use crate::devices::serialport::SerialState;
use crate::devices::button::ButtonState;
#[test]
fn test_event_coalesce_masterclockevent() {
let mut event1 = OxideEvent::MasterClockEvent(12);
let event2 = OxideEvent::MasterClockEvent(14);
event1.coalesce(&event2).unwrap();
if let MasterClockEvent(ticks) = event1 {
println!("Coalesced MasterClockEvent (ticks == {})", ticks);
assert_eq!(ticks, 26);
}
}
#[test]
fn test_event_coalesce_serialevent_ok() {
let mut event1 = OxideEvent::SerialEvent(SerialState::ReadAvailable);
let event2 = OxideEvent::SerialEvent(SerialState::ReadAvailable);
event1.coalesce(&event2).unwrap();
let mut event1 = OxideEvent::SerialEvent(SerialState::BreakDetected);
let event2 = OxideEvent::SerialEvent(SerialState::BreakDetected);
event1.coalesce(&event2).unwrap();
}
#[test]
#[should_panic]
fn test_event_coalesce_serialevent_fail() {
let mut event1 = OxideEvent::SerialEvent(SerialState::ReadAvailable);
let event2 = OxideEvent::SerialEvent(SerialState::BreakDetected);
event1.coalesce(&event2).unwrap();
}
#[test]
#[should_panic]
fn test_event_coalesce_fail() {
let mut event1 = OxideEvent::MasterClockEvent(42);
let event2 = OxideEvent::ButtonEvent(ButtonState::Pressed);
event1.coalesce(&event2).unwrap();
}
}