Alternative to NSTimer - Printable Version
+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: iPhone, iPad & iPod Game Development (/forum-11.html)
+--- Thread: Alternative to NSTimer (/thread-1592.html)
Alternative to NSTimer - Ammonium - Apr 6, 2009 12:44 PM
When using a while loop to handle the main game loop, is your game able to handle multiple touches? I switched from NSTimer to a while loop similar to demonpants' but my app no longer handles multiple touch events. It won't recognize new touch events unless any previous touch event has ended.
Alternative to NSTimer - demonpants - Apr 8, 2009 02:43 PM
Multiple touches works just fine for me. Did you make sure that setting didn't somehow get turned off?
Alternative to NSTimer - mterlecki - May 12, 2009 09:26 AM
Where exactly do you place this mainLoop code? Is this called once from applicationDidFinishLaunching or are you wedging in someplace else?
I have set up my game to enter its main loop from applicationDidFinishLaunching
and never return, however I get no rending what-so-ever - so I suspect that I have a flaw in the setup.
Alternative to NSTimer - longjumper - May 12, 2009 06:08 PM
Just read the previous posts...
When you create an instance of a NSRunLoop, it creates an autorelease pool. Any methods/functions/whatevers that get called by this NSRunLoop have an autorelease pool to back it up.
A CFRunLoop does not create an autorelease pool. If a CFRunLoop calls a method/function/whatever, it is not backed up by an autorelease pool. For example, when you create a CFStream with a callback for when bytes arrive, that callback function does not have an autorelease pool.
You might think you can avoid this problem by not using autorelease. This is ridiculous. Just because you don't explicitly send an autorelease message to one of the objects you own doesn't mean that a method you call doesn't send the message autorelease to one of the objects it owns.
Alternative to NSTimer - mister_t - May 13, 2009 12:49 PM
Well first of all thanks for all the useful information in this thread, I was having problems with NSTimer for quite some time. I now call the gameloop in my glView with
Is this the preferred way, or is there a more efficient alternative?
Alternative to NSTimer - green_ghost - May 13, 2009 11:12 PM
Thanks for the suggestion.
I gained a couple fps with this code rather than using a nstimer.
In my mainloop I added, in addition to the
while( CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.004, FALSE) == kCFRunLoopRunHandledSource);
I added a safe sleep to keep the loop from polling too heavily.
Alternative to NSTimer - bmantzey - May 15, 2009 09:25 AM
My 2 cents... I'm working on a game that's become quite large in scope now. It's in Objective C as much as possible but since we had to port from Windows some of the engines, there are many areas that are Objective-C++. It's mixing 2D and 3D graphics in OpenGL ES and has audio, accelerometer, touch, tap, and the kitchen sink. I've been using NSTimer for the game loop at 1/60 ever since the beginning and mach timers for timing and it runs great.
From experience I recommend strongly that you keep NSTimer for your loop and use mach for timing. If you even get more than 60 FPS, your game is pretty simple and it shouldn't matter anyway. If it's less than 60 FPS NSTimer will fire as frequently as possible anyway. Trying to do all this other stuff is complicating things for you and might make your life miserable.
Apple is a very successful company and they have some of the most intelligent and innovative people in the world working for them. If you find yourself cussing them as you struggle to defy their design, maybe consider that you're doing something wrong, not they.
Alternative to NSTimer - warmi - May 15, 2009 10:49 AM
bmantzey Wrote:My 2 cents... I'm working on a game that's become quite large in scope now. It's in Objective C as much as possible but since we had to port from Windows some of the engines, there are many areas that are Objective-C++. It's mixing 2D and 3D graphics in OpenGL ES and has audio, accelerometer, touch, tap, and the kitchen sink. I've been using NSTimer for the game loop at 1/60 ever since the beginning and mach timers for timing and it runs great.
Oh they are wrong often enough ... like for instance their borked implementation of OpenGL driver (copyVertexData anyone ?) ... implicitly disabling anti-aliasing by forcing OpenGL ES devs to render to a texture etc ..etc ..
NSTimer is kind of like WM_TIMER on Windows â€¦. good enough for GUI apps but I donâ€™t know anybody who uses it for coding time sensitive apps ( like games)
Alternative to NSTimer - warmi - May 15, 2009 10:53 AM
green_ghost Wrote:Thanks for the suggestion.
Why don't you just run CFRunLoopRunInMode with whatever time period you want to sleep for instead of doing selects ?
Alternative to NSTimer - green_ghost - May 15, 2009 07:45 PM
Yeah, your right.
But I did find the most responsiveness and fps when I used two calls to pause in the loop.
Alternative to NSTimer - ShiftZ - May 16, 2009 02:24 AM
Finally composed fixed time step loop:
begin_time = GetTimeInMsSinceCPUStart();
step_time = GetTimeInMsSinceCPUStart();
end_time = GetTimeInMsSinceCPUStart();
double sleep = STEP_DT - (end_time - begin_time);
if (sleep < 0.002) sleep = 0.002;
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, sleep, false) == kCFRunLoopRunHandledSource);
LOG("World step: %10.3f", step_time - begin_time);
LOG("Render step: %10.3f", end_time - step_time);
if (last_time != 0.0)
LOG("Frame DT = %10.3f, WorkTime = %10.3f", begin_time - last_time, end_time - begin_time);
last_time = begin_time;
If frame work time is below STEP_DT, then rest of the time smoking CFRunLoopRunInMode. If frame time is above STEP_DT, then CFRunLoopRunInMode should run at least 0.002 sec.
Alternative to NSTimer - mpatric - May 18, 2009 09:49 AM
I'm going to disagree with the general sentiment in this thread and say using a thread is much better than using a timer. If the amount of time it takes to render your frame gets too close to your timer period (16.667ms for 60fps), then the incidence of misfires from the timer becomes unacceptable. I posted a blog about this earlier today (although I wrote this up a few months ago).
A timer overrun, no matter how small will mean a 'tick' is missed. The next tick will be at the next scheduled time. It's quite common to see ticks like this:
16.67ms, 16.67ms, 33.34ms, 16.67ms, etc.
That 33.34ms tick is generally going to cause a jitter. Sure, increasing the timer period as many here have suggested helps. But a misfire still means waiting for the next scheduled tick. A thread will never have this problem.
In fact, if your thread churns out frames as fast as possible, you'll find if your rendering takes less than 16.67ms your framerate will be exactly 60fps as one of the calls (I suspect flipping the frame buffer) blocks.
So in my book, a thread is the only option unless you can render your frame in something significantly less than 16.67ms (for 60fps).
Alternative to NSTimer - ShiftZ - May 18, 2009 11:55 AM
mpatric Wrote:I'm going to disagree with the general sentiment in this thread, and say using a thread is much better than using a timer.
Generally this thread dedicated exactly to unacceptable behavior of NSTimer. I have found this thread when i have got suddenly doubled render time. i was trying to setup fixed time step game loop with dt = 0.030s, and found that actually it takes 0.060s.
As you can see my post above there is no NSTimer atall, and no mess with threads. Only odd thing is I have very unstable render time that jumps from 42ms to 55ms from frame to frame, and i cannot find reason of it.
PS I can only confirm that render in thread could increase render performance in some cases.
Alternative to NSTimer - warmi - May 18, 2009 12:03 PM
mpatric Wrote:I'm going to disagree with the general sentiment in this thread and say using a thread is much better than using a timer. If the amount of time it takes to render your frame gets too close to your timer period (16.667ms for 60fps), then the incidence of misfires from the timer becomes unacceptable. I posted a blog about this earlier today (although I wrote this up a few months ago).
Yeah, it makes sense.
On other hand I am kind of puzzled why would you need a separate thread to handle timing issues.
Imo it is much simpler to run your own loop and simply enter the default message loop if you have some time to spare or just for a set bare minimum if your game starts to chase its own tail.
Am I missing anything here ?
Alternative to NSTimer - DoG - May 18, 2009 02:56 PM
I think people are misunderstanding NSTimer. It's not a hard-realtime timing solution. You're supposed to set the timer to fire faster than your intended framerate, and check the time in your callback. If it's running too fast, you'd just do nothing, and wait for the next callback. If the timer runs slower than intended, it's because device is busy doing something else.
The custom runloop doesn't do much else, only in a roundabout fashion. A separate thread only helps if the main thread is blocked on IO or other transactions which leave the CPU idle.