mod builder;
pub use self::builder::*;
use crate::component::{
Component, ComponentData, ComponentSet, ComponentStorage, GroupInfo, GroupLayout, View, ViewMut,
};
use crate::entity::{Entity, EntityStorage};
use crate::query::{Query, QueryAll, QueryOne};
use core::any::TypeId;
#[derive(Default, Debug)]
pub struct World {
pub(crate) entities: EntityStorage,
pub(crate) components: ComponentStorage,
}
impl World {
#[inline]
pub fn builder() -> WorldBuilder {
WorldBuilder::default()
}
#[inline]
#[must_use]
pub fn new(layout: &GroupLayout) -> Self {
Self {
entities: EntityStorage::default(),
components: ComponentStorage::new(layout),
}
}
#[inline]
pub fn set_layout(&mut self, layout: &GroupLayout) {
unsafe {
self.components.set_layout(layout, self.entities.as_slice());
}
}
pub fn register<T>(&mut self) -> bool
where
T: Component,
{
self.register_dyn(ComponentData::new::<T>())
}
#[inline]
pub fn register_dyn(&mut self, component: ComponentData) -> bool {
self.components.register_dyn(component)
}
#[must_use]
pub fn is_registered<T>(&self) -> bool
where
T: Component,
{
self.is_registered_dyn(TypeId::of::<T>())
}
#[inline]
#[must_use]
pub fn is_registered_dyn(&self, component: TypeId) -> bool {
self.components.is_registered_dyn(component)
}
pub fn create<C>(&mut self, components: C) -> Entity
where
C: ComponentSet,
{
let entity = self.entities.create();
unsafe {
C::insert(self, entity, components);
}
entity
}
pub fn extend<C, I>(&mut self, components: I) -> &[Entity]
where
C: ComponentSet,
I: IntoIterator<Item = C>,
{
C::extend(self, components)
}
#[inline]
pub fn destroy(&mut self, entity: Entity) -> bool {
if !self.entities.remove(entity) {
return false;
}
self.components.strip(entity);
true
}
#[inline]
pub fn create_atomic(&self) -> Entity {
self.entities.create_atomic()
}
#[inline]
pub fn maintain(&mut self) {
self.entities.maintain();
}
pub fn insert<C>(&mut self, entity: Entity, components: C) -> bool
where
C: ComponentSet,
{
if !self.entities.contains(entity) {
return false;
}
unsafe {
C::insert(self, entity, components);
}
true
}
#[must_use = "Use `delete` to discard the components."]
pub fn remove<C>(&mut self, entity: Entity) -> C::Remove
where
C: ComponentSet,
{
unsafe { C::remove(self, entity) }
}
pub fn delete<C>(&mut self, entity: Entity)
where
C: ComponentSet,
{
unsafe {
C::delete(self, entity);
}
}
pub fn query_one<G>(&self) -> QueryOne<G, (), ()>
where
G: Query,
{
QueryOne::new(self)
}
pub fn query_all<G>(&self) -> QueryAll<G, (), ()>
where
G: Query,
{
QueryAll::new(self)
}
#[must_use]
pub fn contains<G>(&self, entity: Entity) -> bool
where
G: Query,
{
QueryOne::<G, (), ()>::new(self).contains(entity)
}
pub fn for_each<G>(&self, f: impl FnMut(G::Item<'_>))
where
G: Query,
{
self.query_all().for_each(f);
}
#[cfg(feature = "parallel")]
pub fn par_for_each<G>(&self, f: impl Fn(G::Item<'_>) + Send + Sync)
where
G: Query,
{
self.query_all().par_for_each(f);
}
#[inline]
#[must_use]
pub fn contains_entity(&self, entity: Entity) -> bool {
self.entities.contains(entity)
}
#[inline]
#[must_use]
pub fn entities(&self) -> &[Entity] {
self.entities.as_slice()
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.entities.is_empty()
}
#[inline]
pub fn clear(&mut self) {
self.entities.clear();
self.components.clear();
}
#[inline]
pub fn reset(&mut self) {
self.entities.reset();
self.components.clear();
}
#[must_use]
pub fn borrow<T>(&self) -> View<T>
where
T: Component,
{
self.components.borrow::<T>()
}
#[must_use]
pub fn borrow_mut<T>(&self) -> ViewMut<T>
where
T: Component,
{
self.components.borrow_mut::<T>()
}
#[must_use]
pub fn borrow_with_group_info<T>(&self) -> (View<T>, Option<GroupInfo>)
where
T: Component,
{
self.components.borrow_with_group_info::<T>()
}
#[must_use]
pub fn borrow_with_group_info_mut<T>(&self) -> (ViewMut<T>, Option<GroupInfo>)
where
T: Component,
{
self.components.borrow_with_group_info_mut::<T>()
}
}