Просмотр исходного кода

Improved 'FlaggedStorage'

master
Bergmann89 4 лет назад
Родитель
Сommit
7697f03369
6 измененных файлов: 130 добавлений и 66 удалений
  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 Просмотреть файл

@@ -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<Self>;
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
}

impl Default for Obstacle {


+ 99
- 20
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<C, T = DenseVecStorage<C>>
where
C: Send + Sync + 'static,
C: Event,
{
event_emission: bool,
channel: EventChannel<ComponentEvent<C>>,
storage: T,
}

pub enum ComponentEvent<C>
where
C: Send + Sync + 'static,
C: Event,
{
Inserted(Index, C),
Modified(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>
where
C: Send + Sync + 'static,
C: Event,
T: TryDefault,
{
fn default() -> Self {
FlaggedStorage {
event_emission: true,
channel: EventChannel::new(),
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
C: Send + Sync + 'static,
C: Component + Event + Clone,
T: UnprotectedStorage<C>,
{
unsafe fn clean<B>(&mut self, has: B)
where
@@ -91,3 +85,88 @@ where
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 Просмотреть файл

@@ -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;

+ 7
- 15
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::<FleetOwned>::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::<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 {
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) => {


+ 7
- 15
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::<OrbitOwned>::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::<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 {
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) => {


+ 11
- 14
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::<FleetOwned>::setup(world);

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 {
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);
}
}



Загрузка…
Отмена
Сохранить