Browse Source

Improved 'FlaggedStorage'

master
Bergmann89 4 years ago
parent
commit
7697f03369
6 changed files with 130 additions and 66 deletions
  1. +3
    -1
      space-crush-common/src/components/ship.rs
  2. +99
    -20
      space-crush-common/src/misc/flagged_storage.rs
  3. +3
    -1
      space-crush-common/src/misc/mod.rs
  4. +7
    -15
      space-crush-common/src/systems/fleet_owned_update.rs
  5. +7
    -15
      space-crush-common/src/systems/orbit_owned_update.rs
  6. +11
    -14
      space-crush-common/src/systems/ships.rs

+ 3
- 1
space-crush-common/src/components/ship.rs View File

@@ -5,6 +5,8 @@ use glc::vector::Vector2f;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use specs::{Component, Entity, VecStorage}; use specs::{Component, Entity, VecStorage};


use crate::misc::FlaggedStorage;

#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Ship { pub struct Ship {
type_: Type, type_: Type,
@@ -84,7 +86,7 @@ impl Ship {
} }


impl Component for Ship { impl Component for Ship {
type Storage = VecStorage<Self>;
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
} }


impl Default for Obstacle { impl Default for Obstacle {


+ 99
- 20
space-crush-common/src/misc/flagged_storage.rs View File

@@ -1,59 +1,53 @@
#![allow(dead_code)] #![allow(dead_code)]


use std::ops::{Deref, DerefMut};

use hibitset::BitSetLike; use hibitset::BitSetLike;
use shrev::EventChannel;
use shrev::{Event, EventChannel, ReaderId};
use specs::{ use specs::{
storage::{TryDefault, UnprotectedStorage},
storage::{DistinctStorage, MaskedStorage, Storage, TryDefault, UnprotectedStorage},
world::Index, world::Index,
Component, DenseVecStorage, Component, DenseVecStorage,
}; };


/* FlaggedStorage */

pub struct FlaggedStorage<C, T = DenseVecStorage<C>> pub struct FlaggedStorage<C, T = DenseVecStorage<C>>
where where
C: Send + Sync + 'static,
C: Event,
{ {
event_emission: bool,
channel: EventChannel<ComponentEvent<C>>, channel: EventChannel<ComponentEvent<C>>,
storage: T, storage: T,
} }


pub enum ComponentEvent<C> pub enum ComponentEvent<C>
where where
C: Send + Sync + 'static,
C: Event,
{ {
Inserted(Index, C), Inserted(Index, C),
Modified(Index, C), Modified(Index, C),
Removed(Index, C), Removed(Index, C),
} }


impl<C, T> FlaggedStorage<C, T>
where
C: Send + Sync + 'static,
{
pub fn channel(&self) -> &EventChannel<ComponentEvent<C>> {
&self.channel
}

pub fn channel_mut(&mut self) -> &mut EventChannel<ComponentEvent<C>> {
&mut self.channel
}
}

impl<C, T> Default for FlaggedStorage<C, T> impl<C, T> Default for FlaggedStorage<C, T>
where where
C: Send + Sync + 'static,
C: Event,
T: TryDefault, T: TryDefault,
{ {
fn default() -> Self { fn default() -> Self {
FlaggedStorage { FlaggedStorage {
event_emission: true,
channel: EventChannel::new(), channel: EventChannel::new(),
storage: T::unwrap_default(), storage: T::unwrap_default(),
} }
} }
} }


impl<C: Component + Clone, T: UnprotectedStorage<C>> UnprotectedStorage<C> for FlaggedStorage<C, T>
impl<C, T> UnprotectedStorage<C> for FlaggedStorage<C, T>
where where
C: Send + Sync + 'static,
C: Component + Event + Clone,
T: UnprotectedStorage<C>,
{ {
unsafe fn clean<B>(&mut self, has: B) unsafe fn clean<B>(&mut self, has: B)
where where
@@ -91,3 +85,88 @@ where
component component
} }
} }

unsafe impl<C, T> DistinctStorage for FlaggedStorage<C, T>
where
C: Component + Event + Clone,
T: DistinctStorage,
{
}

/* Tracked */

pub trait Tracked<C: Event> {
fn channel(&self) -> &EventChannel<ComponentEvent<C>>;
fn channel_mut(&mut self) -> &mut EventChannel<ComponentEvent<C>>;

fn event_emission(&self) -> bool;
fn set_event_emission(&mut self, value: bool);
}

