summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock21
-rw-r--r--ecs/Cargo.toml1
-rw-r--r--ecs/src/entity.rs30
-rw-r--r--ecs/src/lib.rs25
-rw-r--r--ecs/src/private.rs2
5 files changed, 74 insertions, 5 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 044c18d..e7faae2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -113,6 +113,7 @@ name = "ecs"
version = "0.1.0"
dependencies = [
"ecs-macros",
+ "linkme",
"paste",
"seq-macro",
"thiserror",
@@ -288,6 +289,26 @@ dependencies = [
]
[[package]]
+name = "linkme"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70fe496a7af8c406f877635cbf3cd6a9fac9d6f443f58691cd8afe6ce0971af4"
+dependencies = [
+ "linkme-impl",
+]
+
+[[package]]
+name = "linkme-impl"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b01f197a15988fb5b2ec0a5a9800c97e70771499c456ad757d63b3c5e9b96e75"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
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};