diff options
Diffstat (limited to 'ecs/src')
-rw-r--r-- | ecs/src/entity.rs | 65 | ||||
-rw-r--r-- | ecs/src/extension.rs | 7 | ||||
-rw-r--r-- | ecs/src/lib.rs | 26 | ||||
-rw-r--r-- | ecs/src/phase.rs | 16 | ||||
-rw-r--r-- | ecs/src/private.rs | 2 |
5 files changed, 73 insertions, 43 deletions
diff --git a/ecs/src/entity.rs b/ecs/src/entity.rs index 4496a2b..ef91d20 100644 --- a/ecs/src/entity.rs +++ b/ecs/src/entity.rs @@ -1,6 +1,6 @@ use std::any::type_name; - -use linkme::distributed_slice; +use std::ops::Deref; +use std::sync::LazyLock; use crate::component::storage::archetype::{ Archetype, @@ -124,31 +124,48 @@ impl<'a> Iterator for MatchingComponentIter<'a> } } +/// The data type of a declaration of a entity. +#[derive(Debug)] +pub struct Declaration +{ + uid: LazyLock<Uid>, + create_func: fn(&mut World), +} + +impl Declaration +{ + pub(crate) fn create(&self, world: &mut World) + { + (self.create_func)(world); + } + + #[doc(hidden)] + pub const fn new(create_func: fn(&mut World)) -> Self + { + Self { + uid: LazyLock::new(|| Uid::new_unique(UidKind::Entity)), + create_func, + } + } +} + +impl Deref for Declaration +{ + type Target = Uid; + + fn deref(&self) -> &Self::Target + { + &self.uid + } +} + #[allow(clippy::module_name_repetitions)] #[macro_export] -macro_rules! static_entity { +macro_rules! declare_entity { ($visibility: vis $ident: ident, $components: expr) => { - $visibility static $ident: ::std::sync::LazyLock<$crate::uid::Uid> = - ::std::sync::LazyLock::new(|| { - $crate::uid::Uid::new_unique($crate::uid::Kind::Entity) + $visibility static $ident: $crate::entity::Declaration = + $crate::entity::Declaration::new(|world| { + world.create_entity_with_uid(*$ident, $components); }); - - $crate::private::paste::paste! { - mod [<__ecs_ $ident:lower _static_entity_priv>] { - use super::*; - - #[$crate::private::linkme::distributed_slice( - $crate::entity::CREATE_STATIC_ENTITIES - )] - #[linkme(crate=$crate::private::linkme)] - static CREATE_STATIC_ENTITY: fn(&mut $crate::World) = |world| { - world.create_entity_with_uid($components, *$ident); - }; - } - } } } - -#[distributed_slice] -#[doc(hidden)] -pub static CREATE_STATIC_ENTITIES: [fn(&mut World)]; diff --git a/ecs/src/extension.rs b/ecs/src/extension.rs index 42ebef9..e180ac7 100644 --- a/ecs/src/extension.rs +++ b/ecs/src/extension.rs @@ -1,4 +1,5 @@ use crate::component::Sequence as ComponentSequence; +use crate::entity::Declaration as EntityDeclaration; use crate::sole::Sole; use crate::system::System; use crate::uid::Uid; @@ -42,6 +43,12 @@ impl<'world> Collector<'world> self.world.create_entity(components); } + /// Adds a declared entity to the [`World`]. + pub fn add_declared_entity(&mut self, entity_decl: &EntityDeclaration) + { + self.world.create_declared_entity(entity_decl); + } + /// Adds a globally shared singleton value to the [`World`]. /// /// # Errors diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 53abc6b..979b517 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -18,7 +18,7 @@ use crate::component::{ Parts as ComponentParts, Sequence as ComponentSequence, }; -use crate::entity::CREATE_STATIC_ENTITIES; +use crate::entity::Declaration as EntityDeclaration; use crate::event::component::{ Added as ComponentAddedEvent, Removed as ComponentRemovedEvent, @@ -56,9 +56,6 @@ pub mod tuple; pub mod uid; pub mod util; -#[doc(hidden)] -pub mod private; - mod lock; pub use ecs_macros::{Component, Sole}; @@ -84,30 +81,30 @@ impl World is_first_tick: AtomicBool::new(false), }; - world.add_sole(Stats::default()).ok(); + crate::phase::spawn_entities(&mut world); - for create_static_entity in CREATE_STATIC_ENTITIES { - create_static_entity(&mut world); - } + world.add_sole(Stats::default()).ok(); world } - /// Creates a new entity with the given components. + /// Creates a entity with the given components. A new unique [`Uid`] will be generated + /// for this entity. pub fn create_entity<Comps>(&mut self, components: Comps) -> Uid where Comps: ComponentSequence, { let entity_uid = Uid::new_unique(UidKind::Entity); - self.create_entity_with_uid(components, entity_uid); + self.create_entity_with_uid(entity_uid, components); entity_uid } + /// Creates a entity with the given components. The entity will have the specified + /// [`Uid`]. #[tracing::instrument(skip_all)] - #[doc(hidden)] - pub fn create_entity_with_uid<Comps>(&mut self, components: Comps, entity_uid: Uid) + pub fn create_entity_with_uid<Comps>(&mut self, entity_uid: Uid, components: Comps) where Comps: ComponentSequence, { @@ -129,6 +126,11 @@ impl World } } + pub fn create_declared_entity(&mut self, entity_decl: &EntityDeclaration) + { + entity_decl.create(self); + } + /// Adds a globally shared singleton value. /// /// # Errors diff --git a/ecs/src/phase.rs b/ecs/src/phase.rs index 9f47fb8..c13c432 100644 --- a/ecs/src/phase.rs +++ b/ecs/src/phase.rs @@ -1,13 +1,19 @@ use ecs_macros::Component; use crate::pair::{ChildOf, Pair}; -use crate::static_entity; +use crate::{declare_entity, World}; #[derive(Debug, Default, Clone, Copy, Component)] pub struct Phase; -static_entity!(pub START, (Phase,)); +declare_entity!(pub START, (Phase,)); +declare_entity!(pub PRE_UPDATE, (Phase,)); +declare_entity!(pub UPDATE, (Phase, Pair::new::<ChildOf>(*PRE_UPDATE))); -static_entity!(pub PRE_UPDATE, (Phase,)); - -static_entity!(pub UPDATE, (Phase, Pair::new::<ChildOf>(*PRE_UPDATE))); +#[doc(hidden)] +pub(crate) fn spawn_entities(world: &mut World) +{ + world.create_declared_entity(&START); + world.create_declared_entity(&PRE_UPDATE); + world.create_declared_entity(&UPDATE); +} diff --git a/ecs/src/private.rs b/ecs/src/private.rs deleted file mode 100644 index 56a6552..0000000 --- a/ecs/src/private.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[doc(hidden)] -pub use {linkme, paste}; |