diff options
Diffstat (limited to 'ecs')
-rw-r--r-- | ecs/Cargo.toml | 1 | ||||
-rw-r--r-- | ecs/src/entity.rs | 30 | ||||
-rw-r--r-- | ecs/src/lib.rs | 25 | ||||
-rw-r--r-- | ecs/src/private.rs | 2 |
4 files changed, 53 insertions, 5 deletions
diff --git a/ecs/Cargo.toml b/ecs/Cargo.toml index 069482d..0f86ef7 100644 --- a/ecs/Cargo.toml +++ b/ecs/Cargo.toml @@ -12,6 +12,7 @@ seq-macro = "0.3.5" paste = "1.0.14" thiserror = "1.0.49" tracing = { version = "0.1.39", optional = true } +linkme = "0.3.29" ecs-macros = { path = "../ecs-macros" } util-macros = { path = "../util-macros" } diff --git a/ecs/src/entity.rs b/ecs/src/entity.rs index abc5991..18f229a 100644 --- a/ecs/src/entity.rs +++ b/ecs/src/entity.rs @@ -1,5 +1,9 @@ use std::sync::atomic::{AtomicU64, Ordering}; +use linkme::distributed_slice; + +use crate::World; + static NEXT_UID: AtomicU64 = AtomicU64::new(0); /// Unique entity ID. @@ -28,3 +32,29 @@ impl Uid } } } + +#[macro_export] +macro_rules! static_entity { + ($visibility: vis $ident: ident, $components: expr) => { + $visibility static $ident: ::std::sync::LazyLock<$crate::entity::Uid> = + ::std::sync::LazyLock::new(|| $crate::entity::Uid::new_unique()); + + $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(&$crate::World) = |world| { + world.create_entity_with_uid($components, *$ident); + }; + } + } + } +} + +#[distributed_slice] +#[doc(hidden)] +pub static CREATE_STATIC_ENTITIES: [fn(&World)]; diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 3c517dd..6725d81 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -11,7 +11,7 @@ use std::sync::Arc; use crate::actions::Action; use crate::component::storage::Storage as ComponentStorage; use crate::component::{Component, Id as ComponentId, Sequence as ComponentSequence}; -use crate::entity::Uid as EntityUid; +use crate::entity::{Uid as EntityUid, CREATE_STATIC_ENTITIES}; use crate::event::component::{ create_added_id as create_component_added_event_id, create_removed_id as create_component_removed_event_id, @@ -42,6 +42,9 @@ pub mod system; pub mod tuple; pub mod type_name; +#[doc(hidden)] +pub mod private; + mod archetype; mod util; @@ -75,7 +78,6 @@ impl World /// /// # Panics /// Will panic if mutable internal lock cannot be acquired. - #[cfg_attr(feature = "debug", tracing::instrument(skip_all))] pub fn create_entity<Comps>(&mut self, components: Comps) -> EntityUid where Comps: ComponentSequence + TupleReduce<TypeTransformComponentsToAddedEvents>, @@ -83,6 +85,17 @@ impl World { let entity_uid = EntityUid::new_unique(); + self.create_entity_with_uid(components, entity_uid); + + entity_uid + } + + #[cfg_attr(feature = "debug", tracing::instrument(skip_all))] + pub fn create_entity_with_uid<Comps>(&self, components: Comps, entity_uid: EntityUid) + where + Comps: ComponentSequence + TupleReduce<TypeTransformComponentsToAddedEvents>, + Comps::Out: EventSequence, + { #[allow(unused_variables)] if let Err(err) = self .data @@ -94,14 +107,12 @@ impl World #[cfg(feature = "debug")] tracing::error!("Failed to create entity: {err}"); - return entity_uid; + return; }; for component_added_event_id in <Comps::Out as EventSequence>::ids().iter() { self.emit_event_by_id(*component_added_event_id); } - - entity_uid } /// Adds a globally shared singleton value. @@ -279,6 +290,10 @@ impl World /// Will panic if a internal lock cannot be acquired. pub fn event_loop<EventSeq: EventSequence>(&self) { + for create_static_entity in CREATE_STATIC_ENTITIES { + create_static_entity(self); + } + self.emit(StartEvent); let event_seq = EventSeq::ids(); diff --git a/ecs/src/private.rs b/ecs/src/private.rs new file mode 100644 index 0000000..56a6552 --- /dev/null +++ b/ecs/src/private.rs @@ -0,0 +1,2 @@ +#[doc(hidden)] +pub use {linkme, paste}; |