use std::cell::RefCell;
use crate::reactive::request_frame;
use crate::render::Screenshot;
type ShotCallback = Box<dyn FnOnce(Screenshot)>;
thread_local! {
static PENDING: RefCell<Vec<ShotCallback>> = const { RefCell::new(Vec::new()) };
}
pub fn request_screenshot(f: impl FnOnce(Screenshot) + 'static) {
PENDING.with(|p| p.borrow_mut().push(Box::new(f)));
request_frame();
}
pub(crate) fn take_screenshot_requests() -> Vec<ShotCallback> {
PENDING.with(|p| std::mem::take(&mut *p.borrow_mut()))
}
#[cfg(test)]
mod tests {
use super::*;
use std::cell::Cell;
use std::rc::Rc;
#[test]
fn requests_queue_and_drain_once() {
assert!(take_screenshot_requests().is_empty(), "clean start");
let served = Rc::new(Cell::new(0));
let s = served.clone();
request_screenshot(move |_| s.set(s.get() + 1));
let pending = take_screenshot_requests();
assert_eq!(pending.len(), 1);
assert!(take_screenshot_requests().is_empty(), "drain is one-shot");
let blank = Screenshot::from_surface(&crate::render::Surface::new(
crate::base::Size::new(2, 1),
crate::render::Cell::EMPTY,
));
for cb in pending {
cb(blank.clone());
}
assert_eq!(served.get(), 1);
}
}