[solved] Updating & Rendering in a timely fashion

Thank you :slight_smile:
And not to be rude :slight_smile: but that link’s been posted earlier in this threads page XD

Thanks for your feedback though (:

[quote]using Swing or other “timers” is fine. all of them use System.sleep(1) anyway.
[/quote]
@basil_
Well, sort of. The util.Timer relies on native code implementing Object’s wait(long) method. It is set to a value that corresponds to the schedule of the next TimerTask on its internal queue. Thus the wait is probably larger than 1.

Thread.sleep(1) uses native code for sleep(long).

But both do make use of the System Clock which is either limited by larger of the granularity of the milliseconds input parameter, or by the minimum interval at which the clock is updated (about 16 millis for some older Microsoft OS).

I don’t think the util.Timer adds much in the way of overhead. The most significant addition is a very nifty queue implementation set up for the TimerTasks (I think it’s set to a simple array of 128 unique tasks), but it is a model of efficiency (written by Joshua Bloch). I would guess having a single wait(long) is probably better than multiple calls to sleep(1). But these are quibbles to your main point.

yes, that’s what i ment. on windows we’re stucked at 15-16 ms. no selfmade native can help here, System.nanoTime() already is.

at least instead of Thread.sleep(1) we can use

LockSupport.parkNanos(500000); // 0.5 ms

what works pretty good on linux.

anyway, that’s low level. for high level most java utils are useful in the end.

There is no specific reason or objection, but I don’t like them. I would like to quote Eli Delventhal’s Game Loops article.

That’s the only reason why I don’t like those Timers in game loops. Hope this helps.

If you’re going to use a Timer for the convenience, you might as well use a ScheduledExecutorService:


ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

scheduler.scheduleAtFixedRate(() -> {
    update();
    render();
}, 0, 16, TimeUnit.MILLISECONDS);

I still wouldn’t do this for a game however, as you cannot control what happens when update() and render() take more than 16 ms.

@SHC
I always found that quote from Eli to be very puzzling. So, util.Timer was not intended for heavy-lifting? How can a person tell this? It’s just code. Nothing in the API warns about this, nor anything in Joshua Bloch’s well-documented source code for the class. Code in the TimerTask runs the same as code in a game loop, as far as I can tell, though they rely on different native routines (wait vs sleep).

@BurntPizza
…doesn’t the exact same thing happens when update() and render() take more than the allotted time: the next iteration simply gets pushed back? This is the same with the ScheduledExecutorService (as you configured it), with util.Timer and with a game loop. Yes?

But if the NEXT iteration after that takes less than 16 millis, with either the scheduler or timer’s .sheduleAtFixedRate(), an attempt to recover the lost time, gratis, no extra coding needed.

I suspect that the poor reputation util.Timer has vs. coding one’s own timing mechanisms into game loops has an element of “herding behavior” to it or some sort of echo chamber effect. I have yet to read one rational explanation or see a concrete example that justifies the preference. I point out again, even “Killer Game Programming” from way back when gets the same performance with util.Timer as with their preferred game loops, and then says well, we are going to stick with writing our own game loops anyway. (The book does an excellent job of demolishing the swing.Timer, though!)

But this is okay. It probably doesn’t make a bit of difference, and my harping on this is an example of I don’t know what. I certainly don’t want to try and tell other people they should convert their game loops to TimerTasks.

How is a fixed time step not reliable? It’s the same idea but you never sleep the thread.

Edit: I suppose if you sleep the thread then you aren’t wasting cpu time doing nothing. Also, my bad reposting the link.

in a rendering loop a fixed timestep/sleep-duration is not taking the “payload” in count.

you might get a stable sleep but it would add to the cpu-time spend updating and rendering things.