Skip to content

Commit

Permalink
feat: FilterRelations subscriber
Browse files Browse the repository at this point in the history
  • Loading branch information
ten3roberts committed Oct 8, 2024
1 parent c2b528a commit 29c8219
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
archetype::{Archetype, Slice, Storage},
component::{ComponentDesc, ComponentKey, ComponentValue},
filter::StaticFilter,
relation::Relation,
sink::Sink,
Component, Entity,
};
Expand Down Expand Up @@ -129,6 +130,16 @@ pub trait EventSubscriber: ComponentValue {
}
}

/// Filter a subscriber to only receive events for a specific set of components
fn filter_relations<I: IntoIterator<Item = Entity>>(self, relations: I) -> FilterRelations<Self>
where
Self: Sized,
{
FilterRelations {
relations: relations.into_iter().collect(),
subscriber: self,
}
}
/// Filter a subscriber to only receive events of a specific kind
fn filter_event_kind(self, event_kind: EventKind) -> FilterEventKind<Self>
where
Expand Down Expand Up @@ -371,6 +382,49 @@ where
}
}

/// Filter a subscriber to only receive events for a specific set of relations
pub struct FilterRelations<S> {
relations: Vec<Entity>,
subscriber: S,
}

impl<S> EventSubscriber for FilterRelations<S>
where
S: EventSubscriber,
{
fn on_added(&self, storage: &Storage, event: &EventData) {
self.subscriber.on_added(storage, event)
}

fn on_modified(&self, event: &EventData) {
self.subscriber.on_modified(event)
}

fn on_removed(&self, storage: &Storage, event: &EventData) {
self.subscriber.on_removed(storage, event)
}

#[inline]
fn matches_arch(&self, arch: &Archetype) -> bool {
self.relations
.iter()
.any(|&key| arch.relations_like(key).any(|_| true))
&& self.subscriber.matches_arch(arch)
}

#[inline]
fn matches_component(&self, desc: ComponentDesc) -> bool {
desc.key.is_relation()
&& self.relations.contains(&desc.key.id())
&& self.subscriber.matches_component(desc)
}

#[inline]
fn is_connected(&self) -> bool {
self.subscriber.is_connected()
}
}

/// Filter a subscriber to only receive events of a specific kind
pub struct FilterEventKind<S> {
event_kind: EventKind,
Expand Down

0 comments on commit 29c8219

Please sign in to comment.