summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-04-05 23:06:49 +0200
committerHampusM <hampus@hampusmat.com>2024-04-06 12:52:54 +0200
commit3e6d04be56e910f77048442a3c744298ef856ca1 (patch)
treefd8e576411bcd1e8cda32d7cb2aaa2c7f36ae673
parent53baf6a6d35a904e1a38873271221af2e01f589c (diff)
feat(ecs): add event loop function to world
-rw-r--r--ecs/src/event.rs48
-rw-r--r--ecs/src/lib.rs44
2 files changed, 79 insertions, 13 deletions
diff --git a/ecs/src/event.rs b/ecs/src/event.rs
index 0cf6da7..01d9d80 100644
--- a/ecs/src/event.rs
+++ b/ecs/src/event.rs
@@ -2,6 +2,8 @@ use std::any::TypeId;
use std::fmt::Debug;
use std::hash::Hash;
+use seq_macro::seq;
+
pub trait Event: Debug + 'static
{
fn id(&self) -> Id;
@@ -22,3 +24,49 @@ impl Id
Self { inner: TypeId::of::<EventT>() }
}
}
+
+pub trait Ids
+{
+ type Iter<'a>: Iterator<Item = &'a Id>
+ where
+ Self: 'a;
+
+ fn iter(&self) -> Self::Iter<'_>;
+}
+
+/// A sequence of events.
+pub trait Sequence
+{
+ type Ids: Ids;
+
+ fn ids() -> Self::Ids;
+}
+
+macro_rules! impl_sequence {
+ ($c: tt) => {
+ seq!(I in 0..=$c {
+ impl Ids for [Id; $c + 1]
+ {
+ type Iter<'a> = std::slice::Iter<'a, Id>;
+
+ fn iter(&self) -> Self::Iter<'_> {
+ self.into_iter()
+ }
+ }
+
+ impl<#(Event~I: Event,)*> Sequence for (#(Event~I,)*) {
+ type Ids = [Id; $c + 1];
+
+ fn ids() -> Self::Ids {
+ [#(
+ Id::of::<Event~I>(),
+ )*]
+ }
+ }
+ });
+ };
+}
+
+seq!(C in 0..=64 {
+ impl_sequence!(C);
+});
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs
index 4d6e4e5..339a314 100644
--- a/ecs/src/lib.rs
+++ b/ecs/src/lib.rs
@@ -12,7 +12,7 @@ use std::vec::Drain;
use crate::actions::Action;
use crate::component::{Component, Sequence as ComponentSequence};
-use crate::event::{Event, Id as EventId};
+use crate::event::{Event, Id as EventId, Ids, Sequence as EventSequence};
use crate::lock::{Lock, ReadGuard};
use crate::system::{
NoInitParamFlag as NoInitSystemParamFlag,
@@ -110,18 +110,7 @@ impl World
/// Will panic if a system has dissapeared.
pub fn emit(&self, event: &impl Event)
{
- let Some(system_indices) = self.data.events.get(&event.id()).cloned() else {
- return;
- };
-
- for system_index in system_indices {
- let system = self.systems.get(system_index).unwrap();
-
- // SAFETY: The world data lives long enough
- unsafe {
- system.run(&self.data);
- }
- }
+ self.emit_event_by_id(event.id());
}
pub fn query<Comps>(&self) -> Query<Comps>
@@ -166,6 +155,35 @@ impl World
}
}
}
+
+ pub fn event_loop<EventSeq: EventSequence>(&self)
+ {
+ let event_seq = EventSeq::ids();
+
+ loop {
+ for event_id in event_seq.iter() {
+ self.emit_event_by_id(*event_id);
+ }
+
+ self.perform_queued_actions();
+ }
+ }
+
+ fn emit_event_by_id(&self, event_id: EventId)
+ {
+ let Some(system_indices) = self.data.events.get(&event_id) else {
+ return;
+ };
+
+ for system_index in system_indices {
+ let system = self.systems.get(*system_index).unwrap();
+
+ // SAFETY: The world data lives long enough
+ unsafe {
+ system.run(&self.data);
+ }
+ }
+ }
}
#[derive(Debug, Default)]