Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
AThilenius committed Sep 6, 2019
2 parents 8da3ede + 48fa4f0 commit de5cb0b
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 11 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ nightly = ["shred/nightly"]
uuid_entity = ["uuid", "serde"]
stdweb = ["uuid/stdweb"]
wasm-bindgen = ["uuid/wasm-bindgen"]
storage-event-control = []

shred-derive = ["shred/shred-derive"]

[package.metadata.docs.rs]
features = ["parallel", "serde", "shred-derive", "specs-derive", "nightly", "uuid_entity"]
features = ["parallel", "serde", "shred-derive", "specs-derive", "nightly", "uuid_entity", "storage-event-control"]

[dev-dependencies]
nalgebra = "0.18"
Expand Down
13 changes: 12 additions & 1 deletion docs/tutorials/src/12_tracked.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@ for (entity, mut comp) in (&entities, &mut comps.restrict_mut()).join() {
}
```

## Start and Stop event emission

Sometimes you may want to perform some operations on the storage, but you don't
want that these operations produce any event.

You can use the function `storage.set_event_emission(false)` to suppress the
event writing for of any action. When you want to re activate them you can
simply call `storage.set_event_emission(true)`.

---

_See
[FlaggedStorage Doc](https://docs.rs/specs/latest/specs/struct.FlaggedStorage.html)
for more into._
for more into._
80 changes: 71 additions & 9 deletions src/storage/flagged.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,20 +125,65 @@ use shrev::EventChannel;
/// //
/// // Otherwise you won't receive any of the modifications until
/// // you start tracking them.
/// let mut comps = world.write_storage::<Comp>();
/// let comp_system = CompSystem {
/// reader_id: comps.register_reader(),
/// modified: BitSet::new(),
/// inserted: BitSet::new(),
/// let mut comp_system = {
/// let mut comps = world.write_storage::<Comp>();
/// CompSystem {
/// reader_id: comps.register_reader(),
/// modified: BitSet::new(),
/// inserted: BitSet::new(),
/// }
/// };
///
/// world.create_entity().with(Comp(19u32)).build();
///
/// {
/// let mut comps = world.write_storage::<Comp>();
/// let events = comps.channel().read(&mut comp_system.reader_id);
/// assert_eq!(events.len(), 1);
/// }
///
/// #[cfg(feature = "storage-event-control")]
/// {
/// world.write_storage::<Comp>().set_event_emission(false);
/// world.create_entity().with(Comp(19u32)).build();
///
/// {
/// let mut comps = world.write_storage::<Comp>();
/// let events = comps.channel().read(&mut comp_system.reader_id);
/// assert_eq!(events.len(), 0);
/// }
///
/// world.write_storage::<Comp>().set_event_emission(true);
/// world.create_entity().with(Comp(19u32)).build();
///
/// {
/// let mut comps = world.write_storage::<Comp>();
/// let events = comps.channel().read(&mut comp_system.reader_id);
/// assert_eq!(events.len(), 1);
/// }
/// }
/// }
/// ```
pub struct FlaggedStorage<C, T = DenseVecStorage<C>> {
channel: EventChannel<ComponentEvent>,
storage: T,
#[cfg(feature = "storage-event-control")]
event_emission: bool,
phantom: PhantomData<C>,
}

impl<C, T> FlaggedStorage<C, T> {
#[cfg(feature = "storage-event-control")]
fn emit_event(&self) -> bool {
self.event_emission
}

#[cfg(not(feature = "storage-event-control"))]
fn emit_event(&self) -> bool {
true
}
}

impl<C, T> Default for FlaggedStorage<C, T>
where
T: TryDefault,
Expand All @@ -147,6 +192,8 @@ where
FlaggedStorage {
channel: EventChannel::<ComponentEvent>::default(),
storage: T::unwrap_default(),
#[cfg(feature = "storage-event-control")]
event_emission: true,
phantom: PhantomData,
}
}
Expand All @@ -165,18 +212,23 @@ impl<C: Component, T: UnprotectedStorage<C>> UnprotectedStorage<C> for FlaggedSt
}

unsafe fn get_mut(&mut self, id: Index) -> &mut C {
// calling `.iter()` on an unconstrained mutable storage will flag everything
self.channel.single_write(ComponentEvent::Modified(id));
if self.emit_event() {
self.channel.single_write(ComponentEvent::Modified(id));
}
self.storage.get_mut(id)
}

unsafe fn insert(&mut self, id: Index, comp: C) {
self.channel.single_write(ComponentEvent::Inserted(id));
if self.emit_event() {
self.channel.single_write(ComponentEvent::Inserted(id));
}
self.storage.insert(id, comp);
}

unsafe fn remove(&mut self, id: Index) -> C {
self.channel.single_write(ComponentEvent::Removed(id));
if self.emit_event() {
self.channel.single_write(ComponentEvent::Removed(id));
}
self.storage.remove(id)
}
}
Expand All @@ -189,4 +241,14 @@ impl<C, T> Tracked for FlaggedStorage<C, T> {
fn channel_mut(&mut self) -> &mut EventChannel<ComponentEvent> {
&mut self.channel
}

#[cfg(feature = "storage-event-control")]
fn set_event_emission(&mut self, emit: bool) {
self.event_emission = emit;
}

#[cfg(feature = "storage-event-control")]
fn event_emission(&self) -> bool {
self.event_emission
}
}
24 changes: 24 additions & 0 deletions src/storage/track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ pub trait Tracked {
fn channel(&self) -> &EventChannel<ComponentEvent>;
/// Mutable event channel tracking modified/inserted/removed components.
fn channel_mut(&mut self) -> &mut EventChannel<ComponentEvent>;

/// Controls the events signal emission.
/// When this is set to false the events modified/inserted/removed are
/// not emitted.
#[cfg(feature = "storage-event-control")]
fn set_event_emission(&mut self, emit: bool);

/// Returns the actual state of the event emission.
#[cfg(feature = "storage-event-control")]
fn event_emission(&self) -> bool;
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -42,6 +52,12 @@ where
pub fn channel(&self) -> &EventChannel<ComponentEvent> {
unsafe { self.open() }.1.channel()
}

/// Returns the actual state of the event emission.
#[cfg(feature = "storage-event-control")]
pub fn event_emission(&self) -> bool {
unsafe { self.open() }.1.event_emission()
}
}

impl<'e, T, D> Storage<'e, T, D>
Expand All @@ -67,4 +83,12 @@ where
pub fn flag(&mut self, event: ComponentEvent) {
self.channel_mut().single_write(event);
}

/// Controls the events signal emission.
/// When this is set to false the events modified/inserted/removed are
/// not emitted.
#[cfg(feature = "storage-event-control")]
pub fn set_event_emission(&mut self, emit: bool) {
unsafe { self.open() }.1.set_event_emission(emit);
}
}

0 comments on commit de5cb0b

Please sign in to comment.