Jump to content
  • Advertisement
Sign in to follow this  
by

Timer Mistake

This topic is 3878 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I have a Timer class that uses SDL_GetTicks() for tick counting. It calls a callback function given by user via function pointer everytime inverval achieved. But it don't work properly. For example if i give 1000 as interval to constructor and start timer, after 7500 ticks, callback is called only for a few times but i was expecting it should be called for 7 times in that case. Some Codes:
ITimer::ITimer(int _iInterval, int _iRunning, void (*_vfCallback)(int, int), int _iLParam, int _iRParam)
{
	iInterval = _iInterval;
	iRunning = _iRunning;
	vfCallback = _vfCallback;
	uiTicks = 0;
	iLParam = _iLParam;
	iRParam = _iRParam;
	uiTicksWhenStarted = SDL_GetTicks();
}

void ITimer::Update()
{
	if(iRunning != 0)
	{
		uiTicks = SDL_GetTicks() - uiTicksWhenStarted;
		if((uiTicks % iInterval) == 0 && vfCallback != NULL)
			vfCallback(iLParam, iRParam);
	}
}

void ITimer::Start()
{
	iRunning = 1;
	uiTicks = 0;
}

void asd(int a, int b)
{
	counter++;
}




int main(int argc, char *argv[])
{
//
//some inits here ...
//

time = new ITimer(123, 1, asd, NULL /*lParam*/, NULL /*rParam*/);
time->Start();

 while(done == 0)
 {
   time->Update();
   //
   // game and render loop code here
   //
 }
//
// deallocs
//
}

I guess (uiTicks % iInterval) doesn't increase by 1. Also an image: http://img49.imageshack.us/img49/9227/clipboard01je1.png

Share this post


Link to post
Share on other sites
Advertisement
Quote:
I guess (uiTicks % iInterval) doesn't increase by 1.


Indeed. You don't want to trigger the event at the time where it was expected to trigger. You want to trigger the event if it should have already happened when you check the time.

Share this post


Link to post
Share on other sites
You're speaking like a puzzle to me :) Could you explain more detailed please?

Share this post


Link to post
Share on other sites

ITimer::ITimer(int _iInterval, int _iRunning, void (*_vfCallback)(int, int), int _iLParam, int _iRParam)
{
iInterval = _iInterval;
iRunning = _iRunning;
vfCallback = _vfCallback;
uiTicks = 0;
iLParam = _iLParam;
iRParam = _iRParam;
lastTimerTrigger = SDL_GetTicks();
}


void ITimer::Update()
{
if(iRunning != 0)
{
int timeSinceLastUpdate = SDL_GetTicks() - lastTimerTrigger;
if(timeSinceLastUpdate > iInterval && vfCallback != NULL) {
lastTimerTrigger = SDL_GetTicks();
vfCallback(iLParam, iRParam);
}
}
}








Depending on design, you may want to consider what happens when multiple intervals have elapsed since your last update. In which case you could do something like this:



void ITimer::Update()
{
if(iRunning != 0)
{
int timeSinceLastUpdate = SDL_GetTicks() - lastTimerTrigger;
while(timeSinceLastUpdate > iInterval && vfCallback != NULL) {
vfCallback(iLParam, iRParam);
timeSinceLastUpdate -= iInterval;
}
// timeSinceLastUpdate is now some left-over time. Push
// back lastTimerTrigger to account for that amount of elapsed
// time for the next time we get an Update
lastTimerTrigger = SDL_GetTicks() - timeSinceLastUpdate;
}
}








This way, if your interval is 5 seconds, but 11 seconds have passed since your last update, the callback will be called twice.

You may not want exactly that, but hopefully you should get the idea.

[Edited by - Tenbatsu on December 5, 2007 9:11:37 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!