Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timer::just_finished() returns true forever when paused during finish tick #4436

Closed
Madadog opened this issue Apr 7, 2022 · 1 comment
Closed
Labels
A-Core Common functionality for all bevy apps C-Bug An unexpected or incorrect behavior D-Trivial Nice and easy! A great choice to get started with Bevy

Comments

@Madadog
Copy link

Madadog commented Apr 7, 2022

Bevy version

0.6.1

Operating system & version

Ubuntu 20.04

The problem

The description of Timer::just_finished() claims it "returns true only on the tick the timer reached its duration", but pausing during that tick causes it to return true indefinitely. This causes inconsistent behaviour as it means pausing a timer will occasionally make Timer::just_finished() return true every frame, usually resulting in a massive speedup for anything the method is being used for: periodic entity spawning, advancing an animation, or printing info to the console.

It's possible this isn't actually a bug, but at the very least it leads to unintuitive behaviour which should be correctly indicated in the method's description.

Minimal example:

use bevy::prelude::*;
use std::time::Duration;

fn main() {
    // consistent for both repeating and non-repeating timers
    let mut timer = Timer::from_seconds(1.0, false);

    // finish timer
    timer.tick(Duration::from_secs_f32(1.0));
    assert!(timer.just_finished());
    
    // pause timer while just_finished()
    timer.pause();

    // timer is now just_finished() forever
    for _ in 0..100 {
        timer.tick(Duration::from_secs_f32(0.5));
        assert!(timer.just_finished());
    }
}

How was this found?

What you did

Used a timer to advance an animation when timer.just_finished() == true. Paused the timer.

What you expected to happen

The animation would stop.

What actually happened

The animation would stop unless it was paused on the tick timer.just_finished() == true. If this happened, the animation would speed up to the screen's refresh rate. Unpausing the animation would slow it back down.

Solutions you have considered

  • Make tick() reset times_finished to 0 when paused
    • In general, ticking a paused timer is supposed to do nothing.
    • Need to consider what exactly times_finished means while paused / if anything relies on it not changing.
@Madadog Madadog added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Apr 7, 2022
@Madadog Madadog changed the title Timer::just_finished() returns true forever when paused during finish tick Timer::just_finished() returns true forever when paused during finish tick Apr 7, 2022
@alice-i-cecile alice-i-cecile added A-Core Common functionality for all bevy apps D-Trivial Nice and easy! A great choice to get started with Bevy and removed S-Needs-Triage This issue needs to be labelled labels Apr 7, 2022
bors bot pushed a commit that referenced this issue Apr 26, 2022
# Objective
Make timers update `just_finished` on tick, even if paused.
Fixes #4436

## Solution
`just_finished()` returns `times_finished > 0`. So I:
 * Renamed `times_finished` to `times_finished_this_tick` to reduce confusion.
 * Set `times_finished_this_tick` to `0` on tick when paused.
 * Additionally set `finished` to `false` if the timer is repeating.

Notably this change broke none of the existing tests, so I added a couple for this.

Files changed shows a lot of noise because of the rename. Check the first commit for the relevant changes.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
@Protowalker
Copy link
Contributor

@alice-i-cecile this has since been fixed. Good to close?

exjam pushed a commit to exjam/bevy that referenced this issue May 22, 2022
# Objective
Make timers update `just_finished` on tick, even if paused.
Fixes bevyengine#4436

## Solution
`just_finished()` returns `times_finished > 0`. So I:
 * Renamed `times_finished` to `times_finished_this_tick` to reduce confusion.
 * Set `times_finished_this_tick` to `0` on tick when paused.
 * Additionally set `finished` to `false` if the timer is repeating.

Notably this change broke none of the existing tests, so I added a couple for this.

Files changed shows a lot of noise because of the rename. Check the first commit for the relevant changes.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
ItsDoot pushed a commit to ItsDoot/bevy that referenced this issue Feb 1, 2023
# Objective
Make timers update `just_finished` on tick, even if paused.
Fixes bevyengine#4436

## Solution
`just_finished()` returns `times_finished > 0`. So I:
 * Renamed `times_finished` to `times_finished_this_tick` to reduce confusion.
 * Set `times_finished_this_tick` to `0` on tick when paused.
 * Additionally set `finished` to `false` if the timer is repeating.

Notably this change broke none of the existing tests, so I added a couple for this.

Files changed shows a lot of noise because of the rename. Check the first commit for the relevant changes.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Core Common functionality for all bevy apps C-Bug An unexpected or incorrect behavior D-Trivial Nice and easy! A great choice to get started with Bevy
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants