Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

113 rader
3.6 KiB

  1. use std::collections::HashMap;
  2. use shrev::ReaderId;
  3. use specs::{prelude::*, world::Index, Entities, ReadStorage, System, World, WriteStorage};
  4. use crate::{
  5. components::{Fleet, FleetOwned, Ship},
  6. misc::{ComponentEvent, StorageHelper, StorageHelperMut},
  7. };
  8. pub struct FleetOwnedUpdate {
  9. fleet_ids: BitSet,
  10. fleet_owned_ids: BitSet,
  11. old_fleet_ids: HashMap<Index, Entity>,
  12. fleet_owned_event_id: ReaderId<ComponentEvent<FleetOwned>>,
  13. }
  14. impl FleetOwnedUpdate {
  15. pub fn new(world: &mut World) -> Self {
  16. WriteStorage::<FleetOwned>::setup(world);
  17. let fleet_ids = BitSet::new();
  18. let fleet_owned_ids = BitSet::new();
  19. let old_fleet_ids = HashMap::new();
  20. let fleet_owned_event_id = world
  21. .system_data::<WriteStorage<FleetOwned>>()
  22. .register_event_reader();
  23. Self {
  24. fleet_ids,
  25. fleet_owned_ids,
  26. old_fleet_ids,
  27. fleet_owned_event_id,
  28. }
  29. }
  30. }
  31. #[derive(SystemData)]
  32. pub struct FleetOwnedUpdateData<'a> {
  33. entities: Entities<'a>,
  34. ships: ReadStorage<'a, Ship>,
  35. fleets: WriteStorage<'a, Fleet>,
  36. fleet_owned: ReadStorage<'a, FleetOwned>,
  37. }
  38. impl<'a> System<'a> for FleetOwnedUpdate {
  39. type SystemData = FleetOwnedUpdateData<'a>;
  40. fn run(&mut self, data: Self::SystemData) {
  41. let FleetOwnedUpdateData {
  42. entities,
  43. ships,
  44. mut fleets,
  45. fleet_owned,
  46. } = data;
  47. self.fleet_ids.clear();
  48. self.fleet_owned_ids.clear();
  49. self.old_fleet_ids.clear();
  50. /* handle events */
  51. let events = fleet_owned.channel().read(&mut self.fleet_owned_event_id);
  52. for event in events {
  53. match event {
  54. ComponentEvent::Inserted(id, fleet_owned) => {
  55. self.fleet_ids.add(fleet_owned.owner().id());
  56. self.fleet_owned_ids.add(*id);
  57. }
  58. ComponentEvent::Modified(id, fleet_owned) => {
  59. self.fleet_ids.add(fleet_owned.owner().id());
  60. self.fleet_owned_ids.add(*id);
  61. *self
  62. .old_fleet_ids
  63. .entry(*id)
  64. .or_insert_with(|| fleet_owned.owner()) = fleet_owned.owner();
  65. }
  66. ComponentEvent::Removed(id, fleet_owned) => {
  67. self.fleet_ids.add(fleet_owned.owner().id());
  68. self.fleet_owned_ids.add(*id);
  69. *self
  70. .old_fleet_ids
  71. .entry(*id)
  72. .or_insert_with(|| fleet_owned.owner()) = fleet_owned.owner();
  73. }
  74. }
  75. }
  76. /* find new fleet ids */
  77. for (fleet_owned, _) in (&fleet_owned, &self.fleet_owned_ids).join() {
  78. self.fleet_ids.add(fleet_owned.owner().id());
  79. }
  80. /* update fleets */
  81. for (fleet_id, fleet, _) in (&entities, &mut fleets, &self.fleet_ids).join() {
  82. let data = (&entities, &ships, &fleet_owned, &self.fleet_owned_ids);
  83. for (ship_id, ship, fleet_owned, _) in data.join() {
  84. let new_match = fleet_id == fleet_owned.owner();
  85. let old_match = match self.old_fleet_ids.get(&ship_id.id()) {
  86. Some(old_fleet_id) => fleet_id == *old_fleet_id,
  87. None => false,
  88. };
  89. if old_match && !new_match {
  90. fleet.remove_ship(ship_id, ship);
  91. } else if !old_match && new_match {
  92. fleet.add_ship(ship_id, ship);
  93. }
  94. }
  95. }
  96. }
  97. }