|
- use std::collections::HashMap;
-
- use shrev::ReaderId;
- use specs::{
- hibitset::BitSet, prelude::*, world::Index, Entities, Entity, ReadStorage, System, World,
- WriteStorage,
- };
-
- use crate::{
- components::{FleetOrbiting, MeetingPoint, Player, PlayerOwned},
- misc::{ComponentEvent, StorageHelper, StorageHelperMut},
- };
-
- pub struct FleetOrbitingUpdate {
- meeting_point_ids: BitSet,
- fleet_orbiting_ids: BitSet,
- old_meeting_point_ids: HashMap<Index, Entity>,
- fleet_orbiting_event_id: ReaderId<crate::misc::ComponentEvent<FleetOrbiting>>,
- }
-
- #[derive(SystemData)]
- pub struct FleetOrbitingUpdateData<'a> {
- entities: Entities<'a>,
- players: ReadStorage<'a, Player>,
- player_owned: ReadStorage<'a, PlayerOwned>,
- fleet_orbiting: ReadStorage<'a, FleetOrbiting>,
- meeting_points: WriteStorage<'a, MeetingPoint>,
- }
-
- impl FleetOrbitingUpdate {
- pub fn new(world: &mut World) -> Self {
- WriteStorage::<FleetOrbiting>::setup(world);
-
- let meeting_point_ids = BitSet::new();
- let fleet_orbiting_ids = BitSet::new();
- let old_meeting_point_ids = HashMap::new();
- let fleet_orbiting_event_id = world
- .system_data::<WriteStorage<FleetOrbiting>>()
- .register_event_reader();
-
- Self {
- meeting_point_ids,
- fleet_orbiting_ids,
- old_meeting_point_ids,
- fleet_orbiting_event_id,
- }
- }
- }
-
- impl<'a> System<'a> for FleetOrbitingUpdate {
- type SystemData = FleetOrbitingUpdateData<'a>;
-
- fn run(&mut self, data: Self::SystemData) {
- let FleetOrbitingUpdateData {
- entities,
- players,
- player_owned,
- fleet_orbiting,
- mut meeting_points,
- } = data;
-
- self.meeting_point_ids.clear();
- self.fleet_orbiting_ids.clear();
- self.old_meeting_point_ids.clear();
-
- /* handle events */
- let events = fleet_orbiting
- .channel()
- .read(&mut self.fleet_orbiting_event_id);
- for event in events {
- match event {
- ComponentEvent::Inserted(id, fleet_orbiting) => {
- self.meeting_point_ids
- .add(fleet_orbiting.meeting_point().id());
- self.fleet_orbiting_ids.add(*id);
- }
- ComponentEvent::Modified(id, fleet_orbiting) => {
- self.meeting_point_ids
- .add(fleet_orbiting.meeting_point().id());
- self.fleet_orbiting_ids.add(*id);
- *self
- .old_meeting_point_ids
- .entry(*id)
- .or_insert_with(|| fleet_orbiting.meeting_point()) =
- fleet_orbiting.meeting_point();
- }
- ComponentEvent::Removed(id, fleet_orbiting) => {
- self.meeting_point_ids
- .add(fleet_orbiting.meeting_point().id());
- self.fleet_orbiting_ids.add(*id);
- *self
- .old_meeting_point_ids
- .entry(*id)
- .or_insert_with(|| fleet_orbiting.meeting_point()) =
- fleet_orbiting.meeting_point();
- }
- }
- }
-
- /* find new meeting_point ids */
- for (fleet_orbiting, _) in (&fleet_orbiting, &self.fleet_orbiting_ids).join() {
- self.meeting_point_ids
- .add(fleet_orbiting.meeting_point().id());
- }
-
- /* update meeting_points */
- for (meeting_point_id, meeting_point, _) in
- (&entities, &mut meeting_points, &self.meeting_point_ids).join()
- {
- let data = (
- &entities,
- &fleet_orbiting,
- &player_owned,
- &self.fleet_orbiting_ids,
- );
-
- for (fleet_id, fleet_orbiting, player_owned, _) in data.join() {
- let new_match = meeting_point_id == fleet_orbiting.meeting_point();
- 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 = players.get(player_id).unwrap();
- 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);
- }
- }
- }
- }
- }
|