Author Topic: Why does "ON TIMER" skip the first time interval?  (Read 282 times)

0 Members and 1 Guest are viewing this topic.

Offline hanness

  • Forum Regular
  • Posts: 144
Why does "ON TIMER" skip the first time interval?
« on: April 20, 2021, 10:36:44 AM »
In the following code sample, I have a DO...LOOP that simply prints out how many seconds have elapsed once per second.

Before that loop is started, I seup a timer to run a subroutine every 5 seconds. That subroutine simply prints out how many times it has been run.

What's odd is that the first timer event does not happen after 5 seconds, it happens after 10 seconds. After the first run it correctly runs every 5 seconds.

If you change the interval, the same thing still happens. For example, if I set the timer to 10 seconds, the first execution of the timed event happens after 20 seconds, not 10 seconds.

Is this expected behavior for some reason?

Test scenario: QB 1.51 (April 9, 2021 Dev Build) on Win 10 20H2

Sample code:

x = 0
y = 0

t1 = _FreeTimer
On Timer(t1, 5) GoSub DoTimedStuff
Timer(t1) On

Do
    _Limit 1
    x = x + 1
    Print "Seconds elapsed:"; x
Loop

DoTimedStuff:
y = y + 1
Print "Timer ticks:"; y
Return

Marked as best answer by hanness on April 21, 2021, 06:07:46 PM

Offline Cobalt

  • Forum Resident
  • Posts: 734
  • At 60 I become highly radioactive!
Re: Why does "ON TIMER" skip the first time interval?
« Reply #1 on: April 20, 2021, 11:20:18 AM »
There must be some internal clock for QB64 cause if you add a _DELAY, even before you turn the timer on, it changes when the first run is. Also TIMERs and _LIMIT\_DELAY don't seem to like each other very much, if the TIMER value lands on a _LIMIT or _DELAY value it seems to be 50\50 who goes first.
Code: QB64: [Select]
  1. DIM SHARED x, y
  2. x = 0
  3. y = 0
  4.  
  5.  
  6. ON TIMER(t1, 5) DoTimedStuff
  7. TIMER(t1) ON
  8.  
  9.  _LIMIT 1
  10.  x = x + 1
  11.  PRINT "Seconds elapsed:"; x
  12.  
  13. SUB DoTimedStuff
  14.  y = y + 1
  15.  PRINT "Timer ticks:"; y
  16.  
Granted after becoming radioactive I only have a half-life!

Offline Petr

  • Forum Resident
  • Posts: 1574
  • The best code is the DNA of the hops.
Re: Why does "ON TIMER" skip the first time interval?
« Reply #2 on: April 20, 2021, 11:27:16 AM »
@hanness  This is probably a deep bug in the ON TIMER statement, because it works just as badly with the ON TIMER (5) statement - the old Qbasic way. I tested it in versions 1.5, 1.1 and 0.954, in all it works badly, as you say.

Online FellippeHeitor

  • QB64 Developer
  • Forum Resident
  • Posts: 2902
  • Let it go, this too shall pass.
    • QB64.org
Re: Why does "ON TIMER" skip the first time interval?
« Reply #3 on: April 20, 2021, 02:14:56 PM »
Here it works as expected, since the timer activation happens after the program had time to initialise:

Code: QB64: [Select]
  1. On Timer(t1, 5) GoSub DoTimedStuff
  2.  
  3. start! = Timer
  4.     Cls
  5.     Print "Seconds elapsed:";
  6.     If timeron Then
  7.         Print Int(Timer - start!)
  8.         Print "Timer ticks:"; y
  9.         Print "TIMER IS ON  - press ENTER to toggle"
  10.     Else
  11.         Print
  12.         Print "TIMER IS OFF - press ENTER to toggle"
  13.     End If
  14.     If _KeyHit = -13 Then
  15.         If timeron = 0 Then
  16.             timeron = 1
  17.             start! = Timer
  18.             y = 0
  19.             Timer(t1) On
  20.             Color 10
  21.         Else
  22.             timeron = 0
  23.             Timer(t1) Off
  24.             Color 7
  25.         End If
  26.     End If
  27.     _Display
  28.     _Limit 60
  29.  
  30. DoTimedStuff:
  31. y = y + 1
  32.  

We're probably looking at some sort of race condition that's happening at startup - that's when the TIMER thread is created.

Offline Cobalt

  • Forum Resident
  • Posts: 734
  • At 60 I become highly radioactive!
Re: Why does "ON TIMER" skip the first time interval?
« Reply #4 on: April 20, 2021, 11:30:04 PM »
We're probably looking at some sort of race condition that's happening at startup - that's when the TIMER thread is created.

Thats why I added the _DELAY to try and let everything get setup before beginning. Whether the delay was before everything or after the timer declare it still behaved the same.
Whether the timer is 5sec or 2sec it still takes that long before it starts registering.

