Originally Posted by
nerduke
How to do *something* when a specific time passes, without checking on every tick (and thus eating cpu)?
Designing "game update loop" are you?
Well as you already figured it out polling is not a god approach. In fact pooling is as if someone tasked you to do something every five minutes and then you go and keep constantly checking your watch over and over again to see when five minutes has passed. Not very effective is it.
Most commonly used approach for this is measuring the time it has taken you to do some work (updating game objects, rendering frame or whatever needs to be done in timed intervals) and then you calculate of how much time you need to sleep in order to reach the start of the next interval.
For instance lets say you have desired time interval of 1 second. You do some processing in current cycle which takes 236 ms. In order to start the next cycle precisely 1 second after the first cycle was started you calculate how much time you need to sleep after the work in your current cycle was done by simply substracting the time that work took from the desired time interval. In this case this would be 1000 ms (desired time interval) - 236 ms (time it took to do the work) and you get that you need to sleep for 764 ms. If the work would took 481 ms you would need to sleep 1000 ms - 481 ms = 519 ms.
So pseudocode for your loop would look something like this
Code:
repeat
Record when work started (get current time)
Do some work
Calculate how much time elapsed since work started till now
Calculate how much time you need to sleep by substracting the work time from desired interval
Sleep for needed time
unjtil EndLoop is True; //EndLoop is control variable used for terminating the loop
This way you are doing one loop per interval and thus are not burning CPU processing power for needlessly checking current time all the time. And your loop will be automatically adapting to the amount of workload that needs to be done in each cycle making sure that the code is executed in regular intervals regardless of how much time was needed to complete the work in specific cycle.
Granted it will fail if the time required to complete work in one cycle was bigger than the desired interval. You surely know this from games as being called lag.
As for using Delphi Timer for this sort of things. Be aware that since Delphi Timer is message based there is no guarantee that its message will be processed at the right time in order to fire the OnTime event. This means that its precision is far from being precise. How far? Years ago when I started programming I made a quick test application where I would place timer on the form and than use that timer to increase value of some variables storing seconds, minutes and hours. After a few hours of not doing anything my timer based clock would already be falling behind from computer clock by a second. Adding OnMouseMove event on the form which would simply update forms caption with mouse coordinates and then moving mouse rapidly for several minutes my timer based clock would be falling behind for several seconds already. Simply because processing all those mouse move messages would prevent on timer messages to be processed at precise intervals.
Bookmarks