use glc::vector::Vector3f; use serde::{Deserialize, Serialize}; use specs::{ error::NoError, saveload::{ConvertSaveload, Marker}, Component, Entity, HashMapStorage, }; #[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct Player { index: usize, color: Vector3f, } #[derive(Copy, Clone, Debug)] pub struct Owned { owner: Entity, } #[derive(Serialize, Deserialize)] pub struct OwnedData { pub owner: M, } impl Player { #[inline] pub fn new(color: Vector3f) -> Self { Self { index: next_index(), color, } } #[inline] pub fn index(&self) -> usize { self.index } #[inline] pub fn color(&self) -> &Vector3f { &self.color } } impl Component for Player { type Storage = HashMapStorage; } impl Owned { pub fn new(owner: Entity) -> Self { Self { owner } } pub fn owner(&self) -> Entity { self.owner } } impl Component for Owned { type Storage = HashMapStorage; } 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 }) } } fn next_index() -> usize { use std::sync::atomic::{AtomicUsize, Ordering}; static NEXT_INDEX: AtomicUsize = AtomicUsize::new(0); NEXT_INDEX.fetch_add(1, Ordering::Relaxed) }