Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

129 lignes
4.1 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,
  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. let fleet_ids = BitSet::new();
  17. let fleet_owned_ids = BitSet::new();
  18. let old_fleet_ids = HashMap::new();
  19. let fleet_owned_event_id = unsafe {
  20. WriteStorage::<FleetOwned>::setup(world);
  21. let mut fleet_owned = world.system_data::<WriteStorage<FleetOwned>>();
  22. fleet_owned
  23. .unprotected_storage_mut()
  24. .channel_mut()
  25. .register_reader()
  26. };
  27. Self {
  28. fleet_ids,
  29. fleet_owned_ids,
  30. old_fleet_ids,
  31. fleet_owned_event_id,
  32. }
  33. }
  34. }
  35. #[derive(SystemData)]
  36. pub struct FleetOwnedUpdateData<'a> {
  37. entities: Entities<'a>,
  38. ships: ReadStorage<'a, Ship>,
  39. fleets: WriteStorage<'a, Fleet>,
  40. fleet_owned: ReadStorage<'a, FleetOwned>,
  41. }
  42. impl<'a> System<'a> for FleetOwnedUpdate {
  43. type SystemData = FleetOwnedUpdateData<'a>;
  44. fn run(&mut self, data: Self::SystemData) {
  45. let FleetOwnedUpdateData {
  46. entities,
  47. ships,
  48. mut fleets,
  49. fleet_owned,
  50. } = data;
  51. self.fleet_ids.clear();
  52. self.fleet_owned_ids.clear();
  53. self.old_fleet_ids.clear();
  54. /* handle events */
  55. let events = fleet_owned
  56. .unprotected_storage()
  57. .channel()
  58. .read(&mut self.fleet_owned_event_id);
  59. for event in events {
  60. match event {
  61. ComponentEvent::Inserted(id, fleet_owned) => {
  62. self.fleet_ids.add(fleet_owned.owner().id());
  63. self.fleet_owned_ids.add(*id);
  64. }
  65. ComponentEvent::Modified(id, fleet_owned) => {
  66. self.fleet_ids.add(fleet_owned.owner().id());
  67. self.fleet_owned_ids.add(*id);
  68. *self
  69. .old_fleet_ids
  70. .entry(*id)
  71. .or_insert_with(|| fleet_owned.owner()) = fleet_owned.owner();
  72. }
  73. ComponentEvent::Removed(id, fleet_owned) => {
  74. self.fleet_ids.add(fleet_owned.owner().id());
  75. self.fleet_owned_ids.add(*id);
  76. *self
  77. .old_fleet_ids
  78. .entry(*id)
  79. .or_insert_with(|| fleet_owned.owner()) = fleet_owned.owner();
  80. }
  81. }
  82. }
  83. /* find new fleet ids */
  84. for (fleet_owned, _) in (&fleet_owned, &self.fleet_owned_ids).join() {
  85. self.fleet_ids.add(fleet_owned.owner().id());
  86. }
  87. /* update fleets */
  88. for (fleet_id, fleet, _) in (&entities, &mut fleets, &self.fleet_ids).join() {
  89. let data = (&entities, &ships, &fleet_owned, &self.fleet_owned_ids);
  90. for (ship_id, ship, fleet_owned, _) in data.join() {
  91. let new_match = fleet_id == fleet_owned.owner();
  92. let old_match = match self.old_fleet_ids.get(&ship_id.id()) {
  93. Some(old_fleet_id) => fleet_id == *old_fleet_id,
  94. None => false,
  95. };
  96. if old_match && !new_match {
  97. let count = fleet.count_mut();
  98. let count = &mut count[ship.type_()];
  99. *count = count.saturating_sub(1);
  100. fleet.owned_mut().remove(ship_id.id());
  101. } else if !old_match && new_match {
  102. let count = fleet.count_mut();
  103. let count = &mut count[ship.type_()];
  104. *count += 1;
  105. fleet.owned_mut().add(ship_id.id());
  106. }
  107. }
  108. }
  109. }
  110. }