|
|
|
@@ -0,0 +1,134 @@ |
|
|
|
use std::collections::HashMap; |
|
|
|
|
|
|
|
use shrev::ReaderId; |
|
|
|
use specs::{ |
|
|
|
hibitset::BitSet, prelude::*, world::Index, Entities, Entity, ReadStorage, System, World, |
|
|
|
WriteStorage, |
|
|
|
}; |
|
|
|
|
|
|
|
use crate::{ |
|
|
|
components::{MeetingPoint, MeetingPointOwned, Player, PlayerOwned}, |
|
|
|
continue_if_none, |
|
|
|
misc::{ComponentEvent, StorageHelper, StorageHelperMut}, |
|
|
|
}; |
|
|
|
|
|
|
|
pub struct MeetingPointOwnedUpdate { |
|
|
|
meeting_point_ids: BitSet, |
|
|
|
meeting_point_owned_ids: BitSet, |
|
|
|
old_meeting_point_ids: HashMap<Index, Entity>, |
|
|
|
meeting_point_owned_event_id: ReaderId<crate::misc::ComponentEvent<MeetingPointOwned>>, |
|
|
|
} |
|
|
|
|
|
|
|
#[derive(SystemData)] |
|
|
|
pub struct MeetingPointOwnedUpdateData<'a> { |
|
|
|
entities: Entities<'a>, |
|
|
|
players: ReadStorage<'a, Player>, |
|
|
|
player_owned: ReadStorage<'a, PlayerOwned>, |
|
|
|
meeting_point_owned: ReadStorage<'a, MeetingPointOwned>, |
|
|
|
meeting_points: WriteStorage<'a, MeetingPoint>, |
|
|
|
} |
|
|
|
|
|
|
|
impl MeetingPointOwnedUpdate { |
|
|
|
pub fn new(world: &mut World) -> Self { |
|
|
|
WriteStorage::<MeetingPointOwned>::setup(world); |
|
|
|
|
|
|
|
let meeting_point_ids = BitSet::new(); |
|
|
|
let meeting_point_owned_ids = BitSet::new(); |
|
|
|
let old_meeting_point_ids = HashMap::new(); |
|
|
|
let meeting_point_owned_event_id = world |
|
|
|
.system_data::<WriteStorage<MeetingPointOwned>>() |
|
|
|
.register_event_reader(); |
|
|
|
|
|
|
|
Self { |
|
|
|
meeting_point_ids, |
|
|
|
meeting_point_owned_ids, |
|
|
|
old_meeting_point_ids, |
|
|
|
meeting_point_owned_event_id, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<'a> System<'a> for MeetingPointOwnedUpdate { |
|
|
|
type SystemData = MeetingPointOwnedUpdateData<'a>; |
|
|
|
|
|
|
|
fn run(&mut self, data: Self::SystemData) { |
|
|
|
let MeetingPointOwnedUpdateData { |
|
|
|
entities, |
|
|
|
players, |
|
|
|
player_owned, |
|
|
|
meeting_point_owned, |
|
|
|
mut meeting_points, |
|
|
|
} = data; |
|
|
|
|
|
|
|
self.meeting_point_ids.clear(); |
|
|
|
self.meeting_point_owned_ids.clear(); |
|
|
|
self.old_meeting_point_ids.clear(); |
|
|
|
|
|
|
|
/* handle events */ |
|
|
|
let events = meeting_point_owned |
|
|
|
.channel() |
|
|
|
.read(&mut self.meeting_point_owned_event_id); |
|
|
|
for event in events { |
|
|
|
match event { |
|
|
|
ComponentEvent::Inserted(id, meeting_point_owned) => { |
|
|
|
self.meeting_point_ids.add(meeting_point_owned.owner().id()); |
|
|
|
self.meeting_point_owned_ids.add(*id); |
|
|
|
} |
|
|
|
ComponentEvent::Modified(id, meeting_point_owned) => { |
|
|
|
self.meeting_point_ids.add(meeting_point_owned.owner().id()); |
|
|
|
self.meeting_point_owned_ids.add(*id); |
|
|
|
*self |
|
|
|
.old_meeting_point_ids |
|
|
|
.entry(*id) |
|
|
|
.or_insert_with(|| meeting_point_owned.owner()) = |
|
|
|
meeting_point_owned.owner(); |
|
|
|
} |
|
|
|
ComponentEvent::Removed(id, meeting_point_owned) => { |
|
|
|
self.meeting_point_ids.add(meeting_point_owned.owner().id()); |
|
|
|
self.meeting_point_owned_ids.add(*id); |
|
|
|
*self |
|
|
|
.old_meeting_point_ids |
|
|
|
.entry(*id) |
|
|
|
.or_insert_with(|| meeting_point_owned.owner()) = |
|
|
|
meeting_point_owned.owner(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* find new meeting_point ids */ |
|
|
|
for (meeting_point_owned, _) in (&meeting_point_owned, &self.meeting_point_owned_ids).join() |
|
|
|
{ |
|
|
|
self.meeting_point_ids.add(meeting_point_owned.owner().id()); |
|
|
|
} |
|
|
|
|
|
|
|
/* update meeting_points */ |
|
|
|
for (meeting_point_id, meeting_point, _) in |
|
|
|
(&entities, &mut meeting_points, &self.meeting_point_ids).join() |
|
|
|
{ |
|
|
|
let data = ( |
|
|
|
&entities, |
|
|
|
&meeting_point_owned, |
|
|
|
&player_owned, |
|
|
|
&self.meeting_point_owned_ids, |
|
|
|
); |
|
|
|
|
|
|
|
for (fleet_id, meeting_point_owned, player_owned, _) in data.join() { |
|
|
|
let new_match = meeting_point_id == meeting_point_owned.owner(); |
|
|
|
let old_match = match self.old_meeting_point_ids.get(&fleet_id.id()) { |
|
|
|
Some(old_meeting_point_id) => meeting_point_id == *old_meeting_point_id, |
|
|
|
None => false, |
|
|
|
}; |
|
|
|
|
|
|
|
let player_id = player_owned.owner(); |
|
|
|
let player = continue_if_none!(players.get(player_id)); |
|
|
|
let player_index = player.index(); |
|
|
|
|
|
|
|
if old_match && !new_match { |
|
|
|
meeting_point.remove_fleet(player_index); |
|
|
|
} else if !old_match && new_match { |
|
|
|
meeting_point.add_fleet(player_index, fleet_id); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |