#![cfg(debug_assertions)]
use core::any::TypeId;
use core::sync::atomic::{AtomicPtr, Ordering};
use crate::ecs::Access;
pub enum Touch {
ComponentRead {
id: u8,
type_name: &'static str,
},
ComponentWrite {
id: u8,
type_name: &'static str,
},
Structural {
op: &'static str,
},
Resource {
type_id: TypeId,
type_name: &'static str,
write: bool,
},
Blob {
op: &'static str,
},
}
type Hook = fn(&Touch);
type ActiveHook = fn(Option<(Access, &'static str)>);
static HOOK: AtomicPtr<()> = AtomicPtr::new(core::ptr::null_mut());
static ACTIVE_HOOK: AtomicPtr<()> = AtomicPtr::new(core::ptr::null_mut());
pub fn install(hook: Hook) {
HOOK.store(hook as *mut (), Ordering::Release);
}
pub fn install_active(hook: ActiveHook) {
ACTIVE_HOOK.store(hook as *mut (), Ordering::Release);
}
#[inline]
pub(crate) fn touch(t: Touch) {
let raw = HOOK.load(Ordering::Acquire);
if raw.is_null() {
return;
}
let hook: Hook = unsafe { core::mem::transmute::<*mut (), Hook>(raw) };
hook(&t);
}
pub fn set_active(active: Option<(Access, &'static str)>) {
let raw = ACTIVE_HOOK.load(Ordering::Acquire);
if raw.is_null() {
return;
}
let hook: ActiveHook = unsafe { core::mem::transmute::<*mut (), ActiveHook>(raw) };
hook(active);
}