diff --git a/Cargo.toml b/Cargo.toml index 8a021a3..ed77c8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,12 +21,12 @@ members = ["./", "tools/ci"] default = [] [dependencies] -bevy = {version ="0.10", default_features = false, features = ["serialize"]} +bevy = {version = "0.12", default_features = false, features = ["serialize"]} serde = {version = "1.0", features = ["derive"]} ron = "0.8" [dev-dependencies] -bevy = {version ="0.10", default_features = true, features = ["serialize"]} +bevy = {version = "0.12", default_features = true, features = ["serialize"]} [lib] name = "leafwing_input_playback" diff --git a/examples/gamepad.rs b/examples/gamepad.rs index 71ece22..73b54c4 100644 --- a/examples/gamepad.rs +++ b/examples/gamepad.rs @@ -17,15 +17,17 @@ fn main() { App::new() // This plugin contains all the code from the original example - .add_plugin(GamepadViewerExample) - .add_plugin(InputCapturePlugin) - .add_plugin(InputPlaybackPlugin) + .add_plugins(( + GamepadViewerExample, + InputCapturePlugin, + InputPlaybackPlugin, + )) // Disable all input capture and playback to start .insert_resource(InputModesCaptured::DISABLE_ALL) .insert_resource(PlaybackStrategy::Paused) // Toggle between playback and capture using Space .insert_resource(InputStrategy::Playback) - .add_system(toggle_capture_vs_playback) + .add_systems(Update, toggle_capture_vs_playback) .run(); } @@ -88,14 +90,19 @@ mod gamepad_viewer_example { .init_resource::() .init_resource::() .init_resource::() - .add_startup_system(setup) - .add_startup_system(setup_sticks) - .add_startup_system(setup_triggers) - .add_startup_system(setup_connected) - .add_system(update_buttons) - .add_system(update_button_values) - .add_system(update_axes) - .add_system(update_connected); + .add_systems( + Startup, + (setup, setup_sticks, setup_triggers, setup_connected), + ) + .add_systems( + Update, + ( + update_buttons, + update_button_values, + update_axes, + update_connected, + ), + ); } } @@ -527,7 +534,7 @@ mod gamepad_viewer_example { mut events: EventReader, mut query: Query<(&mut Text, &TextWithButtonValue)>, ) { - for event in events.iter() { + for event in events.read() { if let GamepadEvent::Button(GamepadButtonChangedEvent { gamepad: _, button_type, @@ -548,7 +555,7 @@ mod gamepad_viewer_example { mut query: Query<(&mut Transform, &MoveWithAxes)>, mut text_query: Query<(&mut Text, &TextWithAxes)>, ) { - for event in events.iter() { + for event in events.read() { if let GamepadEvent::Axis(axis_changed_event) = event { let axis_type = axis_changed_event.axis_type; let value = axis_changed_event.value; diff --git a/examples/input_capture.rs b/examples/input_capture.rs index 25e9284..aacaa27 100644 --- a/examples/input_capture.rs +++ b/examples/input_capture.rs @@ -5,9 +5,8 @@ use leafwing_input_playback::{ fn main() { App::new() - .add_plugins(DefaultPlugins) - .add_plugin(InputCapturePlugin) - .add_system(debug_input_capture) + .add_plugins((DefaultPlugins, InputCapturePlugin)) + .add_systems(Update, debug_input_capture) .run() } diff --git a/examples/input_playback.rs b/examples/input_playback.rs index 8195823..b3b6ef8 100644 --- a/examples/input_playback.rs +++ b/examples/input_playback.rs @@ -8,20 +8,19 @@ use leafwing_input_playback::{ fn main() { App::new() - .add_plugins(DefaultPlugins) - .add_plugin(InputCapturePlugin) - .add_plugin(InputPlaybackPlugin) + .add_plugins((DefaultPlugins, InputCapturePlugin, InputPlaybackPlugin)) // Disable all input capture and playback to start .insert_resource(InputModesCaptured::DISABLE_ALL) .insert_resource(PlaybackStrategy::Paused) // Creates a little game that spawns decaying boxes where the player clicks .insert_resource(ClearColor(Color::rgb(0.9, 0.9, 0.9))) - .add_startup_system(setup) - .add_system(spawn_boxes) - .add_system(decay_boxes) + .add_systems(Startup, setup) + .add_systems( + Update, + (spawn_boxes, decay_boxes, toggle_capture_vs_playback), + ) // Toggle between playback and capture by pressing Space .insert_resource(InputStrategy::Playback) - .add_system(toggle_capture_vs_playback) .run() } diff --git a/examples/playback_serialized_input.rs b/examples/playback_serialized_input.rs index aa1c8ce..33a98fc 100644 --- a/examples/playback_serialized_input.rs +++ b/examples/playback_serialized_input.rs @@ -6,15 +6,14 @@ use leafwing_input_playback::serde::PlaybackFilePath; fn main() { App::new() - .add_plugins(DefaultPlugins) - .add_plugin(InputPlaybackPlugin) + .add_plugins((DefaultPlugins, InputPlaybackPlugin)) .insert_resource(PlaybackFilePath::new("./data/hello_world.ron")) - .add_system(debug_keyboard_inputs) + .add_systems(Update, debug_keyboard_inputs) .run(); } fn debug_keyboard_inputs(mut keyboard_events: EventReader) { - for keyboard_event in keyboard_events.iter() { + for keyboard_event in keyboard_events.read() { dbg!(keyboard_event); } } diff --git a/examples/serialize_captured_input.rs b/examples/serialize_captured_input.rs index 3e91024..c1d6e89 100644 --- a/examples/serialize_captured_input.rs +++ b/examples/serialize_captured_input.rs @@ -7,8 +7,7 @@ use leafwing_input_playback::serde::PlaybackFilePath; fn main() { App::new() - .add_plugins(DefaultPlugins) - .add_plugin(InputCapturePlugin) + .add_plugins((DefaultPlugins, InputCapturePlugin)) .insert_resource(PlaybackFilePath::new("./data/test_playback.ron")) // In this example, we're only capturing keyboard inputs .insert_resource(InputModesCaptured { diff --git a/examples/useless_machine.rs b/examples/useless_machine.rs index a677470..e5cd4c3 100644 --- a/examples/useless_machine.rs +++ b/examples/useless_machine.rs @@ -8,8 +8,7 @@ use leafwing_input_playback::serde::PlaybackFilePath; fn main() { App::new() - .add_plugins(DefaultPlugins) - .add_plugin(InputPlaybackPlugin) + .add_plugins((DefaultPlugins, InputPlaybackPlugin)) .insert_resource(PlaybackFilePath::new("./data/app_exit.ron")) .run(); } diff --git a/src/input_capture.rs b/src/input_capture.rs index 2dbc0f4..7bdb886 100644 --- a/src/input_capture.rs +++ b/src/input_capture.rs @@ -2,7 +2,7 @@ //! //! These are unified into a single [`TimestampedInputs`](crate::timestamped_input::TimestampedInputs) resource, which can be played back. -use bevy::app::{App, AppExit, CoreSet, Plugin}; +use bevy::app::{App, AppExit, First, Last, Plugin}; use bevy::ecs::prelude::*; use bevy::input::gamepad::GamepadEvent; use bevy::input::keyboard::KeyboardInput; @@ -30,20 +30,20 @@ impl Plugin for InputCapturePlugin { // Avoid double-adding frame_counter if !app.world.contains_resource::() { app.init_resource::() - .add_system(frame_counter.in_base_set(CoreSet::First)); + .add_systems(First, frame_counter); } app.init_resource::() .init_resource::() .init_resource::() - .add_system( - // Capture any mocked input as well - capture_input.in_base_set(CoreSet::Last), - ) - .add_system( - serialize_captured_input_on_exit - .in_base_set(CoreSet::Last) - .after(capture_input), + .add_systems( + Last, + ( + // Capture any mocked input as well + capture_input, + serialize_captured_input_on_exit, + ) + .chain(), ); } } @@ -118,33 +118,42 @@ pub fn capture_input( timestamped_input.send_multiple( frame, time_since_startup, - mouse_button_events.iter().cloned(), + mouse_button_events.read().cloned(), ); timestamped_input.send_multiple( frame, time_since_startup, - mouse_wheel_events.iter().cloned(), + mouse_wheel_events.read().cloned(), ); + } else { + mouse_button_events.clear(); + mouse_wheel_events.clear(); } if input_modes_captured.mouse_motion { timestamped_input.send_multiple( frame, time_since_startup, - cursor_moved_events.iter().cloned(), + cursor_moved_events.read().cloned(), ); + } else { + cursor_moved_events.clear(); } if input_modes_captured.keyboard { - timestamped_input.send_multiple(frame, time_since_startup, keyboard_events.iter().cloned()); + timestamped_input.send_multiple(frame, time_since_startup, keyboard_events.read().cloned()); + } else { + keyboard_events.clear() } if input_modes_captured.gamepad { - timestamped_input.send_multiple(frame, time_since_startup, gamepad_events.iter().cloned()); + timestamped_input.send_multiple(frame, time_since_startup, gamepad_events.read().cloned()); + } else { + gamepad_events.clear() } - timestamped_input.send_multiple(frame, time_since_startup, app_exit_events.iter().cloned()) + timestamped_input.send_multiple(frame, time_since_startup, app_exit_events.read().cloned()) } /// Serializes captured input to the path given in the [`PlaybackFilePath`] resource. diff --git a/src/input_playback.rs b/src/input_playback.rs index e248e81..dc51e8f 100644 --- a/src/input_playback.rs +++ b/src/input_playback.rs @@ -2,7 +2,7 @@ //! //! These are played back by emulating assorted Bevy input events. -use bevy::app::{App, AppExit, CoreSet, Plugin}; +use bevy::app::{App, AppExit, First, Plugin, Startup}; use bevy::ecs::{prelude::*, system::SystemParam}; use bevy::input::gamepad::GamepadEvent; use bevy::input::{ @@ -33,19 +33,15 @@ impl Plugin for InputPlaybackPlugin { // Avoid double-adding frame_counter if !app.world.contains_resource::() { app.init_resource::() - .add_system(frame_counter.in_base_set(CoreSet::First)); + .add_systems(First, frame_counter); } app.init_resource::() .init_resource::() .init_resource::() .init_resource::() - .add_startup_system(deserialize_timestamped_inputs) - .add_system( - playback_timestamped_input - .after(frame_counter) - .in_base_set(CoreSet::First), - ); + .add_systems(Startup, deserialize_timestamped_inputs) + .add_systems(First, playback_timestamped_input.after(frame_counter)); } } diff --git a/src/timestamped_input.rs b/src/timestamped_input.rs index 2695051..a6fdd12 100644 --- a/src/timestamped_input.rs +++ b/src/timestamped_input.rs @@ -410,11 +410,13 @@ mod tests { const LEFT_CLICK_PRESS: InputEvent = InputEvent::MouseButton(MouseButtonInput { button: MouseButton::Left, state: ButtonState::Pressed, + window: Entity::PLACEHOLDER, }); const LEFT_CLICK_RELEASE: InputEvent = InputEvent::MouseButton(MouseButtonInput { button: MouseButton::Left, state: ButtonState::Released, + window: Entity::PLACEHOLDER, }); fn complex_timestamped_input() -> TimestampedInputs { diff --git a/tests/input_capture.rs b/tests/input_capture.rs index 8f78a14..0df4830 100644 --- a/tests/input_capture.rs +++ b/tests/input_capture.rs @@ -15,26 +15,31 @@ const TEST_PRESS: KeyboardInput = KeyboardInput { scan_code: 1, key_code: Some(KeyCode::F), state: ButtonState::Pressed, + window: Entity::PLACEHOLDER, }; const TEST_RELEASE: KeyboardInput = KeyboardInput { scan_code: 1, key_code: Some(KeyCode::F), state: ButtonState::Released, + window: Entity::PLACEHOLDER, }; const TEST_MOUSE: MouseButtonInput = MouseButtonInput { button: MouseButton::Left, state: ButtonState::Pressed, + window: Entity::PLACEHOLDER, }; fn capture_app() -> App { let mut app = App::new(); - app.add_plugins(MinimalPlugins) - .add_plugin(WindowPlugin::default()) - .add_plugin(InputPlugin) - .add_plugin(InputCapturePlugin); + app.add_plugins(( + MinimalPlugins, + WindowPlugin::default(), + InputPlugin, + InputCapturePlugin, + )); app } diff --git a/tests/input_playback.rs b/tests/input_playback.rs index 9770783..84ea16c 100644 --- a/tests/input_playback.rs +++ b/tests/input_playback.rs @@ -19,21 +19,25 @@ const TEST_PRESS: KeyboardInput = KeyboardInput { scan_code: 1, key_code: Some(KeyCode::F), state: ButtonState::Pressed, + window: Entity::PLACEHOLDER, }; const TEST_RELEASE: KeyboardInput = KeyboardInput { scan_code: 1, key_code: Some(KeyCode::F), state: ButtonState::Released, + window: Entity::PLACEHOLDER, }; fn playback_app(strategy: PlaybackStrategy) -> App { let mut app = App::new(); - app.add_plugins(MinimalPlugins) - .add_plugin(WindowPlugin::default()) - .add_plugin(InputPlugin) - .add_plugin(InputPlaybackPlugin); + app.add_plugins(( + MinimalPlugins, + WindowPlugin::default(), + InputPlugin, + InputPlaybackPlugin, + )); *app.world.resource_mut::() = strategy; @@ -85,7 +89,7 @@ fn minimal_playback() { #[test] fn capture_and_playback() { let mut app = playback_app(PlaybackStrategy::default()); - app.add_plugin(InputCapturePlugin); + app.add_plugins(InputCapturePlugin); app.insert_resource(PlaybackStrategy::Paused); let mut input_events = app.world.resource_mut::>();