| @@ -1,3 +0,0 @@ | |||
| mod player_visual; | |||
| pub use player_visual::PlayerVisual; | |||
| @@ -1,12 +0,0 @@ | |||
| use glc::vector::Vector4f; | |||
| use serde::{Deserialize, Serialize}; | |||
| use specs::{Component, HashMapStorage}; | |||
| #[derive(Clone, Debug, Serialize, Deserialize)] | |||
| pub struct PlayerVisual { | |||
| pub color: Vector4f, | |||
| } | |||
| impl Component for PlayerVisual { | |||
| type Storage = HashMapStorage<Self>; | |||
| } | |||
| @@ -1,10 +1,9 @@ | |||
| pub mod components; | |||
| pub mod constants; | |||
| pub mod error; | |||
| pub mod misc; | |||
| pub mod render; | |||
| pub mod resources; | |||
| pub mod systems; | |||
| mod constants; | |||
| mod error; | |||
| mod misc; | |||
| mod render; | |||
| mod resources; | |||
| mod systems; | |||
| use specs::{Dispatcher, DispatcherBuilder, World}; | |||
| @@ -51,17 +51,15 @@ fn run(vfs: Vfs) -> Result<(), Error> { | |||
| fn create_world(world: &mut World) { | |||
| use glc::vector::{Vector2f, Vector4f}; | |||
| use space_crush_app::{components::PlayerVisual, misc::PersistWorld}; | |||
| use space_crush_common::{ | |||
| components::{Owned, Planet, Player, Position, Ship, ShipType, Velocity}, | |||
| misc::Persistence, | |||
| misc::{PersistWorld, Persistence}, | |||
| }; | |||
| use specs::{saveload::MarkedBuilder, Builder}; | |||
| let player1 = world | |||
| .create_entity() | |||
| .with(Player {}) | |||
| .with(PlayerVisual { | |||
| .with(Player { | |||
| color: Vector4f::new(0.0, 0.5, 1.0, 0.1), | |||
| }) | |||
| .build(); | |||
| @@ -107,8 +105,7 @@ fn create_world(world: &mut World) { | |||
| fn load_world(world: &mut World, path: &str) -> Result<bool, Error> { | |||
| use serde_json::de::{Deserializer, IoRead}; | |||
| use space_crush_app::misc::PersistWorld; | |||
| use space_crush_common::misc::{Persistence, WorldHelper}; | |||
| use space_crush_common::misc::{PersistWorld, Persistence, WorldHelper}; | |||
| PersistWorld::setup(world); | |||
| @@ -128,8 +125,7 @@ fn load_world(world: &mut World, path: &str) -> Result<bool, Error> { | |||
| fn save_world(world: &mut World, path: &str) -> Result<(), Error> { | |||
| use serde_json::Serializer; | |||
| use space_crush_app::misc::PersistWorld; | |||
| use space_crush_common::misc::WorldHelper; | |||
| use space_crush_common::misc::{PersistWorld, WorldHelper}; | |||
| let vfs = world.resource::<Vfs>()?; | |||
| let mut file = vfs.join(path)?.create_file()?; | |||
| @@ -6,4 +6,4 @@ mod world; | |||
| pub use events::{Events, KeyboardEvent, MouseButton, MouseEvent, VirtualKeyCode, WindowEvent}; | |||
| pub use text::{Text, TextCache, TextManager}; | |||
| pub use window::Window; | |||
| pub use world::{PersistWorld, WorldHelper}; | |||
| pub use world::WorldHelper; | |||
| @@ -5,31 +5,10 @@ use glc::{ | |||
| shader::{Program, Shader, Type}, | |||
| texture::{Data, FilterMag, FilterMin, Target, Texture, Wrap}, | |||
| }; | |||
| use space_crush_common::{ | |||
| components::{Owned, Planet, Player, Position, Ship, Velocity}, | |||
| misc::{Persistence, Vfs}, | |||
| }; | |||
| use specs::{saveload::SimpleMarker, World}; | |||
| use crate::{components::PlayerVisual, Error}; | |||
| /* PersistWorld */ | |||
| pub struct PersistWorld; | |||
| pub struct PersistWorldMarker; | |||
| impl Persistence for PersistWorld { | |||
| type Marker = SimpleMarker<PersistWorldMarker>; | |||
| type Components = ( | |||
| Position, | |||
| Velocity, | |||
| Planet, | |||
| Ship, | |||
| Owned, | |||
| Player, | |||
| PlayerVisual, | |||
| ); | |||
| } | |||
| use space_crush_common::misc::Vfs; | |||
| use specs::World; | |||
| use crate::Error; | |||
| /* WorldHelper */ | |||
| @@ -6,13 +6,12 @@ use glc::{ | |||
| vector::Vector4f, | |||
| }; | |||
| use space_crush_common::{ | |||
| components::{Owned, Planet, Position}, | |||
| components::{Owned, Planet, Player, Position}, | |||
| misc::LogResult, | |||
| }; | |||
| use specs::{prelude::*, ReadExpect, ReadStorage, System, World}; | |||
| use crate::{ | |||
| components::PlayerVisual, | |||
| constants::{PLAYER_COLOR_DEFAULT, UNIFORM_BUFFER_INDEX_CAMERA, UNIFORM_BUFFER_INDEX_UNIFORM}, | |||
| misc::WorldHelper, | |||
| resources::Geometry, | |||
| @@ -60,7 +59,7 @@ pub struct PlanetsData<'a> { | |||
| position: ReadStorage<'a, Position>, | |||
| planet: ReadStorage<'a, Planet>, | |||
| owned: ReadStorage<'a, Owned>, | |||
| player_visual: ReadStorage<'a, PlayerVisual>, | |||
| player: ReadStorage<'a, Player>, | |||
| } | |||
| impl<'a> System<'a> for Planets { | |||
| @@ -72,7 +71,7 @@ impl<'a> System<'a> for Planets { | |||
| position, | |||
| planet, | |||
| owned, | |||
| player_visual, | |||
| player, | |||
| } = data; | |||
| gl::enable(gl::BLEND); | |||
| @@ -86,7 +85,7 @@ impl<'a> System<'a> for Planets { | |||
| let p_y = p.pos.y; | |||
| let s = p.size; | |||
| let c = match owned.and_then(|owned| player_visual.get(owned.owner)) { | |||
| let c = match owned.and_then(|owned| player.get(owned.owner)) { | |||
| Some(pv) => &pv.color, | |||
| None => &*PLAYER_COLOR_DEFAULT, | |||
| }; | |||
| @@ -6,13 +6,12 @@ use glc::{ | |||
| vector::Vector4f, | |||
| }; | |||
| use space_crush_common::{ | |||
| components::{Owned, Position, Ship, ShipType, Velocity}, | |||
| components::{Owned, Player, Position, Ship, ShipType, Velocity}, | |||
| misc::LogResult, | |||
| }; | |||
| use specs::{prelude::*, ReadExpect, ReadStorage, System, World}; | |||
| use crate::{ | |||
| components::PlayerVisual, | |||
| constants::{PLAYER_COLOR_DEFAULT, UNIFORM_BUFFER_INDEX_CAMERA, UNIFORM_BUFFER_INDEX_UNIFORM}, | |||
| misc::WorldHelper, | |||
| resources::Geometry, | |||
| @@ -67,7 +66,7 @@ pub struct ShipsData<'a> { | |||
| velocity: ReadStorage<'a, Velocity>, | |||
| ship: ReadStorage<'a, Ship>, | |||
| owned: ReadStorage<'a, Owned>, | |||
| player_visual: ReadStorage<'a, PlayerVisual>, | |||
| player: ReadStorage<'a, Player>, | |||
| } | |||
| impl<'a> System<'a> for Ships { | |||
| @@ -80,7 +79,7 @@ impl<'a> System<'a> for Ships { | |||
| velocity, | |||
| ship, | |||
| owned, | |||
| player_visual, | |||
| player, | |||
| } = data; | |||
| gl::enable(gl::BLEND); | |||
| @@ -95,7 +94,7 @@ impl<'a> System<'a> for Ships { | |||
| ShipType::Transporter => BindGuard::new(&self.texture_transporter), | |||
| }; | |||
| let c = match owned.and_then(|owned| player_visual.get(owned.owner)) { | |||
| let c = match owned.and_then(|owned| player.get(owned.owner)) { | |||
| Some(pv) => &pv.color, | |||
| None => &*PLAYER_COLOR_DEFAULT, | |||
| }; | |||
| @@ -1,9 +1,12 @@ | |||
| use glc::vector::Vector4f; | |||
| use serde::{Deserialize, Serialize}; | |||
| use specs::{Component, NullStorage}; | |||
| use specs::{Component, HashMapStorage}; | |||
| #[derive(Clone, Debug, Default, Serialize, Deserialize)] | |||
| pub struct Player {} | |||
| pub struct Player { | |||
| pub color: Vector4f, | |||
| } | |||
| impl Component for Player { | |||
| type Storage = NullStorage<Self>; | |||
| type Storage = HashMapStorage<Self>; | |||
| } | |||
| @@ -1,9 +1,11 @@ | |||
| mod log; | |||
| mod log_result; | |||
| mod persistence; | |||
| mod vfs; | |||
| mod world; | |||
| pub use self::log::init as init_logger; | |||
| pub use self::vfs::{Vfs, VfsError}; | |||
| pub use log_result::LogResult; | |||
| pub use world::{Persistence, WorldHelper}; | |||
| pub use persistence::{PersistWorld, Persistence}; | |||
| pub use world::WorldHelper; | |||
| @@ -0,0 +1,143 @@ | |||
| use serde::{de::Deserializer, ser::Serializer}; | |||
| use specs::{ | |||
| error::NoError, | |||
| saveload::{ConvertSaveload, DeserializeComponents, Marker, SerializeComponents, SimpleMarker}, | |||
| Component, Entities, ReadStorage, World, WorldExt, Write, WriteStorage, | |||
| }; | |||
| use crate::components::{Owned, Planet, Player, Position, Ship, Velocity}; | |||
| /* PersistWorld */ | |||
| pub struct PersistWorld; | |||
| pub struct PersistWorldMarker; | |||
| impl Persistence for PersistWorld { | |||
| type Marker = SimpleMarker<PersistWorldMarker>; | |||
| type Components = (Position, Velocity, Planet, Ship, Owned, Player); | |||
| } | |||
| /* Persistence */ | |||
| pub trait Persistence { | |||
| type Marker: Marker; | |||
| type Components: PersistenceComponents<Self::Marker>; | |||
| fn setup(world: &mut World) | |||
| where | |||
| <Self::Marker as Component>::Storage: Default, | |||
| <Self::Marker as Marker>::Allocator: Default, | |||
| { | |||
| world.register::<Self::Marker>(); | |||
| world.insert(<Self::Marker as Marker>::Allocator::default()); | |||
| } | |||
| fn serialize<S>(&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<M> | |||
| where | |||
| M: Marker, | |||
| { | |||
| fn serialize<S>(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<M $(,$T)+> PersistenceComponents<M> for ($($T,)+) | |||
| where | |||
| M: Marker, | |||
| M::Allocator: Default, | |||
| $($T: Component + ConvertSaveload<M, Error = NoError>,)+ | |||
| { | |||
| fn serialize<S>(world: &World, serializer: S) -> Result<(), S::Error> | |||
| where | |||
| S: Serializer, | |||
| { | |||
| let ( | |||
| entities, | |||
| mut marker, | |||
| mut allocator, | |||
| $($T,)+ | |||
| ) = world.system_data::<( | |||
| Entities, | |||
| WriteStorage<M>, | |||
| Write<M::Allocator>, | |||
| $(ReadStorage<$T>, | |||
| )+)>(); | |||
| SerializeComponents::<NoError, M>::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<M>, | |||
| Write<M::Allocator>, | |||
| $(WriteStorage<$T>,)+ | |||
| )>(); | |||
| DeserializeComponents::<NoError, M>::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); | |||
| @@ -3,14 +3,12 @@ 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 specs::World; | |||
| use crate::Error; | |||
| use super::Persistence; | |||
| /* WorldHelper */ | |||
| pub trait WorldHelper { | |||
| @@ -77,128 +75,3 @@ impl WorldHelper for World { | |||
| persistence.deserialize(self, deserializer) | |||
| } | |||
| } | |||
| /* Persistence */ | |||
| pub trait Persistence { | |||
| type Marker: Marker; | |||
| type Components: PersistenceComponents<Self::Marker>; | |||
| fn setup(world: &mut World) | |||
| where | |||
| <Self::Marker as Component>::Storage: Default, | |||
| <Self::Marker as Marker>::Allocator: Default, | |||
| { | |||
| world.register::<Self::Marker>(); | |||
| world.insert(<Self::Marker as Marker>::Allocator::default()); | |||
| } | |||
| fn serialize<S>(&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<M> | |||
| where | |||
| M: Marker, | |||
| { | |||
| fn serialize<S>(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<M $(,$T)+> PersistenceComponents<M> for ($($T,)+) | |||
| where | |||
| M: Marker, | |||
| M::Allocator: Default, | |||
| $($T: Component + ConvertSaveload<M, Error = NoError>,)+ | |||
| { | |||
| fn serialize<S>(world: &World, serializer: S) -> Result<(), S::Error> | |||
| where | |||
| S: Serializer, | |||
| { | |||
| let ( | |||
| entities, | |||
| mut marker, | |||
| mut allocator, | |||
| $($T,)+ | |||
| ) = world.system_data::<( | |||
| Entities, | |||
| WriteStorage<M>, | |||
| Write<M::Allocator>, | |||
| $(ReadStorage<$T>, | |||
| )+)>(); | |||
| SerializeComponents::<NoError, M>::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<M>, | |||
| Write<M::Allocator>, | |||
| $(WriteStorage<$T>,)+ | |||
| )>(); | |||
| DeserializeComponents::<NoError, M>::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); | |||