Is there somthing wrong with pausing, resuming timers?

You made some great points I just discovered about paulscottrobson. The reason I have so many timers is this. I have ‘turrets’ which fires projectiles. The turret gets created by a function when needed with a timer like this;

            autoTurret.destroyTimer = timer.performWithDelay(autoTurret.lifeTime, destroySelf, 1)

And than I do the necessary removal things. And when game is paused I pause that timer, and resume when resumed. The projectiles the turret fires also has these timers, they spawn with a lifetime and a timer. And sometimes there are 50+ projectiles on-screen and all needs to be paused. I can now see why this might be a huge liability when it comes to being reliable. How do you advice I approach managing all these without timers?
 

 

Well, you can’t, because pausing this timer will just stop it being destroyed.

I’d write a class, or a module, which spawns the projectiles, thus it ‘knows’ about the projectiles (by keeping a list). The module can then send the projectiles positional updates (e.g. update display.x,display.y) and delete them based on their own personal timer. You can then control whether these timers are updated or not. It can also delete them all if you want. This can be driven by just one enterFrame() or timer, if you prefer.

I would add that this is in some ways counter-intuitive to Corona which does sort of encourage this glue together by the seat of your pants approach. There are some advantages to this, for example the approach I describe means you can’t use the physics module. The downside is the lack of modularity and compartmentalisation.

I see, thanks for the input. I guess I can’t use it because projectiles actually heavily dependent on physics, lots of bouncing etc. I’m yet to test this on a device but I hope it will work similar to simulator. Do you know if timers may cause any performance issues that I can’t see on the simulator?

Shouldn’t do. (It may be possible to ‘stop’ the physics engine, I haven’t used it much). There is a basic problem that an iPhone or an Android phone just isn’t that fast compared to a PC. The thing to do is try it before you’ve written too much code, just the core is working. It is worth having an old phone just to check these things, or a really cheap Android tablet. 

I made my first test on an s4 mini and it is… not very good. While almost nothing is happening I get an avg. of 55fps but when I have a few turrets and a few bullets it drops to ~20. It is not that noticeable while playing (some lag spikes does occur) but fps counter doesn’t lie! This is not really about the timers tho, I have ~100 objects with physics bodies colliding, I think that is the problem.

It is sad to see Corona SDK can’t handle this. Or perhaps it is bad coding? I would say not because when the turrets gets destroyed fps goes back up to ~55…

For performance reasons, it is better to create a pool of objects and re-use them, as opposed to a destroy/recreate cycle.

So perhaps create a pool of bullets and turrets, and when you “destroy” them, instead of removing them, you just move them off screen, set them to invisible and disable their physics bodies until you need them again.

So I guess you’re saying that timer.pause(someTimer), followed by timer.resume(someTimer) can cause issues?

I’ve never seen it in any of my apps, although I only use a handful of timers at a time.

It’s good to see you’ve found a workaround, but if you have a repeatable test-case, I think it would be a good idea to make an official bug report.

Is there a reason you’re doing:  pause, cancel, create vs. pause, resume or cancel, create?

It’s possible that when you pause the timer, we are setting some value in the table returned by timer.performWithDelay and when you cancel it with out nil’ing it out, the remaining data might confuse things.   I would only use pause, resume in pairs or cancel, performWithDelay in pairs.

Rob

@Rob

The way I interpreted his post was that pause, resume is causing problems for him, and that he found a workaround by using pause, cancel, create instead. But I may be wrong…

You are probably right Ingemar.  We do need a reproducible test case.

Yeah ingemar got it right. If I do pause than resume, unexpected results occur. I then use timer.pause() because it returns the time left, and I’m using it to set a new timer. I’ll try to prepare a test code to be reproducible but I don’t have high hopes because it is so unstable I don’t understand when exactly it happens, it will just work sometimes. I can of course send my whole project tho, you can see it happen with changing few lines there.

The whole project won’t help because we will spend hours trying to figure your code out and we really cant afford the engineering resources to debug your project.

Rob

Generally, timers and so on are problematic. It is difficult to know in what order they will fire and so on. 

Timers can be quite useful for frilly little bits, but in game core it is better to do it as a centralised timer event system, driven by one core timer event, and rather than (say) stop and resume timers, set a boolean to ignore them.

@paulscottrobson

Hi;

" it is better to do it as a centralised timer event system, driven by one core timer event, and rather than (say) stop and resume timers, set a boolean to ignore them."

Is there a tutorial somewhere that deals with this or an example maybe I could look at?

Cheers!

I actually wouldn’t use timers at all in the core code, but rely on the enterFrame() event. Timers can be used for little one offs - make a bang sound in 0.1s, draw this little bit of graphic fluff, but for managing core game events, you can end up with all sorts of complex interplays that are undebuggable because you can’t reproduce them. Only my opinion though.

Yes I think I have encountered this type of behaviour before… thus my interest in the subject.

OK Thanks for the reply, I will look into it more.

Cheers!

So if I wanted to do something every few seconds for instance, it would be something like what is discussed in the post below right!?

http://coronalabs.com/blog/2012/02/21/understanding-coronas-enterframe-event/

I would do something along those lines. It’s more about centralising the code that does similar sorts of things. If you have objects starting timers and sending messages to each other … asking for trouble.

Yes very interesting, it never occurred to me - to use the enterFrame() event in a “timer” type of way.

I am going to try that and see what affect it has on performance. 

Cheers.

So let me run this by you… for instance:

If FPS is 30 then a half second timer would look like this basically:

local framesPassed = 0

– enterFrame listener function
local function trackTime( event )
  framesPassed = framesPassed + 1

  if framesPassed >= 15 then
 

    --do something here

    framesPassed = 0
    – stop tracking time
    Runtime:removeEventListener( “enterFrame”, trackTime )
  end
end

–everytime I wanted to run the “timer” again I would use this
Runtime:addEventListener( “enterFrame”, trackTime )

So would something like this work as a timer? Or am I wrong? I think timers are easier to use and keep track of, however, more control over the firing of a function is appealing for me to avoid “all sorts of complex interplays that are undebuggable”.

OR

Maybe I just need better debugging skills? LOL

Cheers.