use serde::{Deserialize, Serialize}; use smallvec::smallvec; use smallvec::SmallVec; use specs::{ error::NoError, saveload::{ConvertSaveload, Marker}, Component, Entity, HashMapStorage, }; use crate::misc::FlaggedStorage; #[derive(Clone, Debug, Default)] pub struct Orbit { min: f32, max: f32, fleets: Fleets, } #[derive(Serialize, Deserialize)] pub struct OrbitData { pub min: f32, pub max: f32, pub fleets: Vec>, } #[derive(Copy, Clone, Debug)] pub struct Owned { owner: Entity, } #[derive(Serialize, Deserialize)] pub struct OwnedData { pub owner: M, } type Fleets = SmallVec<[Option; 8]>; impl Orbit { #[inline] pub fn new(min: f32, max: f32) -> Self { Self { min, max, fleets: smallvec![], } } #[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(crate) fn fleets_mut(&mut self) -> &mut Fleets { &mut self.fleets } #[inline] pub fn fleet(&self, index: usize) -> Option { self.fleets.get(index).cloned().flatten() } #[inline] pub(crate) fn fleet_mut(&mut self, index: usize) -> &mut Option { self.fleets.resize_with(index + 1, Default::default); &mut self.fleets[index] } } impl Component for Orbit { type Storage = HashMapStorage; } impl ConvertSaveload for Orbit where for<'de> M: Marker + Serialize + Deserialize<'de>, { type Data = OrbitData; type Error = NoError; fn convert_into(&self, mut ids: F) -> Result where F: FnMut(Entity) -> Option, { let Orbit { 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(OrbitData { min, max, fleets }) } fn convert_from(data: Self::Data, mut ids: F) -> Result where F: FnMut(M) -> Option, { let OrbitData { min, max, fleets } = data; let fleets = fleets.into_iter().map(|e| e.and_then(|e| ids(e))).collect(); Ok(Orbit { min, max, fleets }) } } impl Owned { pub fn new(owner: Entity) -> Self { Self { owner } } pub fn owner(&self) -> Entity { self.owner } pub(crate) fn set_owner(&mut self, value: Entity) { self.owner = value; } } impl Component for Owned { type Storage = FlaggedStorage>; } impl ConvertSaveload for Owned where for<'de> M: Marker + Serialize + Deserialize<'de>, { type Data = OwnedData; type Error = NoError; fn convert_into(&self, mut ids: F) -> Result where F: FnMut(Entity) -> Option, { let owner = ids(self.owner).unwrap(); Ok(OwnedData { owner }) } fn convert_from(data: Self::Data, mut ids: F) -> Result where F: FnMut(M) -> Option, { let owner = ids(data.owner).unwrap(); Ok(Owned { owner }) } }