Skip to content

Commit

Permalink
Merge pull request #6 from shanecelis/systems-are-the-answer
Browse files Browse the repository at this point in the history
Systems are the answer!
  • Loading branch information
not-elm authored Apr 22, 2024
2 parents 590ced1 + 133fa26 commit 085d1d6
Show file tree
Hide file tree
Showing 19 changed files with 1,630 additions and 1,188 deletions.
19 changes: 17 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,28 @@

All notable changes to this project will be documented in this file.

## [released]
## [unreleased]

### Features

- Generalize to running one-shot systems instead of firing events.
- Use a plugin, can configure schedule and system set.
- Remove `GamepadEvent`; use system with input `In<Gamepad>`.
- Add IntoCondSystem that adds `only_if()` conditions to `IntoSystems`.
- Add `only_if` example.
- Add prelude module for glob imports.

### Refactor

- Hollow out lib so it's just `mod` and `pub use` statements.
- Extract sets of functionality from `lib.rs` into `chord.rs`, `cache.rs` and `plugin.rs`.
- Extract simulated tests into `tests/` directory.

## [0.3.0] - 2024-03-08

### Features

- Removed `Act::Any`, so We can no longer define an act composed of multiple buttons(or keycodes).
- Removed `Act::Any`, so we can no longer define an act composed of multiple buttons(or keycodes).
- The keyboard and gamepad now use different sequences.


Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ path = "examples/multiple_input.rs"

[dependencies]
bevy = { version = "0.13", default-features = false, features = [] }
trie-rs = { version = "0.2" }
keyseq = { version = "0.2.2", features = [ "bevy" ] }
trie-rs = { version = "0.3" }
keyseq = { version = "0.2.3", features = [ "bevy" ] }

[dev-dependencies]
bevy = "0.13"
Expand Down
223 changes: 114 additions & 109 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# bevy-input-sequence

This crate recognizes input sequences and sends events.
This crate recognizes input sequences from keyboard and gamepad.

# Use cases
# Use Cases

* Hotkeys
* Cheat codes
Expand All @@ -14,46 +14,125 @@ This crate recognizes input sequences and sends events.
cargo install bevy-input-sequence
```

# Usage
# Code Examples

## Import symbols
Here are some code snippets. These also run as doctests so they do a few things
differently than a regular runnable example:

```rust ignore
- Use `MinimalPlugins` instead of `DefaultPlugins`,
- and call `app.update()` instead of `app.run()`.

The next section describes the runnable examples that come with the crate.

## Run a System on a Key Sequence

Runs a system whenever the user presses the key sequence `H I` or "hi" within a
time limit.

```rust
use bevy::prelude::*;
use bevy_input_sequence::*;
use bevy_input_sequence::prelude::*;

fn main() {
App::new()
.add_plugins(MinimalPlugins)
.add_plugins(InputSequencePlugin::default())
.add_systems(Startup, setup)
.update(); // Normally you'd run it here.
}

fn setup(mut commands: Commands) {
commands.add(
KeySequence::new(say_hello,
keyseq! { H I })
.time_limit(Duration::from_secs(2))
);
}

fn say_hello() {
info!("hello");
}
```

## Define an event
## Send an Event on Key Sequence

Originally `bevy-input-sequence` always send an event. You can still do that
with the `action::send_event()`.

```rust
use bevy::prelude::*;
use bevy_input_sequence::prelude::*;

```rust ignore
// Define an event
#[derive(Event, Clone, Debug)]
struct MyEvent;
```

## Add event as an key sequence

```rust ignore
// Add event as an key sequence
fn main() {
App::new()
.add_key_sequence_event::<MyEvent>()
.run()
.add_plugins(MinimalPlugins)
.add_plugins(InputSequencePlugin::default())
.add_event::<MyEvent>()
.add_systems(Startup, setup)
.update(); // Normally you'd run it here.
}

fn setup(mut commands: Commands) {
commands.add(
KeySequence::new(action::send_event(MyEvent),
keyseq! { ctrl-E L M })
);
}

