pub struct BspScratch<'a> {
pub face_visframe: &'a mut [u32],
pub frame: u32,
}
impl<'a> BspScratch<'a> {
pub fn new(face_visframe: &'a mut [u32]) -> Self {
Self {
face_visframe,
frame: 0,
}
}
#[inline]
pub fn mark_new_frame(&mut self) {
self.frame = self.frame.wrapping_add(1);
}
#[inline]
pub fn is_marked(&self, face_idx: usize) -> bool {
self.face_visframe.get(face_idx).copied().unwrap_or(0) == self.frame
}
#[inline]
pub fn mark(&mut self, face_idx: usize) {
if let Some(slot) = self.face_visframe.get_mut(face_idx) {
*slot = self.frame;
}
}
}
#[cfg(test)]
mod tests {
extern crate std;
use super::*;
#[test]
fn new_frame_deduplication() {
let mut buf = [0u32; 4];
let mut s = BspScratch::new(&mut buf);
s.mark_new_frame();
assert!(!s.is_marked(0));
s.mark(0);
assert!(s.is_marked(0));
assert!(!s.is_marked(1));
s.mark_new_frame();
assert!(!s.is_marked(0));
}
#[test]
fn out_of_bounds_mark_is_noop() {
let mut buf = [0u32; 2];
let mut s = BspScratch::new(&mut buf);
s.mark_new_frame();
s.mark(99); assert!(!s.is_marked(99));
}
#[test]
fn frame_wraps_safely() {
let mut buf = [0u32; 1];
let mut s = BspScratch::new(&mut buf);
s.frame = u32::MAX;
s.mark_new_frame();
assert_eq!(s.frame, 0);
}
}