function run by a timer can't create another timer to re-run itself?

Posted by Fiendish on Thu 23 Jun 2016 04:38 PM — 6 posts, 18,364 views.

USA Global Moderator #0

times_fired = 0
function test_timer()
    times_fired = times_fired+1
    print(times_fired)
    AddTimer("mytimer", 0, 0, 0.1, "test_timer()", timer_flag.Enabled + timer_flag.OneShot + timer_flag.Replace + timer_flag.Temporary, "")
    SetTimerOption("mytimer", "send_to", sendto.script)
    Repaint()
end
test_timer()

This prints

1
2

and then it stops. Why? What am I doing wrong here?
Amended on Thu 23 Jun 2016 04:39 PM by Fiendish
USA Global Moderator #1
Doing this works.

times_fired = 0
function test_timer()
    times_fired = times_fired+1
    print(times_fired)
    AddTimer("mytimer"..times_fired, 0, 0, 0.1, "test_timer()", timer_flag.Enabled + timer_flag.OneShot + timer_flag.Replace + timer_flag.Temporary, "")
    SetTimerOption("mytimer"..times_fired, "send_to", sendto.script)
    Repaint()
end
test_timer()

But it breaks timer_flag.Replace because they'll never have the same name.

It suggests that OneShot is both trying to remove the timer _after_ my function call instead of before (and isn't removing _that_ timer but any timer with the name) so that it is trapping my newly created timer instead of the one that just expired.
Making OneShot evaluate first before the code is run would probably fix this.
Amended on Thu 23 Jun 2016 05:05 PM by Fiendish
Australia Forum Administrator #2
Yes, but you can't delete a timer (which is what one-shot does) and then evaluate its stuff. And I'm reluctant to remember pointers rather than names, because - during script execution - that pointer might become invalid. Hence it deletes by name.

If you hadn't assigned a name you would get a new automatically-generated name each time and the problem goes away.

But you needed the name to make it send-to-script, right? So how about using addxml? Like this:


require "addxml"
times_fired = 0
function test_timer()
    times_fired = times_fired+1
    print(times_fired)
    addxml.timer {  second = 0.1, 
                    send = "test_timer ()",
                    send_to = sendto.script,
                    enabled = true,
                    one_shot = true,
                    temporary = true,
                    active_closed = true,
              }
    Repaint()
end
test_timer()
USA Global Moderator #3
Quote:
Yes, but you can't delete a timer (which is what one-shot does) and then evaluate its stuff.

What about removing it from the list to search up front but not deleting the actual object until after? Or mangle the name so that a new one doesn't conflict, since at least _my_ expectation was that at the time of the resulting action the named timer no longer exists.
Amended on Fri 24 Jun 2016 02:40 AM by Fiendish
Australia Forum Administrator #4
If I save the object pointer, then run a script, the script might delete the pointer, so it is an error to delete it after the script runs.

Generating a new name, putting it into the timer, and then looking that up afterwards seems an unnecessary overhead to me.

Quote:

... _my_ expectation was that at the time of the resulting action the named timer no longer exists


Why though? You made a timer, you got it to call a script. Surely the timer exists at that point?
USA Global Moderator #5
Nick Gammon said:

Why though? You made a timer, you got it to call a script. Surely the timer exists at that point?

Just a difference of expectation I guess. At that point, to me, the timer is done because the time has elapsed.

For now I've achieved my basic goal in this case by actually using something close to my "it works this way" example and changing the timer name for subsequent calls, starting at 0 for the main kickoff each time, and ignoring the odd accidental misfire (because the previous invocation doesn't get replaced anymore by new ones) because the work pool is global so there's actually no work left to be done so the time cost of the (at most a handful) misfires is negligible.

Now I need to find a fix for my WindowAddHotspots taking so long.