fn check_events(mut events: EventReader<MyEvent>) {
for event in events.read() {
info!("got event {event:?}");
}
}
```

## Add a key sequence component
## Send an Event on Gamepad Button Sequence

So long as one component is present, it will fire one event when the input
sequence is entered. This crate re-exports the `keyseq!` macro for bevy from the [keyseq](https://crates.io/crates/keyseq) crate.
Gamepads have something that keyboards don't: identity problems. Which player
hit the button sequence may be important to know. So the systems it accepts will
take an input of `Gamepad`.

```rust
use bevy::prelude::*;
use bevy_input_sequence::prelude::*;

// Define an event
#[derive(Event, Clone, Debug)]
struct MyEvent(Gamepad);

// Add event as an key sequence
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.add_plugins(InputSequencePlugin::default())
.add_event::<MyEvent>()
.add_systems(Startup, setup)
.update(); // Normally you'd run it here.
}

```rust ignore
fn setup(mut commands: Commands) {
commands.spawn(
KeySequence::new(MyEvent, keyseq! { alt-X M })
commands.add(
ButtonSequence::new(action::send_event_with_input(|gamepad| MyEvent(gamepad)),
[GamepadButtonType::North,
GamepadButtonType::East,
GamepadButtonType::South,
GamepadButtonType::West])
);
}

fn check_events(mut events: EventReader<MyEvent>) {
for event in events.read() {
info!("got event {event:?}");
}
}
```

# Examples
# Runnable Examples

## keycode

Expand Down Expand Up @@ -96,108 +175,34 @@ be recognized from the controller. But a mixed sequence like `W D A X` will not
currently be recognized. If this should be done and how exactly one should do it
are under consideration. Please open an issue or PR if you have thoughts on this.

## run_if
## only_if

The `run_if` example recognizes `Space` and fires an event if it's in game mode.
The `Escape` key toggles the app betwee n menu and game mode.
The `only_if` example recognizes `Space` and fires an event if it's in game
mode. The `Escape` key toggles the app between menu and game mode. It does this
by only sending the `Space` event if it's in game mode.

``` sh
cargo run --example run_if
```

# Advanced Usage

## Fire event on gamepad button sequence

Define an event

```rust ignore
#[derive(Event, Clone, Debug)]
struct MyEvent(Gamepad);

impl GamepadEvent for MyEvent {
fn gamepad(&self) -> Option<Gamepad> {
Some(self.0)
}

fn set_gamepad(&mut self, gamepad: Gamepad) {
self.0 = gamepad;
}
}

```

Add event as a button sequence.

```rust ignore
fn main() {
App::new()
.add_button_sequence_event::<MyEvent>()
.run()
}
```

Add a button sequence component.

```rust ignore
fn setup(mut commands: Commands) {
commands.spawn(ButtonSequence::new(
MyEvent(Gamepad { id: 999 }),
[
GamepadButtonType::North,
GamepadButtonType::East,
GamepadButtonType::South,
GamepadButtonType::West,
],
));
println!("Press north, east, south, west to emit MyEvent.");
}
cargo run --example only_if
```

## Add an event with a condition

Some key sequences you may only what to fire in particular modes. You can supply
a condition that will only run if it's met. This works nicely with bevy `States`
for example.

```rust ignore
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)]
enum AppState {
#[default]
Menu,
Game,
}

fn main() {
App::new()
.add_key_sequence_event_run_if::<MyEvent, _>(in_state(AppState::Menu))
.run()
}
```

See the "run_if" example for more details.

## Add a input sequence component with a time limit
## run_if

Input sequences can have time limits. Sequences must be completed within the
time limit in order to fire the event.
The `run_if` has the same behavior as `only_if` but achieves it differently. It
places the `InputSequencePlugin` systems in a system set that is configured to
only run in game mode. Because of this the `Escape` key which toggles between
game and menu mode cannot be a `KeySequence`.

```rust ignore
fn setup(mut commands: Commands) {
commands.spawn(
KeySequence::new(MyEvent, keyseq! { alt-X M })
.time_limit(Duration::from_secs(1)),
);
}
``` sh
cargo run --example run_if
```

# Compatibility

| bevy-input-sequence | bevy |
| ------------------- | ---- |
| 0.1 | 0.11 |
| 0.2 | 0.12 |
| 0.3 | 0.13 |
| 0.2 | 0.12 |
| 0.1 | 0.11 |

# License

Expand Down
Loading

0 comments on commit 085d1d6

Please sign in to comment.