Browse Source

Chapter 7 is now wasm friendly.

Herbert Wolverson 5 years ago
parent
commit
0b1fecc903

+ 2 - 0
Cargo.lock

@@ -221,6 +221,8 @@ dependencies = [
  "rltk 0.3.1 (git+https://github.com/thebracket/rltk_rs)",
  "rltk 0.3.1 (git+https://github.com/thebracket/rltk_rs)",
  "specs 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "specs 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "specs-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "specs-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "web-sys 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]

+ 22 - 20
book/src/chapter_7.md

@@ -52,7 +52,7 @@ extern crate specs;
 use specs::prelude::*;
 use specs::prelude::*;
 use super::{Viewshed, Monster, Name, Map, Position};
 use super::{Viewshed, Monster, Name, Map, Position};
 extern crate rltk;
 extern crate rltk;
-use rltk::{Point};
+use rltk::{Point, console};
 
 
 pub struct MonsterAI {}
 pub struct MonsterAI {}
 
 
@@ -70,7 +70,7 @@ impl<'a> System<'a> for MonsterAI {
 
 
         for (mut viewshed,_monster,name,mut pos) in (&mut viewshed, &monster, &name, &mut position).join() {
         for (mut viewshed,_monster,name,mut pos) in (&mut viewshed, &monster, &name, &mut position).join() {
             if viewshed.visible_tiles.contains(&*player_pos) {
             if viewshed.visible_tiles.contains(&*player_pos) {
-                println!("{} shouts insults", name.name);
+                console::log(&format!("{} shouts insults", name.name));
                 let path = rltk::a_star_search(
                 let path = rltk::a_star_search(
                     map.xy_idx(pos.x, pos.y) as i32, 
                     map.xy_idx(pos.x, pos.y) as i32, 
                     map.xy_idx(player_pos.x, player_pos.y) as i32, 
                     map.xy_idx(player_pos.x, player_pos.y) as i32, 
@@ -196,18 +196,20 @@ impl<'a> System<'a> for MapIndexingSystem {
 }
 }
 ```
 ```
 
 
-This tells the map to setup blocking from the terrain, and then iterates all entities with a `BlocksTile` component, and applies them to the blocked list. We need to register it with the dispatcher; in `main.rs`:
+This tells the map to setup blocking from the terrain, and then iterates all entities with a `BlocksTile` component, and applies them to the blocked list. We need to register it with `run_systems`; in `main.rs`:
 
 
 ```rust
 ```rust
-let mut gs = State {
-    ecs: World::new(),
-    systems : DispatcherBuilder::new()
-        .with(MapIndexingSystem{}, "map_indexing_system", &[])
-        .with(VisibilitySystem{}, "visibility_system", &[])
-        .with(MonsterAI{}, "monster_ai", &["visibility_system", "map_indexing_system"])
-        .build(),
-    runstate : RunState::Running
-};
+impl State {
+    fn run_systems(&mut self) {
+        let mut mapindex = MapIndexingSystem{};
+        mapindex.run_now(&self.ecs);
+        let mut vis = VisibilitySystem{};
+        vis.run_now(&self.ecs);
+        let mut mob = MonsterAI{};
+        mob.run_now(&self.ecs);
+        self.ecs.maintain();
+    }
+}
 ```
 ```
 
 
 We didn't specify any dependencies, we're relying upon Specs to figure out if it can run concurrently with anything. We do however add it to the dependency list for `MonsterAI` - the AI relies on its results, so it has to be done.
 We didn't specify any dependencies, we're relying upon Specs to figure out if it can run concurrently with anything. We do however add it to the dependency list for `MonsterAI` - the AI relies on its results, so it has to be done.
@@ -218,7 +220,7 @@ If you `cargo run` now, monsters no longer end up on top of each other - but the
 let distance = rltk::DistanceAlg::Pythagoras.distance2d(Point::new(pos.x, pos.y), *player_pos);
 let distance = rltk::DistanceAlg::Pythagoras.distance2d(Point::new(pos.x, pos.y), *player_pos);
 if distance < 1.5 {
 if distance < 1.5 {
     // Attack goes here
     // Attack goes here
-    println!("{} shouts insults", name.name);
+    console::log(&format!("{} shouts insults", name.name));
     return;
     return;
 }
 }
 ```
 ```
@@ -408,7 +410,7 @@ for (_player, pos, viewshed) in (&mut players, &mut positions, &mut viewsheds).j
             None => {}
             None => {}
             Some(t) => {
             Some(t) => {
                 // Attack it
                 // Attack it
-                println!("From Hell's Heart, I stab thee!");
+                console::log(&format!("From Hell's Heart, I stab thee!"));
                 return; // So we don't move after attacking
                 return; // So we don't move after attacking
             }
             }
         }
         }
@@ -478,9 +480,9 @@ impl<'a> System<'a> for MeleeCombatSystem {
                     let damage = i32::max(0, stats.power - target_stats.defense);
                     let damage = i32::max(0, stats.power - target_stats.defense);
 
 
                     if damage == 0 {
                     if damage == 0 {
-                        println!("{} is unable to hurt {}", &name.name, &target_name.name);
+                        console::log(&format!("{} is unable to hurt {}", &name.name, &target_name.name));
                     } else {
                     } else {
-                        println!("{} hits {}, for {} hp.", &name.name, &target_name.name, damage);
+                        console::log(&format!("{} hits {}, for {} hp.", &name.name, &target_name.name, damage));
                         inflict_damage.insert(wants_melee.target, SufferDamage{ amount: damage }).expect("Unable to do damage");
                         inflict_damage.insert(wants_melee.target, SufferDamage{ amount: damage }).expect("Unable to do damage");
                     }
                     }
                 }
                 }
@@ -686,18 +688,18 @@ fn tick(&mut self, ctx : &mut Rltk) {
         
         
         match newrunstate {
         match newrunstate {
             RunState::PreRun => {
             RunState::PreRun => {
-                self.systems.dispatch(&self.ecs);
+                self.run_systems();
                 newrunstate = RunState::AwaitingInput;
                 newrunstate = RunState::AwaitingInput;
             }
             }
             RunState::AwaitingInput => {
             RunState::AwaitingInput => {
                 newrunstate = player_input(self, ctx);
                 newrunstate = player_input(self, ctx);
             }
             }
             RunState::PlayerTurn => {
             RunState::PlayerTurn => {
-                self.systems.dispatch(&self.ecs);
+                self.run_systems();
                 newrunstate = RunState::MonsterTurn;
                 newrunstate = RunState::MonsterTurn;
             }
             }
             RunState::MonsterTurn => {
             RunState::MonsterTurn => {
-                self.systems.dispatch(&self.ecs);
+                self.run_systems();
                 newrunstate = RunState::AwaitingInput;
                 newrunstate = RunState::AwaitingInput;
             }
             }
         }
         }
@@ -728,7 +730,7 @@ In `player.rs` we simply replace all `Paused` with `AwaitingInput`, and `Running
 
 
 Lastly, we modify `monster_ai_system` to only run if the state is `MonsterTurn` (snippet):
 Lastly, we modify `monster_ai_system` to only run if the state is `MonsterTurn` (snippet):
 
 
-```
+```rust
 impl<'a> System<'a> for MonsterAI {
 impl<'a> System<'a> for MonsterAI {
 #[allow(clippy::type_complexity)]
 #[allow(clippy::type_complexity)]
 type SystemData = ( WriteExpect<'a, Map>,
 type SystemData = ( WriteExpect<'a, Map>,

+ 4 - 0
chapter-07-damage/Cargo.toml

@@ -10,3 +10,7 @@ edition = "2018"
 rltk = { git = "https://github.com/thebracket/rltk_rs" }
 rltk = { git = "https://github.com/thebracket/rltk_rs" }
 specs = "0.15.0"
 specs = "0.15.0"
 specs-derive = "0.4.0"
 specs-derive = "0.4.0"
+
+[target.'cfg(any(target_arch = "wasm32"))'.dependencies]
+web-sys = { version = "0.3", features=["console"] }
+wasm-bindgen = "0.2"

+ 2 - 1
chapter-07-damage/src/damage_system.rs

@@ -1,6 +1,7 @@
 extern crate specs;
 extern crate specs;
 use specs::prelude::*;
 use specs::prelude::*;
 use super::{CombatStats, SufferDamage, Player};
 use super::{CombatStats, SufferDamage, Player};
+use rltk::console;
 
 
 pub struct DamageSystem {}
 pub struct DamageSystem {}
 
 
@@ -31,7 +32,7 @@ pub fn delete_the_dead(ecs : &mut World) {
                 let player = players.get(entity);
                 let player = players.get(entity);
                 match player {
                 match player {
                     None => dead.push(entity),
                     None => dead.push(entity),
-                    Some(_) => println!("You are dead")
+                    Some(_) => console::log(&format!("You are dead"))
                 }
                 }
             }
             }
         }
         }

+ 23 - 13
chapter-07-damage/src/main.rs

@@ -23,12 +23,29 @@ use melee_combat_system::MeleeCombatSystem;
 mod damage_system;
 mod damage_system;
 use damage_system::DamageSystem;
 use damage_system::DamageSystem;
 
 
+rltk::add_wasm_support!();
+
 #[derive(PartialEq, Copy, Clone)]
 #[derive(PartialEq, Copy, Clone)]
 pub enum RunState { AwaitingInput, PreRun, PlayerTurn, MonsterTurn }
 pub enum RunState { AwaitingInput, PreRun, PlayerTurn, MonsterTurn }
 
 
 pub struct State {
 pub struct State {
-    pub ecs: World,
-    pub systems: Dispatcher<'static, 'static>
+    pub ecs: World
+}
+
+impl State {
+    fn run_systems(&mut self) {
+        let mut mapindex = MapIndexingSystem{};
+        mapindex.run_now(&self.ecs);
+        let mut vis = VisibilitySystem{};
+        vis.run_now(&self.ecs);
+        let mut mob = MonsterAI{};
+        mob.run_now(&self.ecs);
+        let mut melee = MeleeCombatSystem{};
+        melee.run_now(&self.ecs);
+        let mut damage = DamageSystem{};
+        damage.run_now(&self.ecs);
+        self.ecs.maintain();
+    }
 }
 }
 
 
 impl GameState for State {
 impl GameState for State {
@@ -42,18 +59,18 @@ impl GameState for State {
         
         
         match newrunstate {
         match newrunstate {
             RunState::PreRun => {
             RunState::PreRun => {
-                self.systems.dispatch(&self.ecs);
+                self.run_systems();
                 newrunstate = RunState::AwaitingInput;
                 newrunstate = RunState::AwaitingInput;
             }
             }
             RunState::AwaitingInput => {
             RunState::AwaitingInput => {
                 newrunstate = player_input(self, ctx);
                 newrunstate = player_input(self, ctx);
             }
             }
             RunState::PlayerTurn => {
             RunState::PlayerTurn => {
-                self.systems.dispatch(&self.ecs);
+                self.run_systems();
                 newrunstate = RunState::MonsterTurn;
                 newrunstate = RunState::MonsterTurn;
             }
             }
             RunState::MonsterTurn => {
             RunState::MonsterTurn => {
-                self.systems.dispatch(&self.ecs);
+                self.run_systems();
                 newrunstate = RunState::AwaitingInput;
                 newrunstate = RunState::AwaitingInput;
             }
             }
         }
         }
@@ -78,16 +95,9 @@ impl GameState for State {
 }
 }
 
 
 fn main() {
 fn main() {
-    let context = Rltk::init_simple8x8(80, 50, "Hello Rust World", "../resources");
+    let context = Rltk::init_simple8x8(80, 50, "Hello Rust World", "resources");
     let mut gs = State {
     let mut gs = State {
         ecs: World::new(),
         ecs: World::new(),
-        systems : DispatcherBuilder::new()
-            .with(MapIndexingSystem{}, "map_indexing_system", &[])
-            .with(VisibilitySystem{}, "visibility_system", &[])
-            .with(MonsterAI{}, "monster_ai", &["visibility_system", "map_indexing_system"])
-            .with(MeleeCombatSystem{}, "melee_combat", &["monster_ai"])
-            .with(DamageSystem{}, "damage", &["melee_combat"])
-            .build(),
     };
     };
     gs.ecs.register::<Position>();
     gs.ecs.register::<Position>();
     gs.ecs.register::<Renderable>();
     gs.ecs.register::<Renderable>();

+ 3 - 2
chapter-07-damage/src/melee_combat_system.rs

@@ -1,6 +1,7 @@
 extern crate specs;
 extern crate specs;
 use specs::prelude::*;
 use specs::prelude::*;
 use super::{CombatStats, WantsToMelee, Name, SufferDamage};
 use super::{CombatStats, WantsToMelee, Name, SufferDamage};
+use rltk::console;
 
 
 pub struct MeleeCombatSystem {}
 pub struct MeleeCombatSystem {}
 
 
@@ -24,9 +25,9 @@ impl<'a> System<'a> for MeleeCombatSystem {
                     let damage = i32::max(0, stats.power - target_stats.defense);
                     let damage = i32::max(0, stats.power - target_stats.defense);
 
 
                     if damage == 0 {
                     if damage == 0 {
-                        println!("{} is unable to hurt {}", &name.name, &target_name.name);
+                        console::log(&format!("{} is unable to hurt {}", &name.name, &target_name.name));
                     } else {
                     } else {
-                        println!("{} hits {}, for {} hp.", &name.name, &target_name.name, damage);
+                        console::log(&format!("{} hits {}, for {} hp.", &name.name, &target_name.name, damage));
                         inflict_damage.insert(wants_melee.target, SufferDamage{ amount: damage }).expect("Unable to do damage");
                         inflict_damage.insert(wants_melee.target, SufferDamage{ amount: damage }).expect("Unable to do damage");
                     }
                     }
                 }
                 }

+ 1 - 0
wasmbuild.bat

@@ -6,6 +6,7 @@ CALL :Stage chapter-03-walkmap
 CALL :Stage chapter-04-newmap
 CALL :Stage chapter-04-newmap
 CALL :Stage chapter-05-fov
 CALL :Stage chapter-05-fov
 CALL :Stage chapter-06-monsters
 CALL :Stage chapter-06-monsters
+CALL :Stage chapter-07-damage
 
 
 REM Publish or perish
 REM Publish or perish
 cd book\book\wasm
 cd book\book\wasm