avr-oxide 0.0.4

An extremely simply Rusty operating system for AVR microcontrollers
/* event.rs
 *
 * Developed by Tim Walls <tim.walls@snowgoons.com>
 * Copyright (c) All Rights Reserved, Tim Walls
 */
//! Oxide system events

// Imports ===================================================================
use crate::ringq::{RingQ, Coalesce, QueueError};
use crate::devices::button::ButtonState;

// Declarations ==============================================================
pub type OxideEventQueue = RingQ<OxideEvent,16>;

/**
 * Events that can cause your application to wake up and need to do something.
 */
#[derive(Clone)]
pub enum OxideEvent {
  /**
   * Sent when the master clock timer tick interrupt occurs.  The number
   * of elapsed clock ticks is included.
   */
  MasterClockEvent(u16),

  /**
   * Sent when a button event occurs.  The state of the button when the
   * event was generated is included.
   */
  ButtonEvent(ButtonState)
}

/**
 * An event sink is something that devices can call to dump their events into.
 */
pub trait EventSink {
  fn event(event: OxideEvent) -> ();
}

// Code ======================================================================
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)
        }
      }
      _ => Err(QueueError::CannotCoalesce)
    }
  }
}


// Tests =====================================================================
#[cfg(test)]
mod tests {
  use crate::event::OxideEvent;
  use crate::ringq::Coalesce;
  use crate::event::OxideEvent::MasterClockEvent;
  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]
  #[should_panic]
  fn test_event_coalesce_fail() {
    let mut event1 = OxideEvent::MasterClockEvent(42);
    let event2 = OxideEvent::ButtonEvent(ButtonState::Pressed);

    event1.coalesce(&event2).unwrap();
  }
}