Probably why I have never noticed this before, most of my timers are fractions of a second. .125, .25 ect. But sure enough it always misses that first run.

So yeah if you have a ridiculous timer cycle rate like 300 seconds you literally have to wait 600 seconds before the first event happens. or wait 300 before turning the timer on.
Granted after becoming radioactive I only have a half-life!

Offline NOVARSEG

  • Seasoned Forum Regular
  • Posts: 391
Re: Why does "ON TIMER" skip the first time interval?
« Reply #5 on: April 21, 2021, 02:55:56 AM »
Found the same problem but this ON TIMER stuff seems to be clunky.  The code seems to initialize BEFORE runtime. During runtime an ON TIMER statement is ignored. 

Here is some code that works with TIMER

Code: QB64: [Select]
  1. x = 0
  2. y = 0
  3.  
  4. t2 = TIMER
  5. t1 = TIMER
  6.  
  7.     IF TIMER - t1 > 5 THEN
  8.         t1 = TIMER
  9.         y = y + 1
  10.         PRINT "Timer ticks:"; y
  11.     END IF
  12.  
  13.     IF TIMER - t2 > 1 THEN
  14.         t2 = TIMER
  15.         x = x + 1
  16.         PRINT "Seconds elapsed:"; x
  17.     END IF
  18.  

Man! talk about a dangerous statement - ON TIMER. It has total disregard to LOOPS. When activated it takes priority over any other code.  We are talking about WW3.

If anyone thought that my programming in common memory with assembler was nuts then this takes the cake.
« Last Edit: April 21, 2021, 03:03:10 AM by NOVARSEG »

Offline Cobalt

  • Forum Resident
  • Posts: 734
  • At 60 I become highly radioactive!
Re: Why does "ON TIMER" skip the first time interval?
« Reply #6 on: April 21, 2021, 10:13:54 AM »
Man! talk about a dangerous statement - ON TIMER. It has total disregard to LOOPS. When activated it takes priority over any other code.  We are talking about WW3.

that is kind of the point, ON TIMER is an EVENT like an interrupt. So say you have a game where you need a message to popup every X ticks until the player completes a task regardless what else is happening in the game. Then you use ON TIMER.
Granted after becoming radioactive I only have a half-life!

Online OldMoses

  • Seasoned Forum Regular
  • Posts: 449
Re: Why does "ON TIMER" skip the first time interval?
« Reply #7 on: April 21, 2021, 01:38:32 PM »
I use it in one of my projects as a auto save for crash recovery. Of course, it doesn't really need to catch the first interval as not much of consequence would happen in that time, so I never noticed that glitch.

It saves the state every 60 seconds to an auto save directory. It uses the same SUB as a manual file save, I just send a boolean byte with the sub call that tells the sub whether to do the dialogs or save to "auto" behind the scenes. I coded it to turn the timer off before doing a manual 'named scenario' save, and then back on again after that is done. I don't know if that would be a problem, but reasoned that it shouldn't be calling the same SUB simultaneously.

I suppose it could go off in the middle of an update loop and screw up the autosave data, but then it should catch it a minute later. I figure the chance of a bad save AND a crash within 60 seconds is fairly low. It's just a case of how unlucky one is, I suppose.
Andy

Offline bplus

  • Forum Resident
  • Posts: 6700
  • b = b + ...
Re: Why does "ON TIMER" skip the first time interval?
« Reply #8 on: April 21, 2021, 02:06:37 PM »
Quote
Man! talk about a dangerous statement - ON TIMER. It has total disregard to LOOPS. When activated it takes priority over any other code.  We are talking about WW3.

If anyone thought that my programming in common memory with assembler was nuts then this takes the cake.

LOL

Power tools are scary ;-))

You can turn it on and off like any good tool.

Offline hanness

  • Forum Regular
  • Posts: 144
Re: Why does "ON TIMER" skip the first time interval?
« Reply #9 on: April 21, 2021, 03:07:23 PM »
Thanks for the all the responses. It's not affecting anything critical for me, I simply wanted to see if I was missing something obvious here :-)

Offline SpriggsySpriggs

  • QB64 Developer
  • Forum Resident
  • Posts: 946
  • If you're API and you know it clap your hands
    • My GitHub
Re: Why does "ON TIMER" skip the first time interval?
« Reply #10 on: April 21, 2021, 03:11:20 PM »
Yeah I can't quite figure out why it is skipping the first run of the timer. Interesting. Now it shall nag the back of my mind forever.

Offline hanness

  • Forum Regular
  • Posts: 144
Re: Why does "ON TIMER" skip the first time interval?
« Reply #11 on: April 22, 2021, 07:03:32 PM »
Yeah I can't quite figure out why it is skipping the first run of the timer. Interesting. Now it shall nag the back of my mind forever.

I get that! Sometimes small things that really don't matter in the grand scheme of things end up occupying way too many cycles of the underpowered central processing unit in my skull.