use std::any::type_name; use serde::{de::Deserializer, ser::Serializer}; use shred::{Fetch, FetchMut, Resource}; use shrev::{Event, EventChannel, ReaderId}; use specs::{ error::NoError, saveload::{ConvertSaveload, DeserializeComponents, Marker, SerializeComponents}, Component, Entities, ReadStorage, World, WorldExt, Write, WriteStorage, }; use crate::Error; /* WorldHelper */ pub trait WorldHelper { fn resource(&self) -> Result, Error> where R: Resource; fn resource_mut(&self) -> Result, Error> where R: Resource; fn register_event_reader(&self) -> Result, Error> where E: Event; fn serialize(&self, persistence: T, serializer: S) -> Result<(), S::Error> where T: Persistence, S: Serializer; fn deserialize<'de, T, D>(&self, persistence: T, deserializer: D) -> Result<(), D::Error> where T: Persistence, D: Deserializer<'de>; } impl WorldHelper for World { fn resource(&self) -> Result, Error> where R: Resource, { self.try_fetch::() .ok_or_else(|| Error::ResourceNotRegistered(type_name::())) } fn resource_mut(&self) -> Result, Error> where R: Resource, { self.try_fetch_mut::() .ok_or_else(|| Error::ResourceNotRegistered(type_name::())) } fn register_event_reader(&self) -> Result, Error> where E: Event, { Ok(self.resource_mut::>()?.register_reader()) } fn serialize(&self, persistence: T, serializer: S) -> Result<(), S::Error> where T: Persistence, S: Serializer, { persistence.serialize(self, serializer) } fn deserialize<'de, T, D>(&self, persistence: T, deserializer: D) -> Result<(), D::Error> where T: Persistence, D: Deserializer<'de>, { persistence.deserialize(self, deserializer) } } /* Persistence */ pub trait Persistence { type Marker: Marker; type Components: PersistenceComponents; fn setup(world: &mut World) where ::Storage: Default, ::Allocator: Default, { world.register::(); world.insert(::Allocator::default()); } fn serialize(&self, world: &World, serializer: S) -> Result<(), S::Error> where S: Serializer, { Self::Components::serialize(world, serializer) } fn deserialize<'de, D>(&self, world: &World, deserializer: D) -> Result<(), D::Error> where D: Deserializer<'de>, { Self::Components::deserialize(world, deserializer) } } /* PersistenceComponents */ pub trait PersistenceComponents where M: Marker, { fn serialize(world: &World, serializer: S) -> Result<(), S::Error> where S: Serializer; fn deserialize<'de, D>(world: &World, deserializer: D) -> Result<(), D::Error> where D: Deserializer<'de>; } macro_rules! define_persistence_components { ($($T:ident),*) => { #[allow(non_snake_case)] impl PersistenceComponents for ($($T,)+) where M: Marker, M::Allocator: Default, $($T: Component + ConvertSaveload,)+ { fn serialize(world: &World, serializer: S) -> Result<(), S::Error> where S: Serializer, { let ( entities, mut marker, mut allocator, $($T,)+ ) = world.system_data::<( Entities, WriteStorage, Write, $(ReadStorage<$T>, )+)>(); SerializeComponents::::serialize_recursive (&($($T,)+), &entities, &mut marker, &mut allocator, serializer, )?; Ok(()) } fn deserialize<'de, D>(world: &World, deserializer: D) -> Result<(), D::Error> where D: Deserializer<'de>, { let ( entities, mut marker, mut allocator, $($T,)+ ) = world.system_data::<( Entities, WriteStorage, Write, $(WriteStorage<$T>,)+ )>(); DeserializeComponents::::deserialize( &mut ($($T,)+), &entities, &mut marker, &mut allocator, deserializer, ) } } } } define_persistence_components!(T1); define_persistence_components!(T1, T2); define_persistence_components!(T1, T2, T3); define_persistence_components!(T1, T2, T3, T4); define_persistence_components!(T1, T2, T3, T4, T5); define_persistence_components!(T1, T2, T3, T4, T5, T6); define_persistence_components!(T1, T2, T3, T4, T5, T6, T7); define_persistence_components!(T1, T2, T3, T4, T5, T6, T7, T8); define_persistence_components!(T1, T2, T3, T4, T5, T6, T7, T8, T9); define_persistence_components!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10); define_persistence_components!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11); define_persistence_components!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12); define_persistence_components!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13); define_persistence_components!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14); define_persistence_components!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);