Skip to content

Commit

Permalink
Simplify timer API
Browse files Browse the repository at this point in the history
  • Loading branch information
Shatur committed Oct 21, 2024
1 parent 48bd8fe commit 31b8712
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 47 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Replace `with_held_timer` with `relative_speed` that just accepts a boolean.
- Rename `HeldTimer` into `ConditionTimer`.
- Use Use `trace!` instead of `debug!` for triggered events.

## [0.1.0] - 2024-10-20
Expand Down
2 changes: 1 addition & 1 deletion src/input_context/input_condition.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub mod blocked_by;
pub mod chord;
pub mod condition_timer;
pub mod down;
pub mod held_timer;
pub mod hold;
pub mod hold_and_release;
pub mod pressed;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,18 @@ use bevy::prelude::*;

/// Helper for building triggers that have firing conditions governed by elapsed time.
#[derive(Clone, Copy, Default, Debug)]
pub struct HeldTimer {
pub struct ConditionTimer {
/// If set to `true`, [`Time::relative_speed`] will be applied to the held duration.
///
/// By default is set to `false`.
pub relative_to_speed: bool,
pub relative_speed: bool,

duration: f32,
}

impl HeldTimer {
pub fn relative_to_speed(relative_to_speed: bool) -> Self {
Self {
relative_to_speed,
duration: 0.0,
}
}

impl ConditionTimer {
pub fn update(&mut self, world: &World, mut delta: f32) {
if self.relative_to_speed {
if self.relative_speed {
let time = world.resource::<Time<Virtual>>();
delta *= time.relative_speed()
}
Expand Down Expand Up @@ -48,7 +41,8 @@ mod tests {
let mut world = World::new();
world.insert_resource(time);

let mut timer = HeldTimer::relative_to_speed(true);
let mut timer = ConditionTimer::default();
timer.relative_speed = true;
timer.update(&world, 1.0);
assert_eq!(timer.duration(), 0.5);
}
Expand Down
17 changes: 9 additions & 8 deletions src/input_context/input_condition/hold.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{held_timer::HeldTimer, InputCondition, DEFAULT_ACTUATION};
use super::{condition_timer::ConditionTimer, InputCondition, DEFAULT_ACTUATION};
use crate::{
action_value::ActionValue,
input_context::{context_instance::ActionContext, input_action::ActionState},
Expand All @@ -20,7 +20,7 @@ pub struct Hold {
/// Trigger threshold.
pub actuation: f32,

held_timer: HeldTimer,
timer: ConditionTimer,

fired: bool,
}
Expand All @@ -32,7 +32,7 @@ impl Hold {
hold_time,
one_shot: false,
actuation: DEFAULT_ACTUATION,
held_timer: Default::default(),
timer: Default::default(),
fired: false,
}
}
Expand All @@ -49,9 +49,10 @@ impl Hold {
self
}

/// Enables or disables time dilation.
#[must_use]
pub fn with_held_timer(mut self, held_timer: HeldTimer) -> Self {
self.held_timer = held_timer;
pub fn relative_speed(mut self, relative: bool) -> Self {
self.timer.relative_speed = relative;
self
}
}
Expand All @@ -60,13 +61,13 @@ impl InputCondition for Hold {
fn evaluate(&mut self, ctx: &ActionContext, delta: f32, value: ActionValue) -> ActionState {
let actuated = value.is_actuated(self.actuation);
if actuated {
self.held_timer.update(ctx.world, delta);
self.timer.update(ctx.world, delta);
} else {
self.held_timer.reset();
self.timer.reset();
}

let is_first_trigger = !self.fired;
self.fired = self.held_timer.duration() >= self.hold_time;
self.fired = self.timer.duration() >= self.hold_time;

if self.fired {
if is_first_trigger || !self.one_shot {
Expand Down
17 changes: 9 additions & 8 deletions src/input_context/input_condition/hold_and_release.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{held_timer::HeldTimer, InputCondition, DEFAULT_ACTUATION};
use super::{condition_timer::ConditionTimer, InputCondition, DEFAULT_ACTUATION};
use crate::{
action_value::ActionValue,
input_context::{context_instance::ActionContext, input_action::ActionState},
Expand All @@ -16,7 +16,7 @@ pub struct HoldAndRelease {
/// Trigger threshold.
pub actuation: f32,

held_timer: HeldTimer,
timer: ConditionTimer,
}

impl HoldAndRelease {
Expand All @@ -25,7 +25,7 @@ impl HoldAndRelease {
Self {
hold_time,
actuation: DEFAULT_ACTUATION,
held_timer: Default::default(),
timer: Default::default(),
}
}

Expand All @@ -35,9 +35,10 @@ impl HoldAndRelease {
self
}

/// Enables or disables time dilation.
#[must_use]
pub fn with_held_timer(mut self, held_timer: HeldTimer) -> Self {
self.held_timer = held_timer;
pub fn relative_speed(mut self, relative: bool) -> Self {
self.timer.relative_speed = relative;
self
}
}
Expand All @@ -47,13 +48,13 @@ impl InputCondition for HoldAndRelease {
// Evaluate the updated held duration prior to checking for actuation.
// This stops us failing to trigger if the input is released on the
// threshold frame due to held duration being 0.
self.held_timer.update(ctx.world, delta);
let held_duration = self.held_timer.duration();
self.timer.update(ctx.world, delta);
let held_duration = self.timer.duration();

if value.is_actuated(self.actuation) {
ActionState::Ongoing
} else {
self.held_timer.reset();
self.timer.reset();
// Trigger if we've passed the threshold and released.
if held_duration >= self.hold_time {
ActionState::Fired
Expand Down
17 changes: 9 additions & 8 deletions src/input_context/input_condition/pulse.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{held_timer::HeldTimer, InputCondition, DEFAULT_ACTUATION};
use super::{condition_timer::ConditionTimer, InputCondition, DEFAULT_ACTUATION};
use crate::{
action_value::ActionValue,
input_context::{context_instance::ActionContext, input_action::ActionState},
Expand All @@ -24,7 +24,7 @@ pub struct Pulse {
/// Trigger threshold.
pub actuation: f32,

held_timer: HeldTimer,
timer: ConditionTimer,

trigger_count: u32,
}
Expand All @@ -38,7 +38,7 @@ impl Pulse {
trigger_on_start: true,
trigger_count: 0,
actuation: DEFAULT_ACTUATION,
held_timer: Default::default(),
timer: Default::default(),
}
}

Expand All @@ -60,17 +60,18 @@ impl Pulse {
self
}

/// Enables or disables time dilation.
#[must_use]
pub fn with_held_timer(mut self, held_timer: HeldTimer) -> Self {
self.held_timer = held_timer;
pub fn relative_speed(mut self, relative: bool) -> Self {
self.timer.relative_speed = relative;
self
}
}

impl InputCondition for Pulse {
fn evaluate(&mut self, ctx: &ActionContext, delta: f32, value: ActionValue) -> ActionState {
if value.is_actuated(self.actuation) {
self.held_timer.update(ctx.world, delta);
self.timer.update(ctx.world, delta);

if self.trigger_limit == 0 || self.trigger_count < self.trigger_limit {
let trigger_count = if self.trigger_on_start {
Expand All @@ -80,7 +81,7 @@ impl InputCondition for Pulse {
};

// If the repeat count limit has not been reached.
if self.held_timer.duration() >= self.interval * trigger_count as f32 {
if self.timer.duration() >= self.interval * trigger_count as f32 {
// Trigger when held duration exceeds the interval threshold.
self.trigger_count += 1;
ActionState::Fired
Expand All @@ -91,7 +92,7 @@ impl InputCondition for Pulse {
ActionState::None
}
} else {
self.held_timer.reset();
self.timer.reset();

self.trigger_count = 0;
ActionState::None
Expand Down
19 changes: 10 additions & 9 deletions src/input_context/input_condition/tap.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{held_timer::HeldTimer, InputCondition, DEFAULT_ACTUATION};
use super::{condition_timer::ConditionTimer, InputCondition, DEFAULT_ACTUATION};
use crate::{
action_value::ActionValue,
input_context::{context_instance::ActionContext, input_action::ActionState},
Expand All @@ -16,7 +16,7 @@ pub struct Tap {
/// Trigger threshold.
pub actuation: f32,

held_timer: HeldTimer,
timer: ConditionTimer,
actuated: bool,
}

Expand All @@ -26,7 +26,7 @@ impl Tap {
Self {
release_time,
actuation: DEFAULT_ACTUATION,
held_timer: Default::default(),
timer: Default::default(),
actuated: false,
}
}
Expand All @@ -37,28 +37,29 @@ impl Tap {
self
}

/// Enables or disables time dilation.
#[must_use]
pub fn with_held_timer(mut self, held_timer: HeldTimer) -> Self {
self.held_timer = held_timer;
pub fn relative_speed(mut self, relative: bool) -> Self {
self.timer.relative_speed = relative;
self
}
}

impl InputCondition for Tap {
fn evaluate(&mut self, ctx: &ActionContext, delta: f32, value: ActionValue) -> ActionState {
let last_actuated = self.actuated;
let last_held_duration = self.held_timer.duration();
let last_held_duration = self.timer.duration();
self.actuated = value.is_actuated(self.actuation);
if self.actuated {
self.held_timer.update(ctx.world, delta);
self.timer.update(ctx.world, delta);
} else {
self.held_timer.reset();
self.timer.reset();
}

if last_actuated && !self.actuated && last_held_duration <= self.release_time {
// Only trigger if pressed then released quickly enough.
ActionState::Fired
} else if self.held_timer.duration() >= self.release_time {
} else if self.timer.duration() >= self.release_time {
// Once we pass the threshold halt all triggering until released.
ActionState::None
} else if self.actuated {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub mod prelude {
},
input_action::{Accumulation, ActionEvent, ActionEventKind, ActionState, InputAction},
input_condition::{
blocked_by::*, chord::*, down::*, held_timer::*, hold::*, hold_and_release::*,
blocked_by::*, chord::*, condition_timer::*, down::*, hold::*, hold_and_release::*,
pressed::*, pulse::*, released::*, tap::*, ConditionKind, InputCondition,
},
input_modifier::{
Expand Down

0 comments on commit 31b8712

Please sign in to comment.