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