use crate::platform::{InputSnapshot, Platform};
use anyhow::Result;
use pixel8_runtime::fb::Framebuffer;
#[cfg(test)]
use std::{cell::RefCell, rc::Rc};
pub struct NullPlatform {
scripted: std::collections::VecDeque<InputSnapshot>,
presented: u32,
#[cfg(test)]
captured: Option<Rc<RefCell<Vec<Vec<u8>>>>>,
}
impl NullPlatform {
pub fn new() -> NullPlatform {
NullPlatform {
scripted: Default::default(),
presented: 0,
#[cfg(test)]
captured: None,
}
}
#[cfg(test)]
pub fn scripted(frames: Vec<InputSnapshot>) -> NullPlatform {
NullPlatform {
scripted: frames.into(),
presented: 0,
captured: None,
}
}
#[cfg(test)]
pub fn frames_presented(&self) -> u32 {
self.presented
}
#[cfg(test)]
pub fn scripted_with_capture(
frames: Vec<InputSnapshot>,
) -> (NullPlatform, Rc<RefCell<Vec<Vec<u8>>>>) {
let captured = Rc::new(RefCell::new(Vec::new()));
(
NullPlatform {
scripted: frames.into(),
presented: 0,
captured: Some(captured.clone()),
},
captured,
)
}
}
impl Default for NullPlatform {
fn default() -> NullPlatform {
NullPlatform::new()
}
}
impl Platform for NullPlatform {
fn present(&mut self, _fb: &Framebuffer) -> Result<()> {
self.presented += 1;
#[cfg(test)]
if let Some(captured) = &self.captured {
captured.borrow_mut().push(_fb.pixels().to_vec());
}
Ok(())
}
fn poll(&mut self) -> InputSnapshot {
self.scripted.pop_front().unwrap_or_default()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn scripted_then_default() {
let mut snap = InputSnapshot::default();
snap.buttons[4] = true;
let mut p = NullPlatform::scripted(vec![snap]);
assert!(p.poll().buttons[4], "first poll replays the script");
assert!(!p.poll().buttons[4], "exhausted script yields default");
p.present(&Framebuffer::new()).unwrap();
assert_eq!(p.frames_presented(), 1);
}
}