use log::{error, info}; use space_crush_app::{App, Error}; use space_crush_common::{ misc::{init_logger, Vfs}, Dispatcher, }; use specs::{World, WorldExt}; fn main() -> Result<(), Error> { let vfs = Vfs::new(&["space-crush-app"])?; init_logger(&vfs, "log4rs.yml"); vfs.log_info(); info!("Application started"); if let Err(err) = run(vfs) { error!("Error while executing application: {}", err); return Err(err); } info!("Application exited"); Ok(()) } fn run(vfs: Vfs) -> Result<(), Error> { let mut world = World::new(); world.insert(vfs); let mut common = Dispatcher::new(&mut world); let mut app = App::new(&mut world)?; if !load_world(&mut world, WORLD_FILEPATH)? { create_world(&mut world); } while app.is_running() { world.maintain(); common.process(&world); app.process(&world)?; } save_world(&mut world, WORLD_FILEPATH)?; Ok(()) } 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, }; use specs::{saveload::MarkedBuilder, Builder}; let player1 = world .create_entity() .with(Player {}) .with(PlayerVisual { color: Vector4f::new(0.0, 0.5, 1.0, 0.1), }) .build(); world .create_entity() .marked::<::Marker>() .with(Owned { owner: player1 }) .with(Position { pos: Vector2f::default(), size: 500.0, }) .with(Planet {}) .build(); for i in 0..3 { let x = if i & 1 == 0 { 1.0 } else { -1.0 }; let y = if i & 2 == 0 { 1.0 } else { -1.0 }; world .create_entity() .marked::<::Marker>() .with(Owned { owner: player1 }) .with(Position { pos: Vector2f::new(250.0 * x, 250.0 * y), size: 30.0, }) .with(Velocity { dir: Vector2f::new(i as f32 - 1.0, 1.0).normalize(), speed: 0.0, }) .with(Ship { type_: match i { 0 => ShipType::Fighter, 1 => ShipType::Bomber, 2 => ShipType::Transporter, _ => unreachable!(), }, }) .build(); } } fn load_world(world: &mut World, path: &str) -> Result { use serde_json::de::{Deserializer, IoRead}; use space_crush_app::misc::PersistWorld; use space_crush_common::misc::{Persistence, WorldHelper}; PersistWorld::setup(world); let vfs = world.resource::()?; let path = vfs.join(path)?; if !path.exists() { return Ok(false); } let mut file = path.open_file()?; let mut read = IoRead::new(&mut file); let mut deserializer = Deserializer::new(&mut read); world.deserialize(PersistWorld, &mut deserializer)?; Ok(true) } 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; let vfs = world.resource::()?; let mut file = vfs.join(path)?.create_file()?; let mut serializer = Serializer::new(&mut file); world.serialize(PersistWorld, &mut serializer)?; Ok(()) } const WORLD_FILEPATH: &str = "resources/world.json";