Is there anything wrong with timer.performWithDelay?

Hi,

I schedule objects that need to appear on the screen at once by calling timer.performWithDelay several times, like this:

for i = 1, numOfFoodsToMakeForCurrentWave do if i == 1 then makeOneFoodObject ( Waves[waveCounter][currentWaveIndex].speed, Waves[waveCounter][currentWaveIndex].position) else local myclosure = function() return makeOneFoodObject ( Waves[waveCounter][currentWaveIndex].speed, Waves[waveCounter][currentWaveIndex].position) end local timerID = timer.performWithDelay( (i - 1) \* 500, myclosure, 1) table.insert(timerStash, timerID) end end

Problem is, sometimes timer.performWithDelay is acting messed up and makes two objects at the same time. This happens more on the simulator on windows than on device but happens.

It’s almost impossible for me to track as it happens randomly.

Any ideas?

Hi,

I haven’t experienced any issues with timer.performWithDelay acting differently than I expect.

One possibility is a frame delay.  If your app is set to run at 30fps, each frame is 33ms.  But if you do a lot of processing in a particular frame (like, loading lots of images to set up a scene), the processing might take more than 33ms, and some frames will be missed.  If you had some timer.performWithDelays as part of that processing, their functions may get executed with a longer delay than you expect too.

For example, let’s say you are setting up your scene and doing a lot of processing.  As part of your setup, you create two timers for 500ms and 1000ms.  However, the entire processing takes 1200ms.  In that case, both timers will end up executing at 1200ms, since that’s the first available frame for them to execute.

  • Andrew

I’m not doing anything fancy, and if I was, I would see the error more often but it happens so randomly that I can’t track it and find a case of reproducing it for over 2 days now.

And the fact that this happens more in the Windows simulator made me suspect the timer.performWIthDelay.

By the way I’m using daily builds.

Auk’s rationale is the most obvious I think. But I would guess you would see a “stutter” in the graphics at the time the double food appeared if it was the case. There’s no quick stutter to the animation when it happens, is there?

Also, I noticed you are not setting the timerID in the timerStash for the case where i == 1. No idea what that causes later, but it looks asymmetric.

Edit: You could try and stress your app, forcing the bug to manifest… You could try a few runs, each time decreasing the timer separation of objects (400 ms, 300 ms, 200 ms, etc) to see if that flushes the bug out into the open (if it is, in fact, timing related).

Hi Aidin,

If you can’t reproduce it for over 2 days, that’ll make it much harder to debug (obviously!).

What I suggest is that you insert some print statements as you set each timer, and also within the closure.  For example, you could print the index i and the current os.time() at the time each timer is created, and again within the closure.  That way, the next time you see this issue, you’ll have some useful info in the console to potentially help you narrow down the root cause.

  • Andrew

Why not

[lua]timerStash.timerID = timer.performWithDelay( (i - 1) * 500, myclosure, 1)[/lua]

Saves 1 line.

I have some bad experiences with timers and calling asynchrone functions so I often try to keep the time as low as possible. Indeed try to print out all the local and global variables in that loop.

Thanks guys, I’ve decided to remove timer.performWithDelay and just after I spawn objects, I offset them before entering the screen as I think dealing with this is way harder than this.

Hi,

I haven’t experienced any issues with timer.performWithDelay acting differently than I expect.

One possibility is a frame delay.  If your app is set to run at 30fps, each frame is 33ms.  But if you do a lot of processing in a particular frame (like, loading lots of images to set up a scene), the processing might take more than 33ms, and some frames will be missed.  If you had some timer.performWithDelays as part of that processing, their functions may get executed with a longer delay than you expect too.

For example, let’s say you are setting up your scene and doing a lot of processing.  As part of your setup, you create two timers for 500ms and 1000ms.  However, the entire processing takes 1200ms.  In that case, both timers will end up executing at 1200ms, since that’s the first available frame for them to execute.

  • Andrew

I’m not doing anything fancy, and if I was, I would see the error more often but it happens so randomly that I can’t track it and find a case of reproducing it for over 2 days now.

And the fact that this happens more in the Windows simulator made me suspect the timer.performWIthDelay.

By the way I’m using daily builds.

Auk’s rationale is the most obvious I think. But I would guess you would see a “stutter” in the graphics at the time the double food appeared if it was the case. There’s no quick stutter to the animation when it happens, is there?

Also, I noticed you are not setting the timerID in the timerStash for the case where i == 1. No idea what that causes later, but it looks asymmetric.

Edit: You could try and stress your app, forcing the bug to manifest… You could try a few runs, each time decreasing the timer separation of objects (400 ms, 300 ms, 200 ms, etc) to see if that flushes the bug out into the open (if it is, in fact, timing related).

Hi Aidin,

If you can’t reproduce it for over 2 days, that’ll make it much harder to debug (obviously!).

What I suggest is that you insert some print statements as you set each timer, and also within the closure.  For example, you could print the index i and the current os.time() at the time each timer is created, and again within the closure.  That way, the next time you see this issue, you’ll have some useful info in the console to potentially help you narrow down the root cause.

  • Andrew

Why not

[lua]timerStash.timerID = timer.performWithDelay( (i - 1) * 500, myclosure, 1)[/lua]

Saves 1 line.

I have some bad experiences with timers and calling asynchrone functions so I often try to keep the time as low as possible. Indeed try to print out all the local and global variables in that loop.

Thanks guys, I’ve decided to remove timer.performWithDelay and just after I spawn objects, I offset them before entering the screen as I think dealing with this is way harder than this.