impl<C, T> Tracked<C> for FlaggedStorage<C, T>
where
C: Component + Event,
{
fn channel(&self) -> &EventChannel<ComponentEvent<C>> {
&self.channel
}

fn channel_mut(&mut self) -> &mut EventChannel<ComponentEvent<C>> {
&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<C: Event> {
fn event_emission(&self) -> bool;
fn channel(&self) -> &EventChannel<ComponentEvent<C>>;
}

pub trait StorageHelperMut<C: Event> {
fn set_event_emission(&mut self, value: bool);
fn channel_mut(&mut self) -> &mut EventChannel<ComponentEvent<C>>;
fn register_event_reader(&mut self) -> ReaderId<ComponentEvent<C>>;
}

impl<'e, T, D> StorageHelper<T> for Storage<'e, T, D>
where
T: Component + Event,
T::Storage: Tracked<T>,
D: Deref<Target = MaskedStorage<T>>,
{
fn event_emission(&self) -> bool {
self.unprotected_storage().event_emission()
}

fn channel(&self) -> &EventChannel<ComponentEvent<T>> {
self.unprotected_storage().channel()
}
}

impl<'e, T, D> StorageHelperMut<T> for Storage<'e, T, D>
where
T: Component + Event,
T::Storage: Tracked<T>,
D: DerefMut<Target = MaskedStorage<T>>,
{
fn set_event_emission(&mut self, value: bool) {
unsafe { self.unprotected_storage_mut().set_event_emission(value) };
}

fn channel_mut(&mut self) -> &mut EventChannel<ComponentEvent<T>> {
unsafe { self.unprotected_storage_mut().channel_mut() }
}

fn register_event_reader(&mut self) -> ReaderId<ComponentEvent<T>> {
self.channel_mut().register_reader()
}
}

+ 3
- 1
space-crush-common/src/misc/mod.rs View File

@@ -7,7 +7,9 @@ mod world;


pub use self::log::init as init_logger; pub use self::log::init as init_logger;
pub use self::vfs::{Vfs, VfsError}; 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 log_result::LogResult;
pub use persistence::{PersistWorld, Persistence}; pub use persistence::{PersistWorld, Persistence};
pub use world::WorldHelper; pub use world::WorldHelper;

+ 7
- 15
space-crush-common/src/systems/fleet_owned_update.rs View File

@@ -5,7 +5,7 @@ use specs::{prelude::*, world::Index, Entities, ReadStorage, System, World, Writ


use crate::{ use crate::{
components::{Fleet, FleetOwned, Ship}, components::{Fleet, FleetOwned, Ship},
misc::ComponentEvent,
misc::{ComponentEvent, StorageHelper, StorageHelperMut},
}; };


pub struct FleetOwnedUpdate { pub struct FleetOwnedUpdate {
@@ -17,19 +17,14 @@ pub struct FleetOwnedUpdate {


impl FleetOwnedUpdate { impl FleetOwnedUpdate {
pub fn new(world: &mut World) -> Self { pub fn new(world: &mut World) -> Self {
WriteStorage::<FleetOwned>::setup(world);

let fleet_ids = BitSet::new(); let fleet_ids = BitSet::new();
let fleet_owned_ids = BitSet::new(); let fleet_owned_ids = BitSet::new();
let old_fleet_ids = HashMap::new(); let old_fleet_ids = HashMap::new();

let fleet_owned_event_id = unsafe {
WriteStorage::<FleetOwned>::setup(world);

let mut fleet_owned = world.system_data::<WriteStorage<FleetOwned>>();
fleet_owned
.unprotected_storage_mut()
.channel_mut()
.register_reader()
};
let fleet_owned_event_id = world
.system_data::<WriteStorage<FleetOwned>>()
.register_event_reader();


Self { Self {
fleet_ids, fleet_ids,
@@ -64,10 +59,7 @@ impl<'a> System<'a> for FleetOwnedUpdate {
self.old_fleet_ids.clear(); self.old_fleet_ids.clear();


/* handle events */ /* 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 { for event in events {
match event { match event {
ComponentEvent::Inserted(id, fleet_owned) => { ComponentEvent::Inserted(id, fleet_owned) => {


+ 7
- 15
space-crush-common/src/systems/orbit_owned_update.rs View File

@@ -8,7 +8,7 @@ use specs::{


use crate::{ use crate::{
components::{Orbit, OrbitOwned, PlayerOwned}, components::{Orbit, OrbitOwned, PlayerOwned},
misc::ComponentEvent,
misc::{ComponentEvent, StorageHelper, StorageHelperMut},
}; };


pub struct OrbitOwnedUpdate { pub struct OrbitOwnedUpdate {
@@ -20,19 +20,14 @@ pub struct OrbitOwnedUpdate {


impl OrbitOwnedUpdate { impl OrbitOwnedUpdate {
pub fn new(world: &mut World) -> Self { pub fn new(world: &mut World) -> Self {
WriteStorage::<OrbitOwned>::setup(world);

let orbit_ids = BitSet::new(); let orbit_ids = BitSet::new();
let orbit_owned_ids = BitSet::new(); let orbit_owned_ids = BitSet::new();
let old_orbit_ids = HashMap::new(); let old_orbit_ids = HashMap::new();

let orbit_owned_event_id = unsafe {
WriteStorage::<OrbitOwned>::setup(world);

let mut orbit_owned = world.system_data::<WriteStorage<OrbitOwned>>();
orbit_owned
.unprotected_storage_mut()
.channel_mut()
.register_reader()
};
let orbit_owned_event_id = world
.system_data::<WriteStorage<OrbitOwned>>()
.register_event_reader();


Self { Self {
orbit_ids, orbit_ids,
@@ -67,10 +62,7 @@ impl<'a> System<'a> for OrbitOwnedUpdate {
self.old_orbit_ids.clear(); self.old_orbit_ids.clear();


/* handle events */ /* 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 { for event in events {
match event { match event {
ComponentEvent::Inserted(id, orbit_owned) => { ComponentEvent::Inserted(id, orbit_owned) => {


+ 11
- 14
space-crush-common/src/systems/ships.rs View File

@@ -16,7 +16,7 @@ use crate::{
SHIP_ORBIT_AGILITY, SHIP_ORBIT_ANGLE_DELTA_MIN, SHIP_ORBIT_ANGLE_DELTA_RND, SHIP_ORBIT_AGILITY, SHIP_ORBIT_ANGLE_DELTA_MIN, SHIP_ORBIT_ANGLE_DELTA_RND,
SHIP_ORBIT_DISTANCE_MAX, VECTOR_2F_POS_X, SHIP_ORBIT_DISTANCE_MAX, VECTOR_2F_POS_X,
}, },
misc::ComponentEvent,
misc::{ComponentEvent, StorageHelper, StorageHelperMut},
resources::Global, resources::Global,
return_if_none, return_if_none,
}; };
@@ -51,16 +51,12 @@ struct Processor<'a> {


impl Ships { impl Ships {
pub fn new(world: &mut World) -> Self { pub fn new(world: &mut World) -> Self {
WriteStorage::<FleetOwned>::setup(world);

let need_update = BitSet::new(); let need_update = BitSet::new();
let fleet_owned_id = unsafe {
WriteStorage::<FleetOwned>::setup(world);

let mut fleet_owned = world.system_data::<WriteStorage<FleetOwned>>();
fleet_owned
.unprotected_storage_mut()
.channel_mut()
.register_reader()
};
let fleet_owned_id = world
.system_data::<WriteStorage<FleetOwned>>()
.register_event_reader();


Self { Self {
need_update, need_update,
@@ -70,10 +66,7 @@ impl Ships {


fn progress_events(&mut self, fleet_owned: &ReadStorage<'_, FleetOwned>) { fn progress_events(&mut self, fleet_owned: &ReadStorage<'_, FleetOwned>) {
self.need_update.clear(); 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 { for event in events {
let id = match event { let id = match event {
ComponentEvent::Inserted(id, _) => id, ComponentEvent::Inserted(id, _) => id,
@@ -115,6 +108,8 @@ impl<'a> System<'a> for Ships {
delta: global.delta * global.world_speed, delta: global.delta * global.world_speed,
}; };


ships.set_event_emission(false);

let data = ( let data = (
positions.mask(), positions.mask(),
&mut ships, &mut ships,
@@ -127,6 +122,8 @@ impl<'a> System<'a> for Ships {
.for_each(|(id, ship, velocity, position, fleet_owned)| { .for_each(|(id, ship, velocity, position, fleet_owned)| {
processor.progress_ship(id, ship, velocity, position, fleet_owned); processor.progress_ship(id, ship, velocity, position, fleet_owned);
}); });

ships.set_event_emission(true);
} }
} }




Loading…
Cancel
Save