use crate::{
archetype,
component::Component,
registry::{
Null,
Registry,
},
};
use alloc::vec::Vec;
use core::{
any::type_name,
fmt::{
Debug,
DebugMap,
},
mem::size_of,
};
pub trait Sealed: Registry {
unsafe fn extract_component_pointers<R>(
index: usize,
components: &[(*mut u8, usize)],
pointers: &mut Vec<*const u8>,
identifier_iter: archetype::identifier::Iter<R>,
) where
R: Registry;
unsafe fn debug_components<R>(
pointers: &[*const u8],
debug_map: &mut DebugMap,
identifier_iter: archetype::identifier::Iter<R>,
) where
R: Registry;
}
impl Sealed for Null {
unsafe fn extract_component_pointers<R>(
_index: usize,
_components: &[(*mut u8, usize)],
_pointers: &mut Vec<*const u8>,
_identifier_iter: archetype::identifier::Iter<R>,
) where
R: Registry,
{
}
unsafe fn debug_components<R>(
_pointers: &[*const u8],
_debug_map: &mut DebugMap,
_identifier_iter: archetype::identifier::Iter<R>,
) where
R: Registry,
{
}
}
impl<C, R> Sealed for (C, R)
where
C: Component + Debug,
R: Sealed,
{
unsafe fn extract_component_pointers<R_>(
index: usize,
mut components: &[(*mut u8, usize)],
pointers: &mut Vec<*const u8>,
mut identifier_iter: archetype::identifier::Iter<R_>,
) where
R_: Registry,
{
if
unsafe { identifier_iter.next().unwrap_unchecked() } {
pointers.push(
unsafe { components.get_unchecked(0).0.add(index * size_of::<C>()) },
);
components =
unsafe { components.get_unchecked(1..) };
}
unsafe { R::extract_component_pointers(index, components, pointers, identifier_iter) };
}
unsafe fn debug_components<R_>(
mut pointers: &[*const u8],
debug_map: &mut DebugMap,
mut identifier_iter: archetype::identifier::Iter<R_>,
) where
R_: Registry,
{
if
unsafe { identifier_iter.next().unwrap_unchecked() } {
debug_map.entry(
&type_name::<C>(),
unsafe { &*pointers.get_unchecked(0).cast::<C>() },
);
pointers =
unsafe {pointers.get_unchecked(1..)};
}
unsafe { R::debug_components(pointers, debug_map, identifier_iter) };
}
}