Browse Source

Add a carpet-specific wrapper over a specs world

Getty Ritter 4 years ago
parent
commit
a7d915dc4e
4 changed files with 67 additions and 21 deletions
  1. 2 0
      Cargo.lock
  2. 2 0
      carpet/Cargo.toml
  3. 60 2
      carpet/src/lib.rs
  4. 3 19
      ch1/src/main.rs

+ 2 - 0
Cargo.lock

@@ -225,6 +225,8 @@ name = "carpet"
 version = "0.1.0"
 dependencies = [
  "ggez 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "specs 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winit 0.19.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]

+ 2 - 0
carpet/Cargo.toml

@@ -8,3 +8,5 @@ edition = "2018"
 
 [dependencies]
 ggez = "*"
+specs = "*"
+winit = "*"

+ 60 - 2
carpet/src/lib.rs

@@ -1,6 +1,7 @@
 use ggez::graphics::spritebatch::{SpriteBatch, SpriteIdx};
 use ggez::graphics::{DrawParam, Drawable, Image};
 use ggez::{Context, GameError};
+use specs::WorldExt;
 use std::path::Path;
 
 #[derive(Eq, PartialEq, Debug, Copy, Clone)]
@@ -26,7 +27,7 @@ impl From<Color> for ggez::graphics::Color {
 /// identifiers we care about should at least be `Clone`, but often
 /// they'll be (wrappers over) small identifiers (like a `u8` or a
 /// `u16`) and could probably be `Copy`.
-pub trait Tile: Clone {
+pub trait Tile: Clone + Send + Sync {
     fn to_location(self) -> [f32;4];
     fn blank() -> Self;
 }
@@ -190,7 +191,7 @@ impl<Idx: Tile> Board<Idx> {
         self.tileset.batch.set(self.contents[idx].1, param).unwrap();
     }
 
-    pub fn get(&mut self, at: impl Into<Coord>) -> Idx {
+    pub fn get(&self, at: impl Into<Coord>) -> Idx {
         let at = at.into();
         let idx = at.x + at.y * self.size.width;
         self.contents[idx].0.clone()
@@ -217,3 +218,60 @@ impl Board<CP437> {
         }
     }
 }
+
+
+
+pub struct Game<Idx> {
+    pub world: specs::World,
+    idx: std::marker::PhantomData<Idx>,
+}
+
+
+impl<Idx: Tile + 'static> Game<Idx> {
+    pub fn create(_name: &str, _author: &str, board: Board<Idx>) -> Result<Game<Idx>, ggez::GameError> {
+        let mut world = specs::World::new();
+        world.insert(board);
+        Ok(Game {
+            world,
+            idx: std::marker::PhantomData,
+        })
+    }
+
+    pub fn set(&mut self, at: impl Into<Coord>, ch: Idx) {
+        self.world.fetch_mut::<Board<Idx>>().set(at, ch)
+    }
+
+    pub fn set_with_color(
+        &mut self,
+        at: impl Into<Coord>,
+        ch: Idx,
+        color: impl Into<ggez::graphics::Color>,
+    ) {
+        self.world
+            .fetch_mut::<Board<Idx>>()
+            .set_with_color(at, ch, color)
+    }
+
+    pub fn get(&self, at: impl Into<Coord>) -> Idx {
+        self.world.fetch::<Board<Idx>>().get(at)
+    }
+}
+
+impl Game<CP437> {
+    pub fn print(&mut self, at: impl Into<Coord>, msg: &str) {
+        self.world.fetch_mut::<Board<CP437>>().print(at, msg)
+    }
+}
+
+
+impl<Idx: 'static + Tile> ggez::event::EventHandler for Game<Idx> {
+    fn draw(&mut self, ctx: &mut Context) -> Result<(), ggez::GameError> {
+        ggez::graphics::clear(ctx, ggez::graphics::BLACK);
+        self.world.fetch::<Board<Idx>>().draw(ctx)?;
+        ggez::graphics::present(ctx)
+    }
+
+    fn update(&mut self, _ctx: &mut Context) -> Result<(), ggez::GameError> {
+        Ok(())
+    }
+}

+ 3 - 19
ch1/src/main.rs

@@ -1,20 +1,4 @@
-use ggez::{event::EventHandler, Context, GameError};
-
-struct State {
-    board: carpet::Board<carpet::CP437>,
-}
-
-impl EventHandler for State {
-    fn draw(&mut self, ctx: &mut Context) -> Result<(), GameError> {
-        ggez::graphics::clear(ctx, ggez::graphics::BLACK);
-        self.board.draw(ctx)?;
-        ggez::graphics::present(ctx)
-    }
-
-    fn update(&mut self, _ctx: &mut Context) -> Result<(), GameError> {
-        Ok(())
-    }
-}
+use ggez::GameError;
 
 fn main() -> Result<(), GameError> {
     let (mut ctx, mut evloop) = ggez::ContextBuilder::new("game", "me")
@@ -33,6 +17,6 @@ fn main() -> Result<(), GameError> {
     let tileset = carpet::Tileset::from_file(&mut ctx, [8, 8], "/terminal8x8.jpg")?;
     let mut board = carpet::Board::new([80, 50], tileset);
     board.print([1, 1], "Hello, world!");
-    let mut state = State { board };
-    ggez::event::run(&mut ctx, &mut evloop, &mut state)
+    let mut game = carpet::Game::create("game", "me", board)?;
+    ggez::event::run(&mut ctx, &mut evloop, &mut game)
 }