#![crate_name = "ecs"]
#![crate_type = "lib"]
#![feature(box_syntax)]
#![feature(core)]
#![feature(collections)]
#![feature(std_misc)]
pub use aspect::Aspect;
pub use component::{Component, ComponentList};
pub use component::{EntityBuilder, EntityModifier};
pub use entity::{Entity, EntityIter};
pub use system::{System, Process};
pub use world::{ComponentManager, SystemManager, DataHelper, World};
use std::ops::{Deref};
pub mod aspect;
pub mod component;
pub mod entity;
pub mod system;
pub mod world;
pub struct BuildData<'a>(&'a Entity);
pub struct ModifyData<'a>(&'a Entity);
pub struct EntityData<'a>(&'a Entity);
impl<'a> Deref for EntityData<'a>
{
type Target = Entity;
fn deref(&self) -> &Entity
{
&self.0
}
}
#[doc(hidden)]
pub unsafe trait EditData { fn entity(&self) -> &Entity; }
unsafe impl<'a> EditData for ModifyData<'a> { fn entity(&self) -> &Entity { &self.0 } }
unsafe impl<'a> EditData for EntityData<'a> { fn entity(&self) -> &Entity { &self.0 } }
#[macro_use]
mod macros
{
#[macro_export]
macro_rules! process {
{
$world:expr, $system:ident
} => {
$crate::Process::process(&mut $world.systems.$system, &mut $world.data)
};
}
#[macro_export]
macro_rules! components {
{
$Name:ident;
} => {
pub struct $Name;
unsafe impl $crate::ComponentManager for $Name
{
unsafe fn new() -> $Name
{
$Name
}
unsafe fn remove_all(&mut self, _: &$crate::Entity)
{
}
}
};
{
$Name:ident {
$(#[$kind:ident] $field_name:ident : $field_ty:ty),+
}
} => {
pub struct $Name {
$(
pub $field_name : $crate::ComponentList<$field_ty>,
)+
}
unsafe impl $crate::ComponentManager for $Name
{
unsafe fn new() -> $Name
{
$Name {
$(
$field_name : $crate::ComponentList::$kind(),
)+
}
}
unsafe fn remove_all(&mut self, entity: &$crate::Entity)
{
$(
self.$field_name.clear(entity);
)+
}
}
};
}
#[macro_export]
macro_rules! systems {
{
$Name:ident<$components:ty>;
} => {
pub struct $Name;
unsafe impl $crate::SystemManager for $Name
{
type Components = $components;
#[allow(unused_unsafe)] unsafe fn new() -> $Name
{
$Name
}
unsafe fn activated(&mut self, _: $crate::EntityData, _: &$components)
{
}
unsafe fn reactivated(&mut self, _: $crate::EntityData, _: &$components)
{
}
unsafe fn deactivated(&mut self, _: $crate::EntityData, _: &$components)
{
}
unsafe fn update(&mut self, _: &mut $crate::DataHelper<$components>)
{
}
}
};
{
$Name:ident<$components:ty> {
$($field_name:ident : $field_ty:ty = $field_init:expr),+
}
} => {
pub struct $Name {
$(
pub $field_name : $field_ty,
)+
}
unsafe impl $crate::SystemManager for $Name
{
type Components = $components;
#[allow(unused_unsafe)] unsafe fn new() -> $Name
{
$Name {
$(
$field_name : $field_init,
)+
}
}
unsafe fn activated(&mut self, en: $crate::EntityData, co: &$components)
{
$(
self.$field_name.activated(&en, co);
)+
}
unsafe fn reactivated(&mut self, en: $crate::EntityData, co: &$components)
{
$(
self.$field_name.reactivated(&en, co);
)+
}
unsafe fn deactivated(&mut self, en: $crate::EntityData, co: &$components)
{
$(
self.$field_name.deactivated(&en, co);
)+
}
unsafe fn update(&mut self, co: &mut $crate::DataHelper<$components>)
{
$(
if self.$field_name.is_active() {
$crate::Process::process(&mut self.$field_name, co);
}
)+
}
}
};
}
#[macro_export]
macro_rules! aspect {
{
<$components:ty>
all: [$($all_field:ident),*]
none: [$($none_field:ident),*]
} => {
unsafe {
$crate::Aspect::new(box |en: &$crate::EntityData, co: &$components| {
($(co.$all_field.has(en) &&)* true) &&
!($(co.$none_field.has(en) ||)* false)
})
}
};
{
<$components:ty>
all: [$($field:ident),*]
} => {
aspect!(
<$components>
all: [$($field),*]
none: []
)
};
{
<$components:ty>
none: [$($field:ident),*]
} => {
aspect!(
<$components>
all: []
none: [$($field),*]
)
};
}
}