use alloc::{boxed::Box, vec::Vec};
pub struct SimpleBatch {
#[expect(clippy::type_complexity, reason = "pending simplification")]
functions: Vec<(fn(*mut ()), *mut ())>,
}
impl SimpleBatch {
const MAX: usize = {
if cfg!(feature = "loom") {
4
} else {
32
}
};
pub const fn new() -> Self {
Self {
functions: Vec::new(),
}
}
pub const fn is_empty(&self) -> bool {
self.functions.is_empty()
}
pub const fn is_full(&self) -> bool {
self.functions.len() >= Self::MAX
}
}
impl Default for SimpleBatch {
fn default() -> Self {
Self::new()
}
}
unsafe impl Send for SimpleBatch {}
impl Drop for SimpleBatch {
fn drop(&mut self) {
self.execute();
}
}
impl SimpleBatch {
pub fn add<F>(&mut self, f: F) -> Result<(), F>
where
F: FnOnce() + Send + 'static,
{
unsafe { self.add_unchecked(f) }
}
pub unsafe fn add_unchecked<F: FnOnce()>(&mut self, f: F) -> Result<(), F> {
if self.is_full() {
return Err(f);
}
let data = Box::into_raw(Box::new(f)).cast::<()>();
let func = |data: *mut ()| (unsafe { Box::from_raw(data.cast::<F>()) })();
self.functions.push((func, data));
Ok(())
}
pub fn execute(&mut self) {
for (func, data) in self.functions.drain(..) {
(func)(data);
}
}
}