You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
3.2 KiB

  1. use log::{error, info};
  2. use space_crush_app::{App, Error};
  3. use space_crush_common::{
  4. misc::{init_logger, Vfs},
  5. Dispatcher,
  6. };
  7. use specs::{World, WorldExt};
  8. fn main() -> Result<(), Error> {
  9. let vfs = Vfs::new(&["space-crush-app"])?;
  10. init_logger(&vfs, "log4rs.yml");
  11. vfs.log_info();
  12. info!("Application started");
  13. if let Err(err) = run(vfs) {
  14. error!("Error while executing application: {}", err);
  15. return Err(err);
  16. }
  17. info!("Application exited");
  18. Ok(())
  19. }
  20. fn run(vfs: Vfs) -> Result<(), Error> {
  21. let mut world = World::new();
  22. world.insert(vfs);
  23. let mut common = Dispatcher::new(&mut world);
  24. let mut app = App::new(&mut world)?;
  25. if !load_world(&mut world, WORLD_FILEPATH)? {
  26. create_world(&mut world);
  27. }
  28. while app.is_running() {
  29. world.maintain();
  30. common.process(&world);
  31. app.process(&world)?;
  32. }
  33. save_world(&mut world, WORLD_FILEPATH)?;
  34. Ok(())
  35. }
  36. fn create_world(world: &mut World) {
  37. use glc::vector::Vector2f;
  38. use space_crush_common::{
  39. components::{Planet, Position, Ship, ShipType, Velocity},
  40. misc::{PersistWorld, Persistence},
  41. };
  42. use specs::{saveload::MarkedBuilder, Builder};
  43. world
  44. .create_entity()
  45. .marked::<<PersistWorld as Persistence>::Marker>()
  46. .with(Position {
  47. pos: Vector2f::default(),
  48. size: 500.0,
  49. })
  50. .with(Planet {})
  51. .build();
  52. for i in 0..3 {
  53. let x = if i & 1 == 0 { 1.0 } else { -1.0 };
  54. let y = if i & 2 == 0 { 1.0 } else { -1.0 };
  55. world
  56. .create_entity()
  57. .marked::<<PersistWorld as Persistence>::Marker>()
  58. .with(Position {
  59. pos: Vector2f::new(250.0 * x, 250.0 * y),
  60. size: 100.0,
  61. })
  62. .with(Velocity {
  63. dir: Vector2f::new(i as f32 - 1.0, 1.0).normalize(),
  64. speed: 0.0,
  65. })
  66. .with(Ship {
  67. type_: match i {
  68. 0 => ShipType::Fighter,
  69. 1 => ShipType::Bomber,
  70. 2 => ShipType::Transporter,
  71. _ => unreachable!(),
  72. },
  73. })
  74. .build();
  75. }
  76. }
  77. fn load_world(world: &mut World, path: &str) -> Result<bool, Error> {
  78. use serde_json::de::{Deserializer, IoRead};
  79. use space_crush_common::misc::{PersistWorld, Persistence, WorldHelper};
  80. PersistWorld::setup(world);
  81. let vfs = world.resource::<Vfs>()?;
  82. let path = vfs.join(path)?;
  83. if !path.exists() {
  84. return Ok(false);
  85. }
  86. let mut file = path.open_file()?;
  87. let mut read = IoRead::new(&mut file);
  88. let mut deserializer = Deserializer::new(&mut read);
  89. world.deserialize(PersistWorld, &mut deserializer)?;
  90. Ok(true)
  91. }
  92. fn save_world(world: &mut World, path: &str) -> Result<(), Error> {
  93. use serde_json::Serializer;
  94. use space_crush_common::misc::{PersistWorld, WorldHelper};
  95. let vfs = world.resource::<Vfs>()?;
  96. let mut file = vfs.join(path)?.create_file()?;
  97. let mut serializer = Serializer::new(&mut file);
  98. world.serialize(PersistWorld, &mut serializer)?;
  99. Ok(())
  100. }
  101. const WORLD_FILEPATH: &str = "resources/world.json";