use std::{fmt::Debug, hash::Hash, marker::PhantomData};
pub trait EntityRef: Clone + Copy + Debug + Hash + PartialEq + PartialOrd {
fn new(value: usize) -> Self;
fn as_u32(&self) -> u32;
fn as_usize(&self) -> usize;
}
#[derive(Clone, PartialEq)]
pub struct EntityList<T, Ref: EntityRef> {
private: Vec<T>,
phantom: PhantomData<Ref>,
}
impl<T, Ref: EntityRef> EntityList<T, Ref> {
#[inline(always)]
pub fn new() -> Self {
Self { private: Vec::new(), phantom: PhantomData }
}
pub fn push(&mut self, item: T) -> Ref {
let r = Ref::new(self.private.len());
self.private.push(item);
r
}
pub fn get(&self, item: Ref) -> &T {
&self.private[item.as_usize()]
}
pub fn get_mut(&mut self, item: Ref) -> &mut T {
&mut self.private[item.as_usize()]
}
pub fn len(&self) -> usize {
self.private.len()
}
pub fn entities(&self) -> &Vec<T> {
&self.private
}
pub fn entities_mut(&mut self) -> &mut Vec<T> {
&mut self.private
}
}
impl<T: Debug, Ref: EntityRef> Debug for EntityList<T, Ref> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.private.fmt(f)
}
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, PartialOrd)]
pub struct LabelRef(u32);
impl EntityRef for LabelRef {
#[inline(always)]
fn new(value: usize) -> Self {
Self(value as u32)
}
#[inline(always)]
fn as_u32(&self) -> u32 {
self.0
}
#[inline(always)]
fn as_usize(&self) -> usize {
self.0 as usize
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Label {
Attached(usize),
Unattached,
}