use core::{any::Any, fmt::Debug};
use crate::{
archetype::{Slot, Storage},
buffer::ComponentBuffer,
component::{ComponentDesc, ComponentValue},
};
use super::Metadata;
component! {
pub debuggable: Debuggable,
}
#[derive(Clone)]
pub struct Debuggable {
pub(crate) debug_any: fn(&dyn Any) -> &dyn Debug,
pub(crate) debug_ptr: fn(&*const u8) -> &dyn Debug,
pub(crate) debug_storage: fn(&Storage, slot: Slot) -> &dyn Debug,
}
impl Debuggable {
pub fn debug<'a>(&self, value: &'a dyn Any) -> &'a dyn Debug {
(self.debug_any)(value)
}
pub(crate) unsafe fn debug_ptr<'a>(&self, ptr: &'a *const u8) -> &'a dyn Debug {
(self.debug_ptr)(ptr)
}
}
impl<T> Metadata<T> for Debuggable
where
T: Sized + core::fmt::Debug + ComponentValue,
{
fn attach(_: ComponentDesc, buffer: &mut ComponentBuffer) {
buffer.set(
debuggable(),
Debuggable {
debug_any: |value| value.downcast_ref::<T>().unwrap(),
debug_storage: |storage, slot| &storage.downcast_ref::<T>()[slot],
debug_ptr: |value| unsafe { &*(value.cast::<T>()) },
},
);
}
}