Browse Source

InputEvents should be components, not resources

Getty Ritter 4 years ago
parent
commit
a754644818
1 changed files with 30 additions and 34 deletions
  1. 30 34
      chapter-07-damage/src/player.rs

+ 30 - 34
chapter-07-damage/src/player.rs

@@ -57,32 +57,34 @@ struct HandleInputEvent;
 
 impl<'a> System<'a> for HandleInputEvent {
     type SystemData = (
-        Write<'a, InputEvent>,
+        WriteStorage<'a, InputEvent>,
         ReadExpect<'a, Map>,
         Entities<'a>,
-        ReadStorage<'a, Player>,
         ReadStorage<'a, Position>,
         ReadStorage<'a, CombatStats>,
         WriteStorage<'a, GameEvent>,
     );
 
-    fn run(&mut self, (mut event, map, entities, player, position, stats, mut game_events): Self::SystemData) {
-        match *event {
-            InputEvent::PlayerMovement { delta_x, delta_y } => {
-                for (e, _, pos) in (&entities, &player, &position).join() {
-                    // depending on what's in the target cell, we
-                    // either want to attack or move
-                    let destination = map.xy_idx(pos.x + delta_x, pos.y + delta_y);
-                    if let Some(target) = map.get_attackable(destination, &stats) {
-                        game_events.insert(e, GameEvent::Attack { target }).expect("Unable to add GameEvent");
-                    } else {
-                        game_events.insert(e, GameEvent::MoveTo { destination }).expect("Unable to add GameEvent");
+    fn run(&mut self, (mut event, map, entities, position, stats, mut game_events): Self::SystemData) {
+        for ev in (&event).join() {
+            match *ev {
+                InputEvent::PlayerMovement { delta_x, delta_y } => {
+                    for (e, pos) in (&entities, &position).join() {
+                        // depending on what's in the target cell, we
+                        // either want to attack or move
+                        let destination = map.xy_idx(pos.x + delta_x, pos.y + delta_y);
+                        if let Some(target) = map.get_attackable(destination, &stats) {
+                            game_events.insert(e, GameEvent::Attack { target })
+                                .expect("Unable to add GameEvent");
+                        } else {
+                            game_events.insert(e, GameEvent::MoveTo { destination })
+                                .expect("Unable to add GameEvent");
+                        }
                     }
                 }
-            },
-            InputEvent::NoAction => {}
+            }
         }
-        *event = InputEvent::NoAction;
+        event.clear();
     }
 }
 
@@ -90,6 +92,7 @@ impl<'a> System<'a> for HandleInputEvent {
 /// This type represents all the "low-level" actions we have available
 /// to us, corresponding directly to the set of actions we have bound
 /// on the keys
+#[derive(Component)]
 enum InputEvent {
     // attempt to move the player some amount in the given direction
     // (delta_x and delta_y should be -1, 0, or 1)
@@ -97,49 +100,42 @@ enum InputEvent {
         delta_x: i32,
         delta_y: i32,
     },
-    // do not take any action at all
-    NoAction,
-}
-
-impl Default for InputEvent {
-    // the default for an InputEvent is of course NoAction
-    fn default() -> InputEvent {
-        InputEvent::NoAction
-    }
 }
 
 pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState {
+    let player = *gs.ecs.fetch::<Entity>();
+    let mut input = gs.ecs.write_storage::<InputEvent>();
     // Player movement
     match ctx.key {
         None => return RunState::AwaitingInput, // Nothing happened
         Some(key) => match key {
             VirtualKeyCode::Left | VirtualKeyCode::Numpad4 | VirtualKeyCode::H =>
-                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: -1, delta_y: 0 }),
+                input.insert(player, InputEvent::PlayerMovement { delta_x: -1, delta_y: 0 }),
 
             VirtualKeyCode::Right | VirtualKeyCode::Numpad6 | VirtualKeyCode::L =>
-                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: 1, delta_y: 0 }),
+                input.insert(player, InputEvent::PlayerMovement { delta_x: 1, delta_y: 0 }),
 
             VirtualKeyCode::Up | VirtualKeyCode::Numpad8 | VirtualKeyCode::K =>
-                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: 0, delta_y: -1 }),
+                input.insert(player, InputEvent::PlayerMovement { delta_x: 0, delta_y: -1 }),
 
             VirtualKeyCode::Down | VirtualKeyCode::Numpad2 | VirtualKeyCode::J =>
-                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: 0, delta_y: 1 }),
+                input.insert(player, InputEvent::PlayerMovement { delta_x: 0, delta_y: 1 }),
 
             // Diagonals
             VirtualKeyCode::Numpad9 | VirtualKeyCode::U =>
-                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: 1, delta_y: -1 }),
+                input.insert(player, InputEvent::PlayerMovement { delta_x: 1, delta_y: -1 }),
 
             VirtualKeyCode::Numpad7 | VirtualKeyCode::Y =>
-                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: -1, delta_y: -1 }),
+                input.insert(player, InputEvent::PlayerMovement { delta_x: -1, delta_y: -1 }),
 
             VirtualKeyCode::Numpad3 | VirtualKeyCode::N =>
-                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: 1, delta_y: 1 }),
+                input.insert(player, InputEvent::PlayerMovement { delta_x: 1, delta_y: 1 }),
 
             VirtualKeyCode::Numpad1 | VirtualKeyCode::B =>
-                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: -1, delta_y: 1 }),
+                input.insert(player, InputEvent::PlayerMovement { delta_x: -1, delta_y: 1 }),
 
             _ => return RunState::AwaitingInput,
         },
-    }
+    };
     RunState::PlayerTurn
 }