diff options
| author | HampusM <hampus@hampusmat.com> | 2024-03-06 00:45:51 +0100 | 
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2024-03-06 00:45:51 +0100 | 
| commit | b9668a6ba06af650eab5c77c78a487556af20a6b (patch) | |
| tree | e39087936c44344eff2b96bd872a9cb31848cc51 /ecs | |
| parent | dba19db5f649f73a5abb1bc3589580721a9a4e32 (diff) | |
feat(ecs): add queueing up spawning entities from systems
Diffstat (limited to 'ecs')
| -rw-r--r-- | ecs/src/actions.rs | 63 | ||||
| -rw-r--r-- | ecs/src/lib.rs | 18 | 
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)]  | 
