You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
3.6 KiB

  1. use serde::{Deserialize, Serialize};
  2. use smallvec::smallvec;
  3. use smallvec::SmallVec;
  4. use specs::{
  5. error::NoError,
  6. saveload::{ConvertSaveload, Marker},
  7. Component, Entity, HashMapStorage,
  8. };
  9. use crate::misc::FlaggedStorage;
  10. /// Point in the universe fleets can meet
  11. #[derive(Clone, Debug, Default)]
  12. pub struct MeetingPoint {
  13. min: f32,
  14. max: f32,
  15. fleets: Fleets,
  16. }
  17. /// Entities with this component are fleets by an meeting point
  18. #[derive(Copy, Clone, Debug)]
  19. pub struct MeetingPointOwned {
  20. owner: Entity,
  21. }
  22. #[derive(Serialize, Deserialize)]
  23. pub struct MeetingPointData<M> {
  24. pub min: f32,
  25. pub max: f32,
  26. pub fleets: Vec<Option<M>>,
  27. }
  28. #[derive(Serialize, Deserialize)]
  29. pub struct MeetingPointOwnedData<M> {
  30. pub owner: M,
  31. }
  32. type Fleets = SmallVec<[Option<Entity>; 8]>;
  33. /* MeetingPoint */
  34. impl MeetingPoint {
  35. #[inline]
  36. pub fn min(&self) -> f32 {
  37. self.min
  38. }
  39. #[inline]
  40. pub fn max(&self) -> f32 {
  41. self.max
  42. }
  43. #[inline]
  44. pub fn fleets(&self) -> &Fleets {
  45. &self.fleets
  46. }
  47. #[inline]
  48. pub fn fleet(&self, index: usize) -> Option<Entity> {
  49. self.fleets.get(index).cloned().flatten()
  50. }
  51. }
  52. impl MeetingPoint {
  53. #[inline]
  54. pub(crate) fn new(min: f32, max: f32) -> Self {
  55. Self {
  56. min,
  57. max,
  58. fleets: smallvec![],
  59. }
  60. }
  61. pub(crate) fn add_fleet(&mut self, player: usize, fleet: Entity) {
  62. self.fleets.resize_with(player + 1, Default::default);
  63. self.fleets[player] = Some(fleet);
  64. }
  65. pub(crate) fn remove_fleet(&mut self, player: usize) {
  66. if let Some(fleet) = self.fleets.get_mut(player) {
  67. *fleet = None;
  68. }
  69. }
  70. }
  71. impl Component for MeetingPoint {
  72. type Storage = HashMapStorage<Self>;
  73. }
  74. impl<M> ConvertSaveload<M> for MeetingPoint
  75. where
  76. for<'de> M: Marker + Serialize + Deserialize<'de>,
  77. {
  78. type Data = MeetingPointData<M>;
  79. type Error = NoError;
  80. fn convert_into<F>(&self, mut ids: F) -> Result<Self::Data, Self::Error>
  81. where
  82. F: FnMut(Entity) -> Option<M>,
  83. {
  84. let MeetingPoint { min, max, fleets } = self;
  85. let min = *min;
  86. let max = *max;
  87. let fleets = fleets
  88. .iter()
  89. .cloned()
  90. .map(|e| e.and_then(|e| ids(e)))
  91. .collect();
  92. Ok(MeetingPointData { min, max, fleets })
  93. }
  94. fn convert_from<F>(data: Self::Data, mut ids: F) -> Result<Self, Self::Error>
  95. where
  96. F: FnMut(M) -> Option<Entity>,
  97. {
  98. let MeetingPointData { min, max, fleets } = data;
  99. let fleets = fleets.into_iter().map(|e| e.and_then(|e| ids(e))).collect();
  100. Ok(MeetingPoint { min, max, fleets })
  101. }
  102. }
  103. /* MeetingPointOwned */
  104. impl MeetingPointOwned {
  105. pub fn owner(&self) -> Entity {
  106. self.owner
  107. }
  108. }
  109. impl MeetingPointOwned {
  110. pub(crate) fn new(owner: Entity) -> Self {
  111. Self { owner }
  112. }
  113. }
  114. impl Component for MeetingPointOwned {
  115. type Storage = FlaggedStorage<Self, HashMapStorage<Self>>;
  116. }
  117. impl<M> ConvertSaveload<M> for MeetingPointOwned
  118. where
  119. for<'de> M: Marker + Serialize + Deserialize<'de>,
  120. {
  121. type Data = MeetingPointOwnedData<M>;
  122. type Error = NoError;
  123. fn convert_into<F>(&self, mut ids: F) -> Result<Self::Data, Self::Error>
  124. where
  125. F: FnMut(Entity) -> Option<M>,
  126. {
  127. let owner = ids(self.owner).unwrap();
  128. Ok(MeetingPointOwnedData { owner })
  129. }
  130. fn convert_from<F>(data: Self::Data, mut ids: F) -> Result<Self, Self::Error>
  131. where
  132. F: FnMut(M) -> Option<Entity>,
  133. {
  134. let owner = ids(data.owner).unwrap();
  135. Ok(MeetingPointOwned { owner })
  136. }
  137. }