use crate::entity;
use crate::iter;
use crate::sparse;
pub struct ComponentVec<T> {
entities: sparse::Set,
components: Vec<T>,
}
impl<T> ComponentVec<T> {
#[must_use]
#[inline]
pub fn new() -> Self {
Self {
components: Vec::new(),
entities: sparse::Set::new(),
}
}
#[must_use]
#[inline]
pub fn len(&self) -> usize {
self.components.len()
}
#[must_use]
#[inline]
pub fn is_empty(&self) -> bool {
self.components.is_empty()
}
#[must_use]
#[inline]
pub fn contains(&self, entity: entity::Entity) -> bool {
self.entities.contains(entity)
}
#[must_use]
#[inline]
pub fn get(&self, entity: entity::Entity) -> Option<&T> {
let index = self.entities.index_of(entity)?;
self.components.get(index)
}
#[must_use]
#[inline]
pub fn get_mut(&mut self, entity: entity::Entity) -> Option<&mut T> {
let index = self.entities.index_of(entity)?;
self.components.get_mut(index)
}
#[inline]
pub fn insert(&mut self, entity: entity::Entity, component: T) -> Option<T> {
if let Some(value) = self.get_mut(entity) {
Some(std::mem::replace(value, component))
} else {
self.entities.insert(entity);
self.components.push(component);
None
}
}
#[inline]
pub fn remove(&mut self, entity: entity::Entity) -> Option<T> {
if let Some(index) = self.entities.index_of(entity) {
self.entities.remove(entity);
Some(self.components.swap_remove(index))
} else {
None
}
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.entities.reserve(additional);
self.components.reserve(additional);
}
#[inline]
pub fn iter(&self) -> Iter<'_, T> {
self.entities.iter().zip(self.components.iter())
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
self.entities.iter().zip(self.components.iter_mut())
}
}
impl<T> Default for ComponentVec<T> {
#[inline]
fn default() -> ComponentVec<T> {
ComponentVec::new()
}
}
use std::iter::Zip;
use std::slice;
pub type Iter<'a, T> = Zip<iter::Iter<'a, entity::Entity>, slice::Iter<'a, T>>;
pub type IterMut<'a, T> = Zip<iter::Iter<'a, entity::Entity>, slice::IterMut<'a, T>>;
impl<'a, T> IntoIterator for &'a ComponentVec<T> {
type IntoIter = Iter<'a, T>;
type Item = (entity::Entity, &'a T);
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut ComponentVec<T> {
type IntoIter = IterMut<'a, T>;
type Item = (entity::Entity, &'a mut T);
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
mod sealed {
use super::ComponentVec;
pub trait Sealed {}
impl<T> Sealed for &ComponentVec<T> {}
impl<T> Sealed for &mut ComponentVec<T> {}
}
use sealed::Sealed;
pub struct RefOrMut<'a, T> {
pub(crate) entities: &'a sparse::Set,
components: T,
}
pub trait IntoRefOrMut<'a>: Sealed {
type Components;
fn into_ref_or_mut(self) -> RefOrMut<'a, Self::Components>;
}
impl<'a, T> IntoRefOrMut<'a> for &'a ComponentVec<T> {
type Components = &'a [T];
#[inline]
fn into_ref_or_mut(self) -> RefOrMut<'a, Self::Components> {
RefOrMut {
entities: &self.entities,
components: &self.components,
}
}
}
impl<'a, T> IntoRefOrMut<'a> for &'a mut ComponentVec<T> {
type Components = &'a mut [T];
#[inline]
fn into_ref_or_mut(self) -> RefOrMut<'a, Self::Components> {
RefOrMut {
entities: &self.entities,
components: &mut self.components,
}
}
}
impl<'l, 'a, T> iter::Lifetime<'l> for RefOrMut<'a, &'a [T]> {
type Item = &'l T;
}
impl<'l, 'a, T> iter::Lifetime<'l> for RefOrMut<'a, &'a mut [T]> {
type Item = &'l mut T;
}
pub trait GetRefOrMut: for<'l> iter::Lifetime<'l> {
fn get_ref_or_mut(
&mut self,
entity: entity::Entity,
) -> Option<<Self as iter::Lifetime<'_>>::Item>;
}
impl<'a, T> GetRefOrMut for RefOrMut<'a, &'a [T]> {
#[inline]
fn get_ref_or_mut(
&mut self,
entity: entity::Entity,
) -> Option<<Self as iter::Lifetime<'_>>::Item> {
let index = self.entities.index_of(entity)?;
self.components.get(index)
}
}
impl<'a, T> GetRefOrMut for RefOrMut<'a, &'a mut [T]> {
#[inline]
fn get_ref_or_mut(
&mut self,
entity: entity::Entity,
) -> Option<<Self as iter::Lifetime<'_>>::Item> {
let index = self.entities.index_of(entity)?;
self.components.get_mut(index)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn components_i32_put_then_delete() {
let mut components = ComponentVec::new();
let e0 = entity::Entity::from(0);
let e1 = entity::Entity::from(1);
components.insert(e0, 42);
assert_eq!(components.components.len(), 1);
components.insert(e1, 17);
assert_eq!(components.components.len(), 2);
assert_eq!(components.get(e0), Some(&42));
assert_eq!(components.get(e1), Some(&17));
assert_eq!(components.get_mut(e0), Some(&mut 42));
assert_eq!(components.get_mut(e1), Some(&mut 17));
components.remove(e0);
assert_eq!(components.components.len(), 1);
assert_eq!(components.get(e0), None);
assert_eq!(components.get(e1), Some(&17));
assert_eq!(components.get_mut(e0), None);
assert_eq!(components.get_mut(e1), Some(&mut 17));
components.remove(e1);
assert_eq!(components.components.len(), 0);
assert_eq!(components.get(e0), None);
assert_eq!(components.get(e1), None);
assert_eq!(components.get_mut(e0), None);
assert_eq!(components.get_mut(e1), None);
}
#[test]
fn reserve() {
let mut vec = ComponentVec::<i32>::new();
assert_eq!(vec.components.capacity(), 0);
let additional = 100;
vec.reserve(additional);
assert!(vec.components.capacity() >= vec.components.len() + additional);
}
#[test]
fn contains() {
let mut components = ComponentVec::<i32>::new();
let e0 = entity::Entity::from(0);
let e1 = entity::Entity::from(1);
let e2 = entity::Entity::from(2);
components.insert(e0, 42);
components.insert(e2, 17);
assert_eq!(components.contains(e0), true);
assert_eq!(components.contains(e1), false);
assert_eq!(components.contains(e2), true);
}
}