summaryrefslogtreecommitdiff
path: root/ecs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-03-06 00:45:51 +0100
committerHampusM <hampus@hampusmat.com>2024-03-06 00:45:51 +0100
commitb9668a6ba06af650eab5c77c78a487556af20a6b (patch)
treee39087936c44344eff2b96bd872a9cb31848cc51 /ecs
parentdba19db5f649f73a5abb1bc3589580721a9a4e32 (diff)
feat(ecs): add queueing up spawning entities from systems
Diffstat (limited to 'ecs')
-rw-r--r--ecs/src/actions.rs63
-rw-r--r--ecs/src/lib.rs18
2 files changed, 81 insertions, 0 deletions
diff --git a/ecs/src/actions.rs b/ecs/src/actions.rs
new file mode 100644
index 0000000..d67f895
--- /dev/null
+++ b/ecs/src/actions.rs
@@ -0,0 +1,63 @@
+use std::any::Any;
+
+use crate::component::{Component, Sequence as ComponentSequence};
+use crate::system::{NoInitParamFlag, Param as SystemParam, System};
+use crate::tuple::FilterExclude as TupleFilterExclude;
+use crate::WorldData;
+
+/// Used to to queue up actions for a [`World`] to perform.
+#[derive(Debug)]
+pub struct Actions<'world>
+{
+ world_data: &'world mut WorldData,
+}
+
+impl<'world> Actions<'world>
+{
+ /// Adds a spawning a new entity to the action queue.
+ pub fn spawn<Comps: ComponentSequence>(&mut self, components: Comps)
+ {
+ self.world_data
+ .action_queue
+ .push(Action::Spawn(components.into_vec()));
+ }
+}
+
+unsafe impl<'world> SystemParam<'world> for Actions<'world>
+{
+ type Flags = NoInitParamFlag;
+ type Input = TupleFilterExclude;
+
+ fn initialize<SystemImpl>(_system: &mut impl System<SystemImpl>, _input: Self::Input)
+ {
+ }
+
+ fn new<SystemImpl>(
+ _system: &'world mut impl System<SystemImpl>,
+ world_data: &'world mut WorldData,
+ ) -> Self
+ {
+ Self { world_data }
+ }
+
+ fn is_compatible<Other: SystemParam<'world>>() -> bool
+ {
+ let other_comparable = Other::get_comparable();
+
+ other_comparable.downcast_ref::<Comparable>().is_none()
+ }
+
+ fn get_comparable() -> Box<dyn Any>
+ {
+ Box::new(())
+ }
+}
+
+/// A action for a [`System`] to perform.
+#[derive(Debug)]
+pub enum Action
+{
+ Spawn(Vec<Box<dyn Component>>),
+}
+
+struct Comparable;
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs
index 0c06472..6b9373c 100644
--- a/ecs/src/lib.rs
+++ b/ecs/src/lib.rs
@@ -6,6 +6,7 @@ use std::fmt::Debug;
use std::marker::PhantomData;
use std::slice::{Iter as SliceIter, IterMut as SliceIterMut};
+use crate::actions::Action;
use crate::component::{Component, Sequence as ComponentSequence};
use crate::event::{Event, Id as EventId};
use crate::system::{
@@ -16,6 +17,7 @@ use crate::system::{
};
use crate::tuple::FilterExclude as TupleFilterExclude;
+pub mod actions;
pub mod component;
pub mod event;
pub mod system;
@@ -94,6 +96,21 @@ impl World
{
Query::new(&mut self.data)
}
+
+ /// Peforms the actions that have been queued up using [`Actions`].
+ pub fn perform_queued_actions(&mut self)
+ {
+ for action in self.data.action_queue.drain(..) {
+ match action {
+ Action::Spawn(components) => {
+ self.data
+ .component_storage
+ .entities
+ .push(Entity { components });
+ }
+ }
+ }
+ }
}
#[derive(Debug, Default)]
@@ -101,6 +118,7 @@ pub struct WorldData
{
events: HashMap<EventId, Vec<usize>>,
component_storage: ComponentStorage,
+ action_queue: Vec<Action>,
}
#[derive(Debug)]