Skip to content

Commit

Permalink
Remove FrameCount in favor of Bevy counterpart (#38)
Browse files Browse the repository at this point in the history
* Remove FrameCount in favor of bevy counterpart

* draft release notes for this change
  • Loading branch information
snendev authored Aug 22, 2024
1 parent e779860 commit ec76962
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 75 deletions.
5 changes: 5 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Release Notes

## Version 0.6 (Draft)

- migrated to Bevy 0.14
- replaced `FrameCount` with its Bevy counterpart and updated system scheduling constraints to match the new `FrameCount`'s behavior, which updates in `Last` rather than `First`

## Version 0.5

- migrated to Bevy 0.13
Expand Down
44 changes: 0 additions & 44 deletions src/frame_counting.rs

This file was deleted.

13 changes: 4 additions & 9 deletions src/input_capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
//!
//! These are unified into a single [`TimestampedInputs`](crate::timestamped_input::TimestampedInputs) resource, which can be played back.

use bevy::app::{App, AppExit, First, Last, Plugin};
use bevy::app::{App, AppExit, Last, Plugin};
use bevy::core::{update_frame_count, FrameCount};
use bevy::ecs::prelude::*;
use bevy::input::gamepad::GamepadEvent;
use bevy::input::keyboard::KeyboardInput;
Expand All @@ -11,7 +12,6 @@ use bevy::time::Time;
use bevy::window::CursorMoved;
use ron::ser::PrettyConfig;

use crate::frame_counting::{frame_counter, FrameCount};
use crate::serde::PlaybackFilePath;
use crate::timestamped_input::TimestampedInputs;
use std::fs::OpenOptions;
Expand All @@ -27,12 +27,6 @@ pub struct InputCapturePlugin;

impl Plugin for InputCapturePlugin {
fn build(&self, app: &mut App) {
// Avoid double-adding frame_counter
if !app.world().contains_resource::<FrameCount>() {
app.init_resource::<FrameCount>()
.add_systems(First, frame_counter);
}

app.init_resource::<TimestampedInputs>()
.init_resource::<InputModesCaptured>()
.init_resource::<PlaybackFilePath>()
Expand All @@ -43,7 +37,8 @@ impl Plugin for InputCapturePlugin {
capture_input,
serialize_captured_input_on_exit,
)
.chain(),
.chain()
.before(update_frame_count),
);
}
}
Expand Down
19 changes: 8 additions & 11 deletions src/input_playback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! These are played back by emulating assorted Bevy input events.

use bevy::app::{App, AppExit, First, Plugin, Startup};
use bevy::core::FrameCount;
use bevy::ecs::{prelude::*, system::SystemParam};
use bevy::input::gamepad::GamepadEvent;
use bevy::input::{
Expand All @@ -16,7 +17,6 @@ use bevy::window::{CursorMoved, Window};
use ron::de::from_reader;
use std::fs::File;

use crate::frame_counting::{frame_counter, FrameCount};
use crate::serde::PlaybackFilePath;
use crate::timestamped_input::{TimestampedInputEvent, TimestampedInputs};

Expand All @@ -30,18 +30,15 @@ pub struct InputPlaybackPlugin;

impl Plugin for InputPlaybackPlugin {
fn build(&self, app: &mut App) {
// Avoid double-adding frame_counter
if !app.world().contains_resource::<FrameCount>() {
app.init_resource::<FrameCount>()
.add_systems(First, frame_counter.after(bevy::ecs::event::EventUpdates));
}

app.init_resource::<TimestampedInputs>()
.init_resource::<PlaybackProgress>()
.init_resource::<PlaybackStrategy>()
.init_resource::<PlaybackFilePath>()
.add_systems(Startup, deserialize_timestamped_inputs)
.add_systems(First, playback_timestamped_input.after(frame_counter));
.add_systems(
First,
playback_timestamped_input.after(bevy::ecs::event::EventUpdates),
);
}
}

Expand Down Expand Up @@ -249,7 +246,7 @@ impl PlaybackProgress {
///
/// Panics if `self.initial_frame` is `None`. Make sure to call `set_initial_frame` first!
pub fn current_frame(&self, start: FrameCount) -> FrameCount {
start + self.elapsed_frames
FrameCount(start.0.wrapping_add(self.elapsed_frames.0))
}

/// Gets the current time.
Expand All @@ -265,7 +262,7 @@ impl PlaybackProgress {
///
/// This also records that one frame has elapsed.
pub fn next_frame(&mut self, start: FrameCount) -> FrameCount {
self.elapsed_frames = self.elapsed_frames + FrameCount(1);
self.elapsed_frames = FrameCount(self.elapsed_frames.0.wrapping_add(1));
// The frame count has been advanced, so this returns the correct value
self.current_frame(start)
}
Expand Down Expand Up @@ -315,7 +312,7 @@ mod tests {

let delta = FrameCount(1);
let next_frame = progress.next_frame(start);
assert_eq!(next_frame, start + delta);
assert_eq!(next_frame.0, start.0.wrapping_add(delta.0));
assert_eq!(progress.elapsed_frames, delta);
}
}
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#![warn(clippy::doc_markdown)]
#![doc = include_str!("../README.md")]

pub mod frame_counting;
pub mod input_capture;
pub mod input_playback;
pub mod serde;
Expand Down
3 changes: 1 addition & 2 deletions src/timestamped_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! Those timestamped events are finally stored inside of a [`TimestampedInputs`] resource, which should be used for input capture and playback.

use bevy::app::AppExit;
use bevy::core::FrameCount;
use bevy::ecs::prelude::*;
use bevy::input::gamepad::GamepadEvent;
use bevy::input::keyboard::KeyboardInput;
Expand All @@ -11,8 +12,6 @@ use bevy::utils::Duration;
use bevy::window::CursorMoved;
use serde::{Deserialize, Serialize};

use crate::frame_counting::FrameCount;

/// A timestamped device-agnostic user-input event
///
/// These are re-emitted as events, and commonly serialized to disk
Expand Down
8 changes: 3 additions & 5 deletions tests/input_capture.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use bevy::core::FrameCount;
use bevy::input::keyboard::Key;
use bevy::input::keyboard::KeyboardInput;
use bevy::input::mouse::MouseButtonInput;
Expand All @@ -6,7 +7,6 @@ use bevy::input::InputPlugin;
use bevy::prelude::*;

use bevy::window::WindowPlugin;
use leafwing_input_playback::frame_counting::FrameCount;
use leafwing_input_playback::input_capture::{InputCapturePlugin, InputModesCaptured};
use leafwing_input_playback::timestamped_input::{
InputEvent, TimestampedInputEvent, TimestampedInputs,
Expand Down Expand Up @@ -105,10 +105,8 @@ fn framecount_of_sent_events() {
let first_event: TimestampedInputEvent = iterator.next().expect("Keyboard event failed.");
let second_event: TimestampedInputEvent = iterator.next().expect("Mouse event failed.");

// The frame count is recorded based on the frame it is read,
// which counts up immediately
assert_eq!(first_event.frame, FrameCount(1));
assert_eq!(second_event.frame, FrameCount(2));
assert_eq!(first_event.frame, FrameCount(0));
assert_eq!(second_event.frame, FrameCount(1));
}

#[test]
Expand Down
10 changes: 7 additions & 3 deletions tests/input_playback.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// BLOCKED: add time strategy tests: https://github.com/bevyengine/bevy/issues/6146

use bevy::core::FrameCount;
use bevy::ecs::event::EventRegistry;
use bevy::input::keyboard::Key;
use bevy::input::keyboard::KeyboardInput;
Expand All @@ -10,7 +11,6 @@ use bevy::time::TimeUpdateStrategy;
use bevy::utils::Duration;
use bevy::window::WindowPlugin;

use leafwing_input_playback::frame_counting::FrameCount;
use leafwing_input_playback::input_capture::InputCapturePlugin;
use leafwing_input_playback::input_capture::InputModesCaptured;
use leafwing_input_playback::input_playback::InputPlaybackPlugin;
Expand Down Expand Up @@ -51,8 +51,8 @@ fn playback_app(strategy: PlaybackStrategy) -> App {

fn simple_timestamped_input() -> TimestampedInputs {
let mut inputs = TimestampedInputs::default();
inputs.send(FrameCount(1), Duration::from_secs(0), TEST_PRESS.into());
inputs.send(FrameCount(2), Duration::from_secs(0), TEST_RELEASE.into());
inputs.send(FrameCount(0), Duration::from_secs(0), TEST_PRESS.into());
inputs.send(FrameCount(1), Duration::from_secs(0), TEST_RELEASE.into());

inputs
}
Expand Down Expand Up @@ -178,6 +178,10 @@ fn playback_strategy_frame() {
assert_eq!(timestamped_input.cursor, 0);

// Check complex_timestamped_input to verify the pattern
app.update();
let timestamped_input = app.world().resource::<TimestampedInputs>();
assert_eq!(timestamped_input.cursor, 1);

app.update();
let timestamped_input = app.world().resource::<TimestampedInputs>();
assert_eq!(timestamped_input.cursor, 2);
Expand Down

0 comments on commit ec76962

Please sign in to comment.