use crate::{
archetype,
registry::Registry,
};
use core::{
fmt,
fmt::Debug,
};
use fnv::FnvBuildHasher;
use hashbrown::HashMap;
pub(crate) struct Location<R>
where
R: Registry,
{
pub(crate) identifier: archetype::IdentifierRef<R>,
pub(crate) index: usize,
}
impl<R> Location<R>
where
R: Registry,
{
pub(crate) fn new(identifier: archetype::IdentifierRef<R>, index: usize) -> Self {
Self { identifier, index }
}
pub(super) unsafe fn clone_with_new_identifier(
&self,
identifier_map: &HashMap<
archetype::IdentifierRef<R>,
archetype::IdentifierRef<R>,
FnvBuildHasher,
>,
) -> Self {
Self {
identifier: *unsafe { identifier_map.get(&self.identifier).unwrap_unchecked() },
index: self.index,
}
}
}
impl<R> Clone for Location<R>
where
R: Registry,
{
fn clone(&self) -> Self {
*self
}
}
impl<R> Copy for Location<R> where R: Registry {}
impl<R> Debug for Location<R>
where
R: Registry,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Location")
.field("identifier", &self.identifier)
.field("index", &self.index)
.finish()
}
}
impl<R> PartialEq for Location<R>
where
R: Registry,
{
fn eq(&self, other: &Self) -> bool {
unsafe {
self.identifier.as_slice() == other.identifier.as_slice() && self.index == other.index
}
}
}
#[cfg(test)]
mod tests {
use super::Location;
use crate::{
archetype::Identifier,
Registry,
};
use alloc::vec;
macro_rules! create_components {
($( $variants:ident ),*) => {
$(
struct $variants(f32);
)*
};
}
create_components!(
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z
);
type Registry =
Registry!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z);
#[test]
fn new() {
let identifier = unsafe { Identifier::<Registry>::new(vec![1, 2, 3, 0]) };
let location = Location::new(unsafe { identifier.as_ref() }, 42);
assert_eq!(location.identifier, unsafe { identifier.as_ref() });
assert_eq!(location.index, 42);
}
}