///|
pub(all) struct PreallocatedEventQueue {
  buffer : FixedArray[SimulationEvent]
  capacity : Int
  mut head : Int
  mut tail : Int
  mut count : Int
} derive(Debug)

///|
pub fn PreallocatedEventQueue::new(capacity : Int) -> PreallocatedEventQueue {
  let default_event = SimulationEvent::empty()
  let arr = FixedArray::make(capacity, default_event)
  { buffer: arr, capacity, head: 0, tail: 0, count: 0 }
}

///|
pub fn PreallocatedEventQueue::push(
  self : PreallocatedEventQueue,
  event : SimulationEvent,
) -> Bool {
  if self.count >= self.capacity {
    return false
  }
  self.buffer[self.tail] = event
  self.tail = (self.tail + 1) % self.capacity
  self.count = self.count + 1
  true
}

///|
pub fn PreallocatedEventQueue::pop(
  self : PreallocatedEventQueue,
) -> SimulationEvent? {
  if self.count == 0 {
    return None
  }
  let ev = self.buffer[self.head]
  self.head = (self.head + 1) % self.capacity
  self.count = self.count - 1
  Some(ev)
}

///|
pub fn PreallocatedEventQueue::is_empty(self : PreallocatedEventQueue) -> Bool {
  self.count == 0
}

///|
pub fn PreallocatedEventQueue::clear(self : PreallocatedEventQueue) -> Unit {
  self.head = 0
  self.tail = 0
  self.count = 0
}