Skip to content

Commit

Permalink
feat: allow access to storage in event subscription
Browse files Browse the repository at this point in the history
  • Loading branch information
ten3roberts committed Oct 29, 2023
1 parent c803a34 commit 77b072a
Show file tree
Hide file tree
Showing 9 changed files with 331 additions and 161 deletions.
2 changes: 1 addition & 1 deletion asteroids/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ async fn main() -> Result<()> {
world.subscribe(
player_dead_tx
.filter_components([player().key()])
.filter(|v| v.kind == EventKind::Removed),
.filter(|v, _| v == EventKind::Removed),
);

// Setup everything required for the game logic and physics
Expand Down
22 changes: 5 additions & 17 deletions src/archetype/guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,11 @@ impl<'a, T: Debug + ?Sized> Debug for CellGuard<'a, T> {

/// A mutable reference to an entity's component with deferred change tracking.
///
/// A modification invent is only generated *if* if this is mutably dereferenced.
/// A modification invent is only generated *iff* this is mutably dereferenced.
pub struct RefMut<'a, T> {
guard: CellMutGuard<'a, T>,

id: Entity,
slot: Slot,
modified: bool,
tick: u32,
}

Expand All @@ -138,7 +136,6 @@ impl<'a, T: ComponentValue> RefMut<'a, T> {
guard,
id,
slot,
modified: false,
tick,
})
}
Expand All @@ -162,19 +159,10 @@ impl<'a, T> Deref for RefMut<'a, T> {
impl<'a, T> DerefMut for RefMut<'a, T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.modified = true;
self.guard.get_mut()
}
}
self.guard
.data
.set_modified(&[self.id], Slice::single(self.slot), self.tick);

impl<'a, T> Drop for RefMut<'a, T> {
#[inline]
fn drop(&mut self) {
if self.modified {
// SAFETY: `value` is not accessed beyond this point
self.guard
.data
.set_modified(&[self.id], Slice::single(self.slot), self.tick)
}
self.guard.get_mut()
}
}
89 changes: 39 additions & 50 deletions src/archetype/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use itertools::Itertools;

use crate::{
component::{ComponentDesc, ComponentKey, ComponentValue},
events::{EventData, EventKind, EventSubscriber},
events::{EventData, EventSubscriber},
writer::ComponentUpdater,
Component, Entity,
};
Expand Down Expand Up @@ -97,30 +97,48 @@ pub(crate) struct CellData {
impl CellData {
/// Sets the specified entities and slots as modified and invokes subscribers
/// **Note**: `ids` must be the slice of entities pointed to by `slice`
pub(crate) fn set_modified(&mut self, ids: &[Entity], slice: Slice, change_tick: u32) {
debug_assert_eq!(ids.len(), slice.len());
let component = self.key;
self.on_event(EventData {
pub(crate) fn set_modified(&mut self, ids: &[Entity], slots: Slice, change_tick: u32) {
debug_assert_eq!(ids.len(), slots.len());
let event = EventData {
ids,
key: component,
kind: EventKind::Modified,
});
slots,
key: self.key,
};

for handler in self.subscribers.iter() {
handler.on_modified(&event)
}

self.changes
.set_modified_if_tracking(Change::new(slice, change_tick));
.set_modified_if_tracking(Change::new(slots, change_tick));
}

/// Sets the specified entities and slots as modified and invokes subscribers
/// **Note**: `ids` must be the slice of entities pointed to by `slice`
pub(crate) fn set_added(&mut self, ids: &[Entity], slice: Slice, change_tick: u32) {
let component = self.key;
self.on_event(EventData {
pub(crate) fn set_added(&mut self, ids: &[Entity], slots: Slice, change_tick: u32) {
let event = EventData {
ids,
key: component,
kind: EventKind::Added,
});
slots,
key: self.key,
};

self.changes.set_added(Change::new(slice, change_tick));
for handler in self.subscribers.iter() {
handler.on_added(&self.storage, &event);
}

self.changes.set_added(Change::new(slots, change_tick));
}

pub(crate) fn set_removed(&mut self, ids: &[Entity], slots: Slice) {
let event = EventData {
ids,
slots,
key: self.key,
};

for handler in self.subscribers.iter() {
handler.on_removed(&self.storage, &event);
}
}
}

Expand Down Expand Up @@ -280,15 +298,6 @@ pub struct Archetype {
unsafe impl Send for Cell {}
unsafe impl Sync for Cell {}

impl CellData {
#[inline]
fn on_event(&self, event: EventData) {
for handler in self.subscribers.iter() {
handler.on_event(&event)
}
}
}

impl Archetype {
pub(crate) fn empty() -> Self {
Self {
Expand Down Expand Up @@ -660,11 +669,7 @@ impl Archetype {
cell.move_to(slot, dst_cell, dst_slot);
} else {
// Notify the subscribers that the component was removed
data.on_event(EventData {
ids: &[id],
key,
kind: EventKind::Removed,
});
data.set_removed(&[id], Slice::single(slot));

cell.take(slot, &mut on_drop);
}
Expand Down Expand Up @@ -697,11 +702,7 @@ impl Archetype {
for cell in self.cells.values_mut() {
let data = cell.data.get_mut();
// data.on_event(&self.entities, Slice::single(slot), EventKind::Removed);
data.on_event(EventData {
ids: &[id],
key: data.key,
kind: EventKind::Removed,
});
data.set_removed(&[id], Slice::single(slot));

cell.take(slot, &mut on_move)
}
Expand Down Expand Up @@ -769,11 +770,7 @@ impl Archetype {
// unsafe { dst.storage.get_mut().append(storage) }
} else {
// Notify the subscribers that the component was removed
data.on_event(EventData {
ids: &entities[slots.as_range()],
key: data.key,
kind: EventKind::Removed,
});
data.set_removed(&entities[slots.as_range()], slots);

cell.clear();
}
Expand Down Expand Up @@ -806,11 +803,7 @@ impl Archetype {
let data = cell.data.get_mut();
// Notify the subscribers that the component was removed
// data.on_event(&self.entities, slots, EventKind::Removed);
data.on_event(EventData {
ids: &self.entities[slots.as_range()],
key: data.key,
kind: EventKind::Removed,
});
data.set_removed(&self.entities[slots.as_range()], slots);

cell.clear()
}
Expand Down Expand Up @@ -859,11 +852,7 @@ impl Archetype {
let slots = self.slots();
for cell in self.cells.values_mut() {
let data = cell.data.get_mut();
data.on_event(EventData {
ids: &self.entities[slots.as_range()],
key: data.key,
kind: EventKind::Removed,
})
data.set_removed(&self.entities[slots.as_range()], slots)
}

ArchetypeDrain {
Expand Down
Loading

0 comments on commit 77b072a

Please sign in to comment.