use serde::{Deserialize, Serialize}; use smallvec::smallvec; use smallvec::SmallVec; use specs::{ error::NoError, saveload::{ConvertSaveload, Marker}, Component, Entity, HashMapStorage, }; use crate::misc::FlaggedStorage; /// Point in the universe fleets can meet #[derive(Clone, Debug, Default)] pub struct MeetingPoint { min: f32, max: f32, fleets: Fleets, } /// Entities with this component are fleets by an meeting point #[derive(Copy, Clone, Debug)] pub struct MeetingPointOwned { owner: Entity, } #[derive(Serialize, Deserialize)] pub struct MeetingPointData { pub min: f32, pub max: f32, pub fleets: Vec>, } #[derive(Serialize, Deserialize)] pub struct MeetingPointOwnedData { pub owner: M, } type Fleets = SmallVec<[Option; 8]>; /* MeetingPoint */ impl MeetingPoint { #[inline] pub fn min(&self) -> f32 { self.min } #[inline] pub fn max(&self) -> f32 { self.max } #[inline] pub fn fleets(&self) -> &Fleets { &self.fleets } #[inline] pub fn fleet(&self, index: usize) -> Option { self.fleets.get(index).cloned().flatten() } } impl MeetingPoint { #[inline] pub(crate) fn new(min: f32, max: f32) -> Self { Self { min, max, fleets: smallvec![], } } pub(crate) fn add_fleet(&mut self, player: usize, fleet: Entity) { self.fleets.resize_with(player + 1, Default::default); self.fleets[player] = Some(fleet); } pub(crate) fn remove_fleet(&mut self, player: usize) { if let Some(fleet) = self.fleets.get_mut(player) { *fleet = None; } } } impl Component for MeetingPoint { type Storage = HashMapStorage; } impl ConvertSaveload for MeetingPoint where for<'de> M: Marker + Serialize + Deserialize<'de>, { type Data = MeetingPointData; type Error = NoError; fn convert_into(&self, mut ids: F) -> Result where F: FnMut(Entity) -> Option, { let MeetingPoint { min, max, fleets } = self; let min = *min; let max = *max; let fleets = fleets .iter() .cloned() .map(|e| e.and_then(|e| ids(e))) .collect(); Ok(MeetingPointData { min, max, fleets }) } fn convert_from(data: Self::Data, mut ids: F) -> Result where F: FnMut(M) -> Option, { let MeetingPointData { min, max, fleets } = data; let fleets = fleets.into_iter().map(|e| e.and_then(|e| ids(e))).collect(); Ok(MeetingPoint { min, max, fleets }) } } /* MeetingPointOwned */ impl MeetingPointOwned { pub fn owner(&self) -> Entity { self.owner } } impl MeetingPointOwned { pub(crate) fn new(owner: Entity) -> Self { Self { owner } } } impl Component for MeetingPointOwned { type Storage = FlaggedStorage>; } impl ConvertSaveload for MeetingPointOwned where for<'de> M: Marker + Serialize + Deserialize<'de>, { type Data = MeetingPointOwnedData; type Error = NoError; fn convert_into(&self, mut ids: F) -> Result where F: FnMut(Entity) -> Option, { let owner = ids(self.owner).unwrap(); Ok(MeetingPointOwnedData { owner }) } fn convert_from(data: Self::Data, mut ids: F) -> Result where F: FnMut(M) -> Option, { let owner = ids(data.owner).unwrap(); Ok(MeetingPointOwned { owner }) } }