leafwing_input_manager/
timing.rs1use bevy::{platform::time::Instant, reflect::Reflect};
4use core::time::Duration;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, Reflect)]
12pub struct Timing {
13 #[serde(skip)]
17 pub instant_started: Option<Instant>,
18 pub current_duration: Duration,
22 pub previous_duration: Duration,
24}
25
26impl Timing {
27 pub const NEW: Timing = Timing {
29 instant_started: None,
30 current_duration: Duration::ZERO,
31 previous_duration: Duration::ZERO,
32 };
33}
34
35impl PartialOrd for Timing {
36 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
37 self.current_duration.partial_cmp(&other.current_duration)
38 }
39}
40
41impl Timing {
42 pub fn tick(&mut self, current_instant: Instant, previous_instant: Instant) {
47 if let Some(instant_started) = self.instant_started {
48 self.current_duration = current_instant - instant_started;
49 } else {
50 self.current_duration = current_instant - previous_instant;
51 self.instant_started = Some(previous_instant);
52 }
53 }
54
55 pub fn flip(&mut self) {
59 self.previous_duration = self.current_duration;
60 self.current_duration = Duration::ZERO;
61 self.instant_started = None;
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use crate as leafwing_input_manager;
68 use bevy::prelude::Reflect;
69 use leafwing_input_manager_macros::Actionlike;
70
71 #[derive(Actionlike, Clone, Copy, PartialEq, Eq, Hash, Debug, Reflect)]
72 enum Action {
73 Run,
74 Jump,
75 Hide,
76 }
77
78 #[test]
79 fn time_tick_ticks_away() {
80 use crate::action_state::ActionState;
81 use bevy::platform::time::Instant;
82 use core::time::Duration;
83
84 let mut action_state = ActionState::<Action>::default();
85
86 assert!(action_state.released(&Action::Run));
88 assert!(!action_state.just_released(&Action::Jump));
89
90 action_state.tick(Instant::now(), Instant::now() - Duration::from_micros(1));
92 assert!(action_state.released(&Action::Jump));
93 assert!(!action_state.just_released(&Action::Jump));
94 action_state.press(&Action::Jump);
95 assert!(action_state.just_pressed(&Action::Jump));
96
97 action_state.tick(Instant::now(), Instant::now() - Duration::from_micros(1));
99 assert!(action_state.pressed(&Action::Jump));
100 assert!(!action_state.just_pressed(&Action::Jump));
101 }
102
103 #[test]
104 fn durations() {
105 use crate::action_state::ActionState;
106 use bevy::platform::time::Instant;
107 use core::time::Duration;
108
109 let mut action_state = ActionState::<Action>::default();
110
111 assert!(action_state.released(&Action::Jump));
113 assert_eq!(action_state.instant_started(&Action::Jump), None,);
114 assert_eq!(action_state.current_duration(&Action::Jump), Duration::ZERO);
115 assert_eq!(
116 action_state.previous_duration(&Action::Jump),
117 Duration::ZERO
118 );
119
120 action_state.press(&Action::Jump);
122 assert!(action_state.pressed(&Action::Jump));
123 assert_eq!(action_state.instant_started(&Action::Jump), None);
124 assert_eq!(action_state.current_duration(&Action::Jump), Duration::ZERO);
125 assert_eq!(
126 action_state.previous_duration(&Action::Jump),
127 Duration::ZERO
128 );
129
130 let t0 = Instant::now();
132 let t1 = t0 + Duration::new(1, 0);
133
134 action_state.tick(t1, t0);
135 assert_eq!(action_state.instant_started(&Action::Jump), Some(t0));
136 assert_eq!(action_state.current_duration(&Action::Jump), t1 - t0);
137 assert_eq!(
138 action_state.previous_duration(&Action::Jump),
139 Duration::ZERO
140 );
141
142 let t2 = t1 + Duration::new(5, 0);
144
145 action_state.tick(t2, t1);
147 assert_eq!(action_state.instant_started(&Action::Jump), Some(t0));
148 assert_eq!(action_state.current_duration(&Action::Jump), t2 - t0);
149 assert_eq!(
150 action_state.previous_duration(&Action::Jump),
151 Duration::ZERO
152 );
153
154 action_state.release(&Action::Jump);
156 assert_eq!(action_state.instant_started(&Action::Jump), None);
157 assert_eq!(action_state.current_duration(&Action::Jump), Duration::ZERO);
158 assert_eq!(action_state.previous_duration(&Action::Jump), t2 - t0);
159 }
160}