summaryrefslogtreecommitdiff
path: root/engine-ecs
diff options
context:
space:
mode:
Diffstat (limited to 'engine-ecs')
-rw-r--r--engine-ecs/src/actions.rs12
-rw-r--r--engine-ecs/src/entity.rs2
-rw-r--r--engine-ecs/src/lib.rs38
-rw-r--r--engine-ecs/src/sole.rs7
-rw-r--r--engine-ecs/src/system.rs4
5 files changed, 54 insertions, 9 deletions
diff --git a/engine-ecs/src/actions.rs b/engine-ecs/src/actions.rs
index cef51cc..bbc19c6 100644
--- a/engine-ecs/src/actions.rs
+++ b/engine-ecs/src/actions.rs
@@ -10,6 +10,7 @@ use crate::component::{
use crate::entity::Name as EntityName;
use crate::event::component::Removed;
use crate::pair::Pair;
+use crate::sole::Sole;
use crate::system::{Metadata as SystemMetadata, Param as SystemParam};
use crate::uid::Uid;
use crate::{ActionQueue, World};
@@ -304,6 +305,16 @@ impl Actions<'_>
});
}
+ /// Queues up creation of a sole at the end of the current tick, returning the [`Uid`]
+ /// of the sole.
+ pub fn create_sole<SoleT: Sole>(&mut self, sole: SoleT) -> Uid
+ {
+ self.action_queue
+ .push(Action::CreateSole(sole.into_parts()));
+
+ SoleT::id()
+ }
+
/// Stops the [`World`]. The world will finish the current tick and that tick will be
/// the last.
pub fn stop(&mut self)
@@ -339,5 +350,6 @@ pub(crate) enum Action
pair_id: Uid,
new_pair: ComponentParts,
},
+ CreateSole(ComponentParts),
Stop,
}
diff --git a/engine-ecs/src/entity.rs b/engine-ecs/src/entity.rs
index 4d472ad..e85c49c 100644
--- a/engine-ecs/src/entity.rs
+++ b/engine-ecs/src/entity.rs
@@ -334,7 +334,7 @@ macro_rules! declare_entity {
world.spawn_with_uid(
*$ident,
($components).with_elem($crate::entity::Name {
- name: concat!(module_path!(), stringify!($ident)).into()
+ name: concat!(module_path!(), "::", stringify!($ident)).into()
})
);
});
diff --git a/engine-ecs/src/lib.rs b/engine-ecs/src/lib.rs
index 6028cf7..f9e8143 100644
--- a/engine-ecs/src/lib.rs
+++ b/engine-ecs/src/lib.rs
@@ -60,10 +60,10 @@ use crate::sole::{Single, Sole};
use crate::system::observer::Observer;
use crate::system::{
Callbacks,
+ Function as SystemFunction,
Metadata as SystemMetadata,
Param as SystemParam,
System,
- SystemComponent,
};
use crate::uid::Uid;
@@ -253,6 +253,7 @@ impl World
[
sole.into_parts(),
EntityName { name: name.into() }.into_parts(),
+ crate::sole::Is.into_parts(),
],
&ComponentAddingFlags { allow_soles: true },
);
@@ -272,7 +273,7 @@ impl World
self.create_ent(
ent_id,
- [SystemComponent { system }.into_parts()].into_iter().chain(
+ [SystemFunction { system }.into_parts()].into_iter().chain(
ObserverT::observed_events()
.into_iter()
.map(IntoComponentParts::into_parts),
@@ -291,7 +292,7 @@ impl World
{
let (type_erased_system, mut system_callbacks) = system.finish();
- let system_ent_id = self.spawn((SystemComponent { system: type_erased_system },));
+ let system_ent_id = self.spawn((SystemFunction { system: type_erased_system },));
system_callbacks.on_created(self, SystemMetadata { ent_id: system_ent_id });
@@ -491,7 +492,7 @@ impl World
.into_iter()
.filter_map(|phase_has_system| phase_has_system.get_target_ent())
{
- let Some(system) = system_entity.get::<SystemComponent>() else {
+ let Some(system) = system_entity.get::<SystemFunction>() else {
cold_path();
continue;
};
@@ -667,6 +668,31 @@ impl World
&ComponentAddingFlags { allow_soles: false },
);
}
+ Action::CreateSole(sole_parts) => {
+ if let Err(EntityAlreadyExistsError) =
+ self.data.component_storage.create_entity(sole_parts.id)
+ {
+ tracing::error!(
+ name = sole_parts.name,
+ "Can not create sole that already exists"
+ );
+ continue;
+ }
+
+ let name = sole_parts.name;
+
+ Self::add_entity_components(
+ sole_parts.id,
+ [
+ sole_parts,
+ EntityName { name: name.into() }.into_parts(),
+ crate::sole::Is.into_parts(),
+ ],
+ &mut self.data.component_storage,
+ &EventSubmitter::new(&self.data.new_events),
+ &ComponentAddingFlags { allow_soles: true },
+ );
+ }
Action::Stop => {
self.stop.store(true, Ordering::Relaxed);
}
@@ -874,10 +900,10 @@ impl World
{
assert!(event_id.is_pair());
- let query = Query::<(&SystemComponent,)>::from_flexible_query(
+ let query = Query::<(&SystemFunction,)>::from_flexible_query(
self.flexible_query(
QueryTerms::<QUERY_MAX_TERM_CNT>::builder()
- .present([SystemComponent::id(), event_id])
+ .present([SystemFunction::id(), event_id])
.build(),
),
);
diff --git a/engine-ecs/src/sole.rs b/engine-ecs/src/sole.rs
index 9168414..cf5283b 100644
--- a/engine-ecs/src/sole.rs
+++ b/engine-ecs/src/sole.rs
@@ -7,7 +7,7 @@ use crate::component::{
WithAssociatedId as ComponentWithAssociatedId,
};
use crate::system::{Metadata as SystemMetadata, Param as SystemParam};
-use crate::World;
+use crate::{Component, World};
/// A component which has a single instance in the [`World`].
pub trait Sole: Any + IntoComponentParts + ComponentWithAssociatedId
@@ -20,6 +20,11 @@ pub trait Sole: Any + IntoComponentParts + ComponentWithAssociatedId
fn name(&self) -> &'static str;
}
+/// Marker component for the entities of soles.
+#[derive(Debug, Component)]
+#[non_exhaustive]
+pub struct Is;
+
/// Holds a reference to a singleton component.
#[derive(Debug)]
pub struct Single<'world, SoleT: Sole>
diff --git a/engine-ecs/src/system.rs b/engine-ecs/src/system.rs
index e0eac57..b79f20c 100644
--- a/engine-ecs/src/system.rs
+++ b/engine-ecs/src/system.rs
@@ -163,8 +163,10 @@ impl Callbacks for NoCallbacks
fn on_created(&mut self, _world: &mut World, _metadata: Metadata) {}
}
+/// System & observer function component. Intentionally not runnable outside of this
+/// crate.
#[derive(Debug, Component)]
-pub(crate) struct SystemComponent
+pub struct Function
{
pub(crate) system: TypeErased,
}