2021-03-05 19:59:14 +00:00
|
|
|
use crate::Stopwatch;
|
2022-05-03 19:20:13 +00:00
|
|
|
use bevy_reflect::prelude::*;
|
2020-11-22 00:38:24 +00:00
|
|
|
use bevy_utils::Duration;
|
2020-06-04 02:53:41 +00:00
|
|
|
|
2020-08-09 23:13:04 +00:00
|
|
|
/// Tracks elapsed time. Enters the finished state once `duration` is reached.
|
2020-08-21 21:57:25 +00:00
|
|
|
///
|
|
|
|
/// Non repeating timers will stop tracking and stay in the finished state until reset.
|
2021-03-11 00:27:30 +00:00
|
|
|
/// Repeating timers will only be in the finished state on each tick `duration` is reached or
|
|
|
|
/// exceeded, and can still be reset at any given point.
|
2020-11-26 19:25:36 +00:00
|
|
|
///
|
|
|
|
/// Paused timers will not have elapsed time increased.
|
bevy_reflect: `FromReflect` Ergonomics Implementation (#6056)
# Objective
**This implementation is based on
https://github.com/bevyengine/rfcs/pull/59.**
---
Resolves #4597
Full details and motivation can be found in the RFC, but here's a brief
summary.
`FromReflect` is a very powerful and important trait within the
reflection API. It allows Dynamic types (e.g., `DynamicList`, etc.) to
be formed into Real ones (e.g., `Vec<i32>`, etc.).
This mainly comes into play concerning deserialization, where the
reflection deserializers both return a `Box<dyn Reflect>` that almost
always contain one of these Dynamic representations of a Real type. To
convert this to our Real type, we need to use `FromReflect`.
It also sneaks up in other ways. For example, it's a required bound for
`T` in `Vec<T>` so that `Vec<T>` as a whole can be made `FromReflect`.
It's also required by all fields of an enum as it's used as part of the
`Reflect::apply` implementation.
So in other words, much like `GetTypeRegistration` and `Typed`, it is
very much a core reflection trait.
The problem is that it is not currently treated like a core trait and is
not automatically derived alongside `Reflect`. This makes using it a bit
cumbersome and easy to forget.
## Solution
Automatically derive `FromReflect` when deriving `Reflect`.
Users can then choose to opt-out if needed using the
`#[reflect(from_reflect = false)]` attribute.
```rust
#[derive(Reflect)]
struct Foo;
#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct Bar;
fn test<T: FromReflect>(value: T) {}
test(Foo); // <-- OK
test(Bar); // <-- Panic! Bar does not implement trait `FromReflect`
```
#### `ReflectFromReflect`
This PR also automatically adds the `ReflectFromReflect` (introduced in
#6245) registration to the derived `GetTypeRegistration` impl— if the
type hasn't opted out of `FromReflect` of course.
<details>
<summary><h4>Improved Deserialization</h4></summary>
> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.
And since we can do all the above, we might as well improve
deserialization. We can now choose to deserialize into a Dynamic type or
automatically convert it using `FromReflect` under the hood.
`[Un]TypedReflectDeserializer::new` will now perform the conversion and
return the `Box`'d Real type.
`[Un]TypedReflectDeserializer::new_dynamic` will work like what we have
now and simply return the `Box`'d Dynamic type.
```rust
// Returns the Real type
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
let mut deserializer = ron::de::Deserializer::from_str(input)?;
let output: SomeStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;
// Returns the Dynamic type
let reflect_deserializer = UntypedReflectDeserializer::new_dynamic(®istry);
let mut deserializer = ron::de::Deserializer::from_str(input)?;
let output: DynamicStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;
```
</details>
---
## Changelog
* `FromReflect` is now automatically derived within the `Reflect` derive
macro
* This includes auto-registering `ReflectFromReflect` in the derived
`GetTypeRegistration` impl
* ~~Renamed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic`, respectively~~ **Descoped**
* ~~Changed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to automatically convert the
deserialized output using `FromReflect`~~ **Descoped**
## Migration Guide
* `FromReflect` is now automatically derived within the `Reflect` derive
macro. Items with both derives will need to remove the `FromReflect`
one.
```rust
// OLD
#[derive(Reflect, FromReflect)]
struct Foo;
// NEW
#[derive(Reflect)]
struct Foo;
```
If using a manual implementation of `FromReflect` and the `Reflect`
derive, users will need to opt-out of the automatic implementation.
```rust
// OLD
#[derive(Reflect)]
struct Foo;
impl FromReflect for Foo {/* ... */}
// NEW
#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct Foo;
impl FromReflect for Foo {/* ... */}
```
<details>
<summary><h4>Removed Migrations</h4></summary>
> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.
* The reflect deserializers now perform a `FromReflect` conversion
internally. The expected output of `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` is no longer a Dynamic (e.g.,
`DynamicList`), but its Real counterpart (e.g., `Vec<i32>`).
```rust
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(®istry);
let mut deserializer = ron::de::Deserializer::from_str(input)?;
// OLD
let output: DynamicStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
// NEW
let output: SomeStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
```
Alternatively, if this behavior isn't desired, use the
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic` methods instead:
```rust
// OLD
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
// NEW
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(®istry);
```
</details>
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-06-29 01:31:34 +00:00
|
|
|
#[derive(Clone, Debug, Default, PartialEq, Eq, Reflect)]
|
2022-10-17 14:38:57 +00:00
|
|
|
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
2022-05-03 19:20:13 +00:00
|
|
|
#[reflect(Default)]
|
2020-06-04 02:53:41 +00:00
|
|
|
pub struct Timer {
|
2021-03-05 19:59:14 +00:00
|
|
|
stopwatch: Stopwatch,
|
|
|
|
duration: Duration,
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
mode: TimerMode,
|
2021-03-05 19:59:14 +00:00
|
|
|
finished: bool,
|
2022-04-26 18:42:42 +00:00
|
|
|
times_finished_this_tick: u32,
|
2020-06-04 02:53:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Timer {
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Creates a new timer with a given duration.
|
|
|
|
///
|
|
|
|
/// See also [`Timer::from_seconds`](Timer::from_seconds).
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
pub fn new(duration: Duration, mode: TimerMode) -> Self {
|
2021-03-05 19:59:14 +00:00
|
|
|
Self {
|
|
|
|
duration,
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
mode,
|
2020-06-04 02:53:41 +00:00
|
|
|
..Default::default()
|
|
|
|
}
|
|
|
|
}
|
2020-07-28 21:24:03 +00:00
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Creates a new timer with a given duration in seconds.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// ```
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
pub fn from_seconds(duration: f32, mode: TimerMode) -> Self {
|
2021-03-05 19:59:14 +00:00
|
|
|
Self {
|
|
|
|
duration: Duration::from_secs_f32(duration),
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
mode,
|
2020-06-04 02:53:41 +00:00
|
|
|
..Default::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-29 21:57:01 +00:00
|
|
|
/// Returns `true` if the timer has reached its duration.
|
|
|
|
///
|
|
|
|
/// For repeating timers, this method behaves identically to [`Timer::just_finished`].
|
2021-03-05 19:59:14 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
2023-09-29 21:57:01 +00:00
|
|
|
///
|
|
|
|
/// let mut timer_once = Timer::from_seconds(1.0, TimerMode::Once);
|
|
|
|
/// timer_once.tick(Duration::from_secs_f32(1.5));
|
|
|
|
/// assert!(timer_once.finished());
|
|
|
|
/// timer_once.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert!(timer_once.finished());
|
|
|
|
///
|
|
|
|
/// let mut timer_repeating = Timer::from_seconds(1.0, TimerMode::Repeating);
|
|
|
|
/// timer_repeating.tick(Duration::from_secs_f32(1.1));
|
|
|
|
/// assert!(timer_repeating.finished());
|
|
|
|
/// timer_repeating.tick(Duration::from_secs_f32(0.8));
|
|
|
|
/// assert!(!timer_repeating.finished());
|
|
|
|
/// timer_repeating.tick(Duration::from_secs_f32(0.6));
|
|
|
|
/// assert!(timer_repeating.finished());
|
2021-03-05 19:59:14 +00:00
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn finished(&self) -> bool {
|
|
|
|
self.finished
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Returns `true` only on the tick the timer reached its duration.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(1.5));
|
|
|
|
/// assert!(timer.just_finished());
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert!(!timer.just_finished());
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn just_finished(&self) -> bool {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick > 0
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-01-19 22:41:37 +00:00
|
|
|
/// Returns the time elapsed on the timer. Guaranteed to be between 0.0 and `duration`.
|
|
|
|
/// Will only equal `duration` when the timer is finished and non repeating.
|
2021-03-05 19:59:14 +00:00
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::elapsed`](Stopwatch::elapsed).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert_eq!(timer.elapsed(), Duration::from_secs_f32(0.5));
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn elapsed(&self) -> Duration {
|
|
|
|
self.stopwatch.elapsed()
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2022-09-26 21:47:31 +00:00
|
|
|
/// Returns the time elapsed on the timer as an `f32`.
|
2021-03-05 19:59:14 +00:00
|
|
|
/// See also [`Timer::elapsed`](Timer::elapsed).
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn elapsed_secs(&self) -> f32 {
|
|
|
|
self.stopwatch.elapsed_secs()
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Sets the elapsed time of the timer without any other considerations.
|
2020-11-26 19:25:36 +00:00
|
|
|
///
|
2021-03-05 19:59:14 +00:00
|
|
|
/// See also [`Stopwatch::set`](Stopwatch::set).
|
|
|
|
///
|
|
|
|
/// #
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.set_elapsed(Duration::from_secs(2));
|
|
|
|
/// assert_eq!(timer.elapsed(), Duration::from_secs(2));
|
|
|
|
/// // the timer is not finished even if the elapsed time is greater than the duration.
|
|
|
|
/// assert!(!timer.finished());
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn set_elapsed(&mut self, time: Duration) {
|
|
|
|
self.stopwatch.set_elapsed(time);
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Returns the duration of the timer.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let timer = Timer::new(Duration::from_secs(1), TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// assert_eq!(timer.duration(), Duration::from_secs(1));
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn duration(&self) -> Duration {
|
|
|
|
self.duration
|
2021-01-19 22:41:37 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Sets the duration of the timer.
|
2021-01-19 22:41:37 +00:00
|
|
|
///
|
2021-03-05 19:59:14 +00:00
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.5, TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.set_duration(Duration::from_secs(1));
|
|
|
|
/// assert_eq!(timer.duration(), Duration::from_secs(1));
|
|
|
|
/// ```
|
2021-01-19 22:41:37 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn set_duration(&mut self, duration: Duration) {
|
|
|
|
self.duration = duration;
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2022-11-18 20:42:33 +00:00
|
|
|
/// Returns the mode of the timer.
|
2021-03-05 19:59:14 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Repeating);
|
|
|
|
/// assert_eq!(timer.mode(), TimerMode::Repeating);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
pub fn mode(&self) -> TimerMode {
|
|
|
|
self.mode
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2022-11-18 20:42:33 +00:00
|
|
|
/// Sets the mode of the timer.
|
2021-03-05 19:59:14 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Repeating);
|
|
|
|
/// timer.set_mode(TimerMode::Once);
|
|
|
|
/// assert_eq!(timer.mode(), TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// ```
|
2022-11-18 20:42:33 +00:00
|
|
|
#[doc(alias = "repeating")]
|
2021-03-05 19:59:14 +00:00
|
|
|
#[inline]
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
pub fn set_mode(&mut self, mode: TimerMode) {
|
|
|
|
if self.mode != TimerMode::Repeating && mode == TimerMode::Repeating && self.finished {
|
2021-03-05 19:59:14 +00:00
|
|
|
self.stopwatch.reset();
|
2021-01-19 22:41:37 +00:00
|
|
|
self.finished = self.just_finished();
|
|
|
|
}
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
self.mode = mode;
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Advance the timer by `delta` seconds.
|
|
|
|
/// Non repeating timer will clamp at duration.
|
|
|
|
/// Repeating timer will wrap around.
|
2022-10-27 15:48:29 +00:00
|
|
|
/// Will not affect paused timers.
|
2021-03-05 19:59:14 +00:00
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::tick`](Stopwatch::tick).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once);
|
|
|
|
/// let mut repeating = Timer::from_seconds(1.0, TimerMode::Repeating);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(1.5));
|
|
|
|
/// repeating.tick(Duration::from_secs_f32(1.5));
|
|
|
|
/// assert_eq!(timer.elapsed_secs(), 1.0);
|
|
|
|
/// assert_eq!(repeating.elapsed_secs(), 0.5);
|
|
|
|
/// ```
|
|
|
|
pub fn tick(&mut self, delta: Duration) -> &Self {
|
|
|
|
if self.paused() {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick = 0;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
if self.mode == TimerMode::Repeating {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.finished = false;
|
|
|
|
}
|
2020-11-27 19:39:33 +00:00
|
|
|
return self;
|
|
|
|
}
|
2021-01-19 22:41:37 +00:00
|
|
|
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
if self.mode != TimerMode::Repeating && self.finished() {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick = 0;
|
2021-03-05 19:59:14 +00:00
|
|
|
return self;
|
|
|
|
}
|
2020-11-27 19:39:33 +00:00
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
self.stopwatch.tick(delta);
|
|
|
|
self.finished = self.elapsed() >= self.duration();
|
|
|
|
|
|
|
|
if self.finished() {
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
if self.mode == TimerMode::Repeating {
|
2023-04-24 14:32:42 +00:00
|
|
|
self.times_finished_this_tick = self
|
|
|
|
.elapsed()
|
|
|
|
.as_nanos()
|
|
|
|
.checked_div(self.duration().as_nanos())
|
|
|
|
.map_or(u32::MAX, |x| x as u32);
|
|
|
|
self.set_elapsed(
|
|
|
|
self.elapsed()
|
|
|
|
.as_nanos()
|
|
|
|
.checked_rem(self.duration().as_nanos())
|
|
|
|
.map_or(Duration::ZERO, |x| Duration::from_nanos(x as u64)),
|
|
|
|
);
|
2020-11-26 00:43:16 +00:00
|
|
|
} else {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick = 1;
|
2021-03-05 19:59:14 +00:00
|
|
|
self.set_elapsed(self.duration());
|
2020-11-26 00:43:16 +00:00
|
|
|
}
|
2021-01-19 22:41:37 +00:00
|
|
|
} else {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick = 0;
|
2020-06-04 02:53:41 +00:00
|
|
|
}
|
2021-03-05 19:59:14 +00:00
|
|
|
|
2020-11-13 02:03:03 +00:00
|
|
|
self
|
2020-06-04 02:53:41 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Pauses the Timer. Disables the ticking of the timer.
|
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::pause`](Stopwatch::pause).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.pause();
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert_eq!(timer.elapsed_secs(), 0.0);
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn pause(&mut self) {
|
|
|
|
self.stopwatch.pause();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Unpauses the Timer. Resumes the ticking of the timer.
|
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::unpause()`](Stopwatch::unpause).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.pause();
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// timer.unpause();
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert_eq!(timer.elapsed_secs(), 0.5);
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn unpause(&mut self) {
|
|
|
|
self.stopwatch.unpause();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `true` if the timer is paused.
|
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::paused`](Stopwatch::paused).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// assert!(!timer.paused());
|
|
|
|
/// timer.pause();
|
|
|
|
/// assert!(timer.paused());
|
|
|
|
/// timer.unpause();
|
|
|
|
/// assert!(!timer.paused());
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn paused(&self) -> bool {
|
|
|
|
self.stopwatch.paused()
|
|
|
|
}
|
|
|
|
|
2022-09-18 23:36:05 +00:00
|
|
|
/// Resets the timer. The reset doesn't affect the `paused` state of the timer.
|
2021-03-05 19:59:14 +00:00
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::reset`](Stopwatch::reset).
|
|
|
|
///
|
|
|
|
/// Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(1.5));
|
|
|
|
/// timer.reset();
|
|
|
|
/// assert!(!timer.finished());
|
|
|
|
/// assert!(!timer.just_finished());
|
|
|
|
/// assert_eq!(timer.elapsed_secs(), 0.0);
|
|
|
|
/// ```
|
2020-06-04 02:53:41 +00:00
|
|
|
pub fn reset(&mut self) {
|
2021-03-05 19:59:14 +00:00
|
|
|
self.stopwatch.reset();
|
2020-06-04 02:53:41 +00:00
|
|
|
self.finished = false;
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick = 0;
|
2020-06-04 02:53:41 +00:00
|
|
|
}
|
2020-11-26 00:43:16 +00:00
|
|
|
|
2023-11-13 14:59:42 +00:00
|
|
|
/// Returns the fraction of the timer elapsed time (goes from 0.0 to 1.0).
|
2021-03-05 19:59:14 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(2.0, TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
2023-11-13 14:59:42 +00:00
|
|
|
/// assert_eq!(timer.fraction(), 0.25);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
2023-11-13 14:59:42 +00:00
|
|
|
pub fn fraction(&self) -> f32 {
|
2023-04-24 14:32:42 +00:00
|
|
|
if self.duration == Duration::ZERO {
|
|
|
|
1.0
|
|
|
|
} else {
|
|
|
|
self.elapsed().as_secs_f32() / self.duration().as_secs_f32()
|
|
|
|
}
|
2020-11-26 00:43:16 +00:00
|
|
|
}
|
|
|
|
|
2023-11-13 14:59:42 +00:00
|
|
|
/// Returns the fraction of the timer remaining time (goes from 1.0 to 0.0).
|
2021-03-05 19:59:14 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(2.0, TimerMode::Once);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
2023-11-13 14:59:42 +00:00
|
|
|
/// assert_eq!(timer.fraction_remaining(), 0.75);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
2023-11-13 14:59:42 +00:00
|
|
|
pub fn fraction_remaining(&self) -> f32 {
|
|
|
|
1.0 - self.fraction()
|
2021-03-05 19:59:14 +00:00
|
|
|
}
|
|
|
|
|
2022-09-14 18:57:13 +00:00
|
|
|
/// Returns the remaining time in seconds
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
|
|
|
/// # use bevy_time::*;
|
|
|
|
/// use std::cmp::Ordering;
|
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(2.0, TimerMode::Once);
|
2022-09-14 18:57:13 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// let result = timer.remaining_secs().total_cmp(&1.5);
|
|
|
|
/// assert_eq!(Ordering::Equal, result);
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn remaining_secs(&self) -> f32 {
|
|
|
|
self.remaining().as_secs_f32()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the remaining time using Duration
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
|
|
|
/// # use bevy_time::*;
|
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(2.0, TimerMode::Once);
|
2022-09-14 18:57:13 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert_eq!(timer.remaining(), Duration::from_secs_f32(1.5));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn remaining(&self) -> Duration {
|
|
|
|
self.duration() - self.elapsed()
|
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Returns the number of times a repeating timer
|
|
|
|
/// finished during the last [`tick`](Timer<T>::tick) call.
|
|
|
|
///
|
|
|
|
/// For non repeating-timers, this method will only ever
|
|
|
|
/// return 0 or 1.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, TimerMode::Repeating);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(6.0));
|
2022-04-26 18:42:42 +00:00
|
|
|
/// assert_eq!(timer.times_finished_this_tick(), 6);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(2.0));
|
2022-04-26 18:42:42 +00:00
|
|
|
/// assert_eq!(timer.times_finished_this_tick(), 2);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
2022-04-26 18:42:42 +00:00
|
|
|
/// assert_eq!(timer.times_finished_this_tick(), 0);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
2022-04-26 18:42:42 +00:00
|
|
|
pub fn times_finished_this_tick(&self) -> u32 {
|
|
|
|
self.times_finished_this_tick
|
2020-11-26 00:43:16 +00:00
|
|
|
}
|
2020-06-04 02:53:41 +00:00
|
|
|
}
|
|
|
|
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
/// Specifies [`Timer`] behavior.
|
bevy_reflect: `FromReflect` Ergonomics Implementation (#6056)
# Objective
**This implementation is based on
https://github.com/bevyengine/rfcs/pull/59.**
---
Resolves #4597
Full details and motivation can be found in the RFC, but here's a brief
summary.
`FromReflect` is a very powerful and important trait within the
reflection API. It allows Dynamic types (e.g., `DynamicList`, etc.) to
be formed into Real ones (e.g., `Vec<i32>`, etc.).
This mainly comes into play concerning deserialization, where the
reflection deserializers both return a `Box<dyn Reflect>` that almost
always contain one of these Dynamic representations of a Real type. To
convert this to our Real type, we need to use `FromReflect`.
It also sneaks up in other ways. For example, it's a required bound for
`T` in `Vec<T>` so that `Vec<T>` as a whole can be made `FromReflect`.
It's also required by all fields of an enum as it's used as part of the
`Reflect::apply` implementation.
So in other words, much like `GetTypeRegistration` and `Typed`, it is
very much a core reflection trait.
The problem is that it is not currently treated like a core trait and is
not automatically derived alongside `Reflect`. This makes using it a bit
cumbersome and easy to forget.
## Solution
Automatically derive `FromReflect` when deriving `Reflect`.
Users can then choose to opt-out if needed using the
`#[reflect(from_reflect = false)]` attribute.
```rust
#[derive(Reflect)]
struct Foo;
#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct Bar;
fn test<T: FromReflect>(value: T) {}
test(Foo); // <-- OK
test(Bar); // <-- Panic! Bar does not implement trait `FromReflect`
```
#### `ReflectFromReflect`
This PR also automatically adds the `ReflectFromReflect` (introduced in
#6245) registration to the derived `GetTypeRegistration` impl— if the
type hasn't opted out of `FromReflect` of course.
<details>
<summary><h4>Improved Deserialization</h4></summary>
> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.
And since we can do all the above, we might as well improve
deserialization. We can now choose to deserialize into a Dynamic type or
automatically convert it using `FromReflect` under the hood.
`[Un]TypedReflectDeserializer::new` will now perform the conversion and
return the `Box`'d Real type.
`[Un]TypedReflectDeserializer::new_dynamic` will work like what we have
now and simply return the `Box`'d Dynamic type.
```rust
// Returns the Real type
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
let mut deserializer = ron::de::Deserializer::from_str(input)?;
let output: SomeStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;
// Returns the Dynamic type
let reflect_deserializer = UntypedReflectDeserializer::new_dynamic(®istry);
let mut deserializer = ron::de::Deserializer::from_str(input)?;
let output: DynamicStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;
```
</details>
---
## Changelog
* `FromReflect` is now automatically derived within the `Reflect` derive
macro
* This includes auto-registering `ReflectFromReflect` in the derived
`GetTypeRegistration` impl
* ~~Renamed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic`, respectively~~ **Descoped**
* ~~Changed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to automatically convert the
deserialized output using `FromReflect`~~ **Descoped**
## Migration Guide
* `FromReflect` is now automatically derived within the `Reflect` derive
macro. Items with both derives will need to remove the `FromReflect`
one.
```rust
// OLD
#[derive(Reflect, FromReflect)]
struct Foo;
// NEW
#[derive(Reflect)]
struct Foo;
```
If using a manual implementation of `FromReflect` and the `Reflect`
derive, users will need to opt-out of the automatic implementation.
```rust
// OLD
#[derive(Reflect)]
struct Foo;
impl FromReflect for Foo {/* ... */}
// NEW
#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct Foo;
impl FromReflect for Foo {/* ... */}
```
<details>
<summary><h4>Removed Migrations</h4></summary>
> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.
* The reflect deserializers now perform a `FromReflect` conversion
internally. The expected output of `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` is no longer a Dynamic (e.g.,
`DynamicList`), but its Real counterpart (e.g., `Vec<i32>`).
```rust
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(®istry);
let mut deserializer = ron::de::Deserializer::from_str(input)?;
// OLD
let output: DynamicStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
// NEW
let output: SomeStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
```
Alternatively, if this behavior isn't desired, use the
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic` methods instead:
```rust
// OLD
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
// NEW
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(®istry);
```
</details>
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-06-29 01:31:34 +00:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default, Reflect)]
|
2022-10-17 14:38:57 +00:00
|
|
|
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
#[reflect(Default)]
|
|
|
|
pub enum TimerMode {
|
|
|
|
/// Run once and stop.
|
|
|
|
#[default]
|
|
|
|
Once,
|
|
|
|
/// Reset when finished.
|
|
|
|
Repeating,
|
|
|
|
}
|
|
|
|
|
2020-11-26 00:43:16 +00:00
|
|
|
#[cfg(test)]
|
2021-02-22 08:42:19 +00:00
|
|
|
#[allow(clippy::float_cmp)]
|
2020-11-26 00:43:16 +00:00
|
|
|
mod tests {
|
2021-03-05 19:59:14 +00:00
|
|
|
use super::*;
|
2020-11-26 00:43:16 +00:00
|
|
|
|
|
|
|
#[test]
|
2021-03-05 19:59:14 +00:00
|
|
|
fn non_repeating_timer() {
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
let mut t = Timer::from_seconds(10.0, TimerMode::Once);
|
2020-11-26 00:43:16 +00:00
|
|
|
// Tick once, check all attributes
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(0.25));
|
|
|
|
assert_eq!(t.elapsed_secs(), 0.25);
|
|
|
|
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(!t.finished());
|
|
|
|
assert!(!t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
assert_eq!(t.mode(), TimerMode::Once);
|
2023-11-13 14:59:42 +00:00
|
|
|
assert_eq!(t.fraction(), 0.025);
|
|
|
|
assert_eq!(t.fraction_remaining(), 0.975);
|
2020-11-27 19:39:33 +00:00
|
|
|
// Ticking while paused changes nothing
|
|
|
|
t.pause();
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(500.0));
|
|
|
|
assert_eq!(t.elapsed_secs(), 0.25);
|
|
|
|
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(!t.finished());
|
|
|
|
assert!(!t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
assert_eq!(t.mode(), TimerMode::Once);
|
2023-11-13 14:59:42 +00:00
|
|
|
assert_eq!(t.fraction(), 0.025);
|
|
|
|
assert_eq!(t.fraction_remaining(), 0.975);
|
2020-11-26 00:43:16 +00:00
|
|
|
// Tick past the end and make sure elapsed doesn't go past 0.0 and other things update
|
2020-11-27 19:39:33 +00:00
|
|
|
t.unpause();
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(500.0));
|
|
|
|
assert_eq!(t.elapsed_secs(), 10.0);
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(t.finished());
|
|
|
|
assert!(t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 1);
|
2023-11-13 14:59:42 +00:00
|
|
|
assert_eq!(t.fraction(), 1.0);
|
|
|
|
assert_eq!(t.fraction_remaining(), 0.0);
|
2020-11-26 00:43:16 +00:00
|
|
|
// Continuing to tick when finished should only change just_finished
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(1.0));
|
|
|
|
assert_eq!(t.elapsed_secs(), 10.0);
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(t.finished());
|
|
|
|
assert!(!t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2023-11-13 14:59:42 +00:00
|
|
|
assert_eq!(t.fraction(), 1.0);
|
|
|
|
assert_eq!(t.fraction_remaining(), 0.0);
|
2020-11-26 00:43:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-03-05 19:59:14 +00:00
|
|
|
fn repeating_timer() {
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
let mut t = Timer::from_seconds(2.0, TimerMode::Repeating);
|
2020-11-26 00:43:16 +00:00
|
|
|
// Tick once, check all attributes
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(0.75));
|
|
|
|
assert_eq!(t.elapsed_secs(), 0.75);
|
|
|
|
assert_eq!(t.duration(), Duration::from_secs_f32(2.0));
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(!t.finished());
|
|
|
|
assert!(!t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
assert_eq!(t.mode(), TimerMode::Repeating);
|
2023-11-13 14:59:42 +00:00
|
|
|
assert_eq!(t.fraction(), 0.375);
|
|
|
|
assert_eq!(t.fraction_remaining(), 0.625);
|
2020-11-26 00:43:16 +00:00
|
|
|
// Tick past the end and make sure elapsed wraps
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(1.5));
|
|
|
|
assert_eq!(t.elapsed_secs(), 0.25);
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(t.finished());
|
|
|
|
assert!(t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 1);
|
2023-11-13 14:59:42 +00:00
|
|
|
assert_eq!(t.fraction(), 0.125);
|
|
|
|
assert_eq!(t.fraction_remaining(), 0.875);
|
2020-11-26 00:43:16 +00:00
|
|
|
// Continuing to tick should turn off both finished & just_finished for repeating timers
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(1.0));
|
|
|
|
assert_eq!(t.elapsed_secs(), 1.25);
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(!t.finished());
|
|
|
|
assert!(!t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2023-11-13 14:59:42 +00:00
|
|
|
assert_eq!(t.fraction(), 0.625);
|
|
|
|
assert_eq!(t.fraction_remaining(), 0.375);
|
2020-11-26 00:43:16 +00:00
|
|
|
}
|
2021-03-05 19:59:14 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn times_finished_repeating() {
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
let mut t = Timer::from_seconds(1.0, TimerMode::Repeating);
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(3.5));
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 3);
|
2021-03-05 19:59:14 +00:00
|
|
|
assert_eq!(t.elapsed_secs(), 0.5);
|
|
|
|
assert!(t.finished());
|
|
|
|
assert!(t.just_finished());
|
|
|
|
t.tick(Duration::from_secs_f32(0.2));
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2021-03-05 19:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2022-04-26 18:42:42 +00:00
|
|
|
fn times_finished_this_tick() {
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
let mut t = Timer::from_seconds(1.0, TimerMode::Once);
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(1.5));
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 1);
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(0.5));
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2021-03-05 19:59:14 +00:00
|
|
|
}
|
2021-06-26 19:49:34 +00:00
|
|
|
|
2023-04-24 14:32:42 +00:00
|
|
|
#[test]
|
|
|
|
fn times_finished_this_tick_repeating_zero_duration() {
|
|
|
|
let mut t = Timer::from_seconds(0.0, TimerMode::Repeating);
|
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
|
|
|
assert_eq!(t.elapsed(), Duration::ZERO);
|
2023-11-13 14:59:42 +00:00
|
|
|
assert_eq!(t.fraction(), 1.0);
|
2023-04-24 14:32:42 +00:00
|
|
|
t.tick(Duration::from_secs(1));
|
|
|
|
assert_eq!(t.times_finished_this_tick(), u32::MAX);
|
|
|
|
assert_eq!(t.elapsed(), Duration::ZERO);
|
2023-11-13 14:59:42 +00:00
|
|
|
assert_eq!(t.fraction(), 1.0);
|
2023-04-24 14:32:42 +00:00
|
|
|
t.tick(Duration::from_secs(2));
|
|
|
|
assert_eq!(t.times_finished_this_tick(), u32::MAX);
|
|
|
|
assert_eq!(t.elapsed(), Duration::ZERO);
|
2023-11-13 14:59:42 +00:00
|
|
|
assert_eq!(t.fraction(), 1.0);
|
2023-04-24 14:32:42 +00:00
|
|
|
t.reset();
|
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
|
|
|
assert_eq!(t.elapsed(), Duration::ZERO);
|
2023-11-13 14:59:42 +00:00
|
|
|
assert_eq!(t.fraction(), 1.0);
|
2023-04-24 14:32:42 +00:00
|
|
|
}
|
|
|
|
|
2021-06-26 19:49:34 +00:00
|
|
|
#[test]
|
2022-04-26 18:42:42 +00:00
|
|
|
fn times_finished_this_tick_precise() {
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
let mut t = Timer::from_seconds(0.01, TimerMode::Repeating);
|
2022-01-28 16:17:54 +00:00
|
|
|
let duration = Duration::from_secs_f64(0.333);
|
2021-06-26 19:49:34 +00:00
|
|
|
|
2022-01-28 16:17:54 +00:00
|
|
|
// total duration: 0.333 => 33 times finished
|
2021-06-26 19:49:34 +00:00
|
|
|
t.tick(duration);
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 33);
|
2022-01-28 16:17:54 +00:00
|
|
|
// total duration: 0.666 => 33 times finished
|
2021-06-26 19:49:34 +00:00
|
|
|
t.tick(duration);
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 33);
|
2022-01-28 16:17:54 +00:00
|
|
|
// total duration: 0.999 => 33 times finished
|
2021-06-26 19:49:34 +00:00
|
|
|
t.tick(duration);
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 33);
|
2022-01-28 16:17:54 +00:00
|
|
|
// total duration: 1.332 => 34 times finished
|
2021-06-26 19:49:34 +00:00
|
|
|
t.tick(duration);
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 34);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn paused() {
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
let mut t = Timer::from_seconds(10.0, TimerMode::Once);
|
2022-04-26 18:42:42 +00:00
|
|
|
|
|
|
|
t.tick(Duration::from_secs_f32(10.0));
|
|
|
|
assert!(t.just_finished());
|
|
|
|
assert!(t.finished());
|
|
|
|
// A paused timer should change just_finished to false after a tick
|
|
|
|
t.pause();
|
|
|
|
t.tick(Duration::from_secs_f32(5.0));
|
|
|
|
assert!(!t.just_finished());
|
|
|
|
assert!(t.finished());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn paused_repeating() {
|
Replace the `bool` argument of `Timer` with `TimerMode` (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.
This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.
Signed-off-by: Lena Milizé <me@lvmn.org>
# Objective
Fixes #2926.
## Solution
Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.
---
## Changelog
### Added
- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`
### Changed
- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`
## Migration Guide
- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
|
|
|
let mut t = Timer::from_seconds(10.0, TimerMode::Repeating);
|
2022-04-26 18:42:42 +00:00
|
|
|
|
|
|
|
t.tick(Duration::from_secs_f32(10.0));
|
|
|
|
assert!(t.just_finished());
|
|
|
|
assert!(t.finished());
|
|
|
|
// A paused repeating timer should change finished and just_finished to false after a tick
|
|
|
|
t.pause();
|
|
|
|
t.tick(Duration::from_secs_f32(5.0));
|
|
|
|
assert!(!t.just_finished());
|
|
|
|
assert!(!t.finished());
|
2021-06-26 19:49:34 +00:00
|
|
|
}
|
2020-11-26 00:43:16 +00:00
|
|
|
}
|