use crate::private::ringq::{RingQ, Coalesce, QueueError};
use crate::devices::button::ButtonState;
use crate::devices::serialport::SerialState;
use crate::hal::generic::timer::TimerIdentity;
use crate::hal::generic::port::PinIdentity;
use crate::hal::generic::serial::SerialPortIdentity;
pub type OxideEventQueue = RingQ<OxideEvent,16>;
#[derive(Clone,Copy)]
pub enum OxideEvent {
Initialise,
MasterClockEvent(TimerIdentity, u16),
ButtonEvent(PinIdentity, ButtonState),
SerialEvent(SerialPortIdentity, 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(source1, myticks) => {
match with {
OxideEvent::MasterClockEvent(source2, ticks) => {
if (source1 == source2) && (u16::MAX - *myticks) > *ticks {
*myticks += ticks;
Ok(())
} else {
Err(QueueError::CannotCoalesce)
}
},
_ => Err(QueueError::CannotCoalesce)
}
},
OxideEvent::SerialEvent(source1, state) => {
match with {
OxideEvent::SerialEvent(source2, with_state) => {
if (source1 == source2) && (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;
use crate::hal::generic::timer::TimerIdentity;
use crate::hal::generic::serial::SerialPortIdentity;
use crate::hal::generic::port::PinIdentity;
#[test]
fn test_event_coalesce_masterclockevent() {
let mut event1 = OxideEvent::MasterClockEvent(TimerIdentity::Tcb0, 12);
let event2 = OxideEvent::MasterClockEvent(TimerIdentity::Tcb0, 14);
event1.coalesce(&event2);
if let MasterClockEvent(TimerIdentity::Tcb0, ticks) = event1 {
println!("Coalesced MasterClockEvent (ticks == {})", ticks);
assert_eq!(ticks, 26);
}
}
#[test]
fn test_event_coalesce_serialevent_ok() {
let mut event1 = OxideEvent::SerialEvent(SerialPortIdentity::Usart0, SerialState::ReadAvailable);
let event2 = OxideEvent::SerialEvent(SerialPortIdentity::Usart0, SerialState::ReadAvailable);
event1.coalesce(&event2);
let mut event1 = OxideEvent::SerialEvent(SerialPortIdentity::Usart0, SerialState::BreakDetected);
let event2 = OxideEvent::SerialEvent(SerialPortIdentity::Usart0, SerialState::BreakDetected);
event1.coalesce(&event2);
}
#[test]
#[should_panic]
fn test_event_coalesce_serialevent_fail() {
let mut event1 = OxideEvent::SerialEvent(SerialPortIdentity::Usart0, SerialState::ReadAvailable);
let event2 = OxideEvent::SerialEvent(SerialPortIdentity::Usart0, SerialState::BreakDetected);
if let Ok(_) = event1.coalesce(&event2) {
} else {
panic!();
}
}
#[test]
#[should_panic]
fn test_event_coalesce_fail() {
let mut event1 = OxideEvent::MasterClockEvent(TimerIdentity::Tcb0, 42);
let event2 = OxideEvent::ButtonEvent(PinIdentity::PortA(0),ButtonState::Pressed);
if let Ok(_) = event1.coalesce(&event2) {
} else {
panic!();
}
}
}