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

Fix timers at program start, TIMER STOP, and Sleep with console #295

Merged
merged 3 commits into from Feb 13, 2023

Conversation

mkilgore
Copy link
Contributor

Three timer-related fixes in here:

  1. Timers started at the start of the program take two intervals to trigger. This was due to the faulty last_time == 0 logic, which was done after check if the interval had passed. This doesn't work correctly at program start when time_now == 0. It's not necessary to check the interval anyway (we're just going to reset it), so we can just check for the last_time == 0 special case first and avoid the issue.
  2. If a timer expired during TIMER STOP, it wouldn't trigger when TIMER ON is used. This was simple to fix, TIMER ON wasn't setting qbevent = 1 to tell the program to check for events (like timer expiration). This meant the timer wouldn't trigger until something else set qbevent.
  3. Using Sleep with a console program on Windows won't run timers while sleeping. This was due to the custom sleep logic not calling evnt(). I rewrote it to sleep for short intervals and then call evnt() to handle timers and such, like all the other sleep commands do.

Fixes: #273
Fixes: #294
Fixes: #293

@mkilgore mkilgore added the bug Something isn't working label Jan 15, 2023
@mkilgore
Copy link
Contributor Author

mkilgore commented Feb 7, 2023

This is ready to be reviewed :)

Timer's were not firing at the right time if they were started shortly
after the program started, instead they would fire at twice the interval
time (and then work correctly after that).

The issue was a mistaken assumption about `time_now`, with the idea that
if `last_time == 0` then `time_now` will be large enough such that the
interval check will pass. This is wrong because in most cases `time_now`
starts at zero at program start, so when `last_time == 0` it will take
one full interval of the timer before `time_now` is large enough for the
interval check to pass (at which point the timer is initialized and runs
normally).

This simply refactors the timer logic so that `last_time == 0` is
checked first, rather than if the interval has expired. This doesn't
change how the normal logic works, but ensures that the value of
`time_now` does not matter for initializing a timer.

Fixes: QB64-Phoenix-Edition#273
The command Sleep is supposed to allow timers to trigger while the
program is sleeping on the delay. This is achieved in QB64 by having
commands that do delays manually call evnt() to trigger events if they
come up (of which timers are one).

Sleep has a custom implementation for console programs on Windows which
doesn't do this, so I redid the logic so that it calls evnt() at regular
intervals while waiting for input. Additionally, due to now calling
evnt() we also need to check if we should exit sleep early due to an
evnt() firing.

Fixes: QB64-Phoenix-Edition#294
If a timer expires while stopped, it should trigger when TIMER ON is
run. Instead, on QB64 it triggers randomly after the TIMER ON happens.

The basic issue is that `qbevent` needs to be set to trigger the timer,
but TIMER ON doesn't do that. The regular timer logic that does that
already set it when the timer expired while sleeping, so it won't set it
again. The simplest solution is to just alway set qbevent = 1 when TIMER
ON is done. It's slightly less efficent but doesn't hurt to set it even
when there are no timers that expired.

Fixes: QB64-Phoenix-Edition#293
@mkilgore mkilgore merged commit 4763950 into QB64-Phoenix-Edition:main Feb 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
2 participants