From 7697f0336948694cc182b1f060e9bc558eac71cb Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Wed, 23 Dec 2020 21:54:33 +0100 Subject: [PATCH] Improved 'FlaggedStorage' --- space-crush-common/src/components/ship.rs | 4 +- .../src/misc/flagged_storage.rs | 119 +++++++++++++++--- space-crush-common/src/misc/mod.rs | 4 +- .../src/systems/fleet_owned_update.rs | 22 ++-- .../src/systems/orbit_owned_update.rs | 22 ++-- space-crush-common/src/systems/ships.rs | 25 ++-- 6 files changed, 130 insertions(+), 66 deletions(-) diff --git a/space-crush-common/src/components/ship.rs b/space-crush-common/src/components/ship.rs index 285303f..83eaca1 100644 --- a/space-crush-common/src/components/ship.rs +++ b/space-crush-common/src/components/ship.rs @@ -5,6 +5,8 @@ use glc::vector::Vector2f; use serde::{Deserialize, Serialize}; use specs::{Component, Entity, VecStorage}; +use crate::misc::FlaggedStorage; + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Ship { type_: Type, @@ -84,7 +86,7 @@ impl Ship { } impl Component for Ship { - type Storage = VecStorage; + type Storage = FlaggedStorage>; } impl Default for Obstacle { diff --git a/space-crush-common/src/misc/flagged_storage.rs b/space-crush-common/src/misc/flagged_storage.rs index 8593f86..4e4d6d5 100644 --- a/space-crush-common/src/misc/flagged_storage.rs +++ b/space-crush-common/src/misc/flagged_storage.rs @@ -1,59 +1,53 @@ #![allow(dead_code)] +use std::ops::{Deref, DerefMut}; + use hibitset::BitSetLike; -use shrev::EventChannel; +use shrev::{Event, EventChannel, ReaderId}; use specs::{ - storage::{TryDefault, UnprotectedStorage}, + storage::{DistinctStorage, MaskedStorage, Storage, TryDefault, UnprotectedStorage}, world::Index, Component, DenseVecStorage, }; +/* FlaggedStorage */ + pub struct FlaggedStorage> where - C: Send + Sync + 'static, + C: Event, { + event_emission: bool, channel: EventChannel>, storage: T, } pub enum ComponentEvent where - C: Send + Sync + 'static, + C: Event, { Inserted(Index, C), Modified(Index, C), Removed(Index, C), } -impl FlaggedStorage -where - C: Send + Sync + 'static, -{ - pub fn channel(&self) -> &EventChannel> { - &self.channel - } - - pub fn channel_mut(&mut self) -> &mut EventChannel> { - &mut self.channel - } -} - impl Default for FlaggedStorage where - C: Send + Sync + 'static, + C: Event, T: TryDefault, { fn default() -> Self { FlaggedStorage { + event_emission: true, channel: EventChannel::new(), storage: T::unwrap_default(), } } } -impl> UnprotectedStorage for FlaggedStorage +impl UnprotectedStorage for FlaggedStorage where - C: Send + Sync + 'static, + C: Component + Event + Clone, + T: UnprotectedStorage, { unsafe fn clean(&mut self, has: B) where @@ -91,3 +85,88 @@ where component } } + +unsafe impl DistinctStorage for FlaggedStorage +where + C: Component + Event + Clone, + T: DistinctStorage, +{ +} + +/* Tracked */ + +pub trait Tracked { + fn channel(&self) -> &EventChannel>; + fn channel_mut(&mut self) -> &mut EventChannel>; + + fn event_emission(&self) -> bool; + fn set_event_emission(&mut self, value: bool); +} + +impl Tracked for FlaggedStorage +where + C: Component + Event, +{ + fn channel(&self) -> &EventChannel> { + &self.channel + } + + fn channel_mut(&mut self) -> &mut EventChannel> { + &mut self.channel + } + + fn event_emission(&self) -> bool { + self.event_emission + } + + fn set_event_emission(&mut self, value: bool) { + self.event_emission = value; + } +} + +/* StorageHelper */ + +pub trait StorageHelper { + fn event_emission(&self) -> bool; + fn channel(&self) -> &EventChannel>; +} + +pub trait StorageHelperMut { + fn set_event_emission(&mut self, value: bool); + fn channel_mut(&mut self) -> &mut EventChannel>; + fn register_event_reader(&mut self) -> ReaderId>; +} + +impl<'e, T, D> StorageHelper for Storage<'e, T, D> +where + T: Component + Event, + T::Storage: Tracked, + D: Deref>, +{ + fn event_emission(&self) -> bool { + self.unprotected_storage().event_emission() + } + + fn channel(&self) -> &EventChannel> { + self.unprotected_storage().channel() + } +} + +impl<'e, T, D> StorageHelperMut for Storage<'e, T, D> +where + T: Component + Event, + T::Storage: Tracked, + D: DerefMut>, +{ + fn set_event_emission(&mut self, value: bool) { + unsafe { self.unprotected_storage_mut().set_event_emission(value) }; + } + + fn channel_mut(&mut self) -> &mut EventChannel> { + unsafe { self.unprotected_storage_mut().channel_mut() } + } + + fn register_event_reader(&mut self) -> ReaderId> { + self.channel_mut().register_reader() + } +} diff --git a/space-crush-common/src/misc/mod.rs b/space-crush-common/src/misc/mod.rs index 0b596ac..7898d40 100644 --- a/space-crush-common/src/misc/mod.rs +++ b/space-crush-common/src/misc/mod.rs @@ -7,7 +7,9 @@ mod world; pub use self::log::init as init_logger; pub use self::vfs::{Vfs, VfsError}; -pub use flagged_storage::{ComponentEvent, FlaggedStorage}; +pub use flagged_storage::{ + ComponentEvent, FlaggedStorage, StorageHelper, StorageHelperMut, Tracked, +}; pub use log_result::LogResult; pub use persistence::{PersistWorld, Persistence}; pub use world::WorldHelper; diff --git a/space-crush-common/src/systems/fleet_owned_update.rs b/space-crush-common/src/systems/fleet_owned_update.rs index 065ec7c..ff607ba 100644 --- a/space-crush-common/src/systems/fleet_owned_update.rs +++ b/space-crush-common/src/systems/fleet_owned_update.rs @@ -5,7 +5,7 @@ use specs::{prelude::*, world::Index, Entities, ReadStorage, System, World, Writ use crate::{ components::{Fleet, FleetOwned, Ship}, - misc::ComponentEvent, + misc::{ComponentEvent, StorageHelper, StorageHelperMut}, }; pub struct FleetOwnedUpdate { @@ -17,19 +17,14 @@ pub struct FleetOwnedUpdate { impl FleetOwnedUpdate { pub fn new(world: &mut World) -> Self { + WriteStorage::::setup(world); + let fleet_ids = BitSet::new(); let fleet_owned_ids = BitSet::new(); let old_fleet_ids = HashMap::new(); - - let fleet_owned_event_id = unsafe { - WriteStorage::::setup(world); - - let mut fleet_owned = world.system_data::>(); - fleet_owned - .unprotected_storage_mut() - .channel_mut() - .register_reader() - }; + let fleet_owned_event_id = world + .system_data::>() + .register_event_reader(); Self { fleet_ids, @@ -64,10 +59,7 @@ impl<'a> System<'a> for FleetOwnedUpdate { self.old_fleet_ids.clear(); /* handle events */ - let events = fleet_owned - .unprotected_storage() - .channel() - .read(&mut self.fleet_owned_event_id); + let events = fleet_owned.channel().read(&mut self.fleet_owned_event_id); for event in events { match event { ComponentEvent::Inserted(id, fleet_owned) => { diff --git a/space-crush-common/src/systems/orbit_owned_update.rs b/space-crush-common/src/systems/orbit_owned_update.rs index b14610f..9555a9e 100644 --- a/space-crush-common/src/systems/orbit_owned_update.rs +++ b/space-crush-common/src/systems/orbit_owned_update.rs @@ -8,7 +8,7 @@ use specs::{ use crate::{ components::{Orbit, OrbitOwned, PlayerOwned}, - misc::ComponentEvent, + misc::{ComponentEvent, StorageHelper, StorageHelperMut}, }; pub struct OrbitOwnedUpdate { @@ -20,19 +20,14 @@ pub struct OrbitOwnedUpdate { impl OrbitOwnedUpdate { pub fn new(world: &mut World) -> Self { + WriteStorage::::setup(world); + let orbit_ids = BitSet::new(); let orbit_owned_ids = BitSet::new(); let old_orbit_ids = HashMap::new(); - - let orbit_owned_event_id = unsafe { - WriteStorage::::setup(world); - - let mut orbit_owned = world.system_data::>(); - orbit_owned - .unprotected_storage_mut() - .channel_mut() - .register_reader() - }; + let orbit_owned_event_id = world + .system_data::>() + .register_event_reader(); Self { orbit_ids, @@ -67,10 +62,7 @@ impl<'a> System<'a> for OrbitOwnedUpdate { self.old_orbit_ids.clear(); /* handle events */ - let events = orbit_owned - .unprotected_storage() - .channel() - .read(&mut self.orbit_owned_event_id); + let events = orbit_owned.channel().read(&mut self.orbit_owned_event_id); for event in events { match event { ComponentEvent::Inserted(id, orbit_owned) => { diff --git a/space-crush-common/src/systems/ships.rs b/space-crush-common/src/systems/ships.rs index f64103c..98430c8 100644 --- a/space-crush-common/src/systems/ships.rs +++ b/space-crush-common/src/systems/ships.rs @@ -16,7 +16,7 @@ use crate::{ SHIP_ORBIT_AGILITY, SHIP_ORBIT_ANGLE_DELTA_MIN, SHIP_ORBIT_ANGLE_DELTA_RND, SHIP_ORBIT_DISTANCE_MAX, VECTOR_2F_POS_X, }, - misc::ComponentEvent, + misc::{ComponentEvent, StorageHelper, StorageHelperMut}, resources::Global, return_if_none, }; @@ -51,16 +51,12 @@ struct Processor<'a> { impl Ships { pub fn new(world: &mut World) -> Self { + WriteStorage::::setup(world); + let need_update = BitSet::new(); - let fleet_owned_id = unsafe { - WriteStorage::::setup(world); - - let mut fleet_owned = world.system_data::>(); - fleet_owned - .unprotected_storage_mut() - .channel_mut() - .register_reader() - }; + let fleet_owned_id = world + .system_data::>() + .register_event_reader(); Self { need_update, @@ -70,10 +66,7 @@ impl Ships { fn progress_events(&mut self, fleet_owned: &ReadStorage<'_, FleetOwned>) { self.need_update.clear(); - let events = fleet_owned - .unprotected_storage() - .channel() - .read(&mut self.fleet_owned_id); + let events = fleet_owned.channel().read(&mut self.fleet_owned_id); for event in events { let id = match event { ComponentEvent::Inserted(id, _) => id, @@ -115,6 +108,8 @@ impl<'a> System<'a> for Ships { delta: global.delta * global.world_speed, }; + ships.set_event_emission(false); + let data = ( positions.mask(), &mut ships, @@ -127,6 +122,8 @@ impl<'a> System<'a> for Ships { .for_each(|(id, ship, velocity, position, fleet_owned)| { processor.progress_ship(id, ship, velocity, position, fleet_owned); }); + + ships.set_event_emission(true); } }