• Steam recently changed the default privacy settings for all users. This may impact tracking. Ensure your profile has the correct settings by following the guide on our forums.

Timer Tutorial

A_Nub

Developer
Well, I am not sure how many people have trouble with this, but hey it is always good to have a reference. This is the second tutorial I have written so bear with me if and when I explain things poorly.

Prerequisite:
* Understanding of C/C++ syntax
* Comfortable Coding in C/C++

Concepts Covered:
* Timing (based on ctime)


Intro:
Ok so lets start with an example. Say you have a variable, and you need it to be updated exactly every 2 seconds. How would you achieve this? Well you could use a loop and stall it the proper amount of time for the CPUs speed to wait 2 seconds. That however would be silly and uncalled for, and wastes CPU time for other processing. So we will use a simple utility found in the standard C library called ctime (time.h).

The Process:
time.h contains many useful functions for time, including but not limited to obtaining the date, the time of day and number of ticks.

Tick - a single iteration of the never ending "loop" on the RTC (Real Time Clock) processor. A ticks interval is always exactly the same time from the previous tick. There is a constant that defines this time, and is relevant to the device being compiled for.

What we are using:
Now we will move into ctime and how we will obtain the time passed by using a simple calculation via ticks. Now you may ask, "if we can just get the time, why waste cpu calculating the time?" this is because obtaining the systems time is actually a lot slower and requires more memory.

So we will need only 2 things from ctime.

1) clock_t clock(); // returns the current tick
2) CLOCKS_PER_SEC;

Now we have introduced some questions. "What is a clock_t?" and "What is CLOCKS_PER_SEC?"
A clock_t is simply a typedef unsigned int.
CLOCKS_PER_SEC is simply the number of ticks per second.

The TUT:
Ok here we go. First off we need to create some variables.

[Timer.h]
[highlight=cpp]
/*
Timer.cpp By: Zachry Thayer (c) 2009
*/

#include <time.h>

class Timer{
private:
clock_t startTick;//the tick for when we first create an instance
clock_t currTick;//the most recent tick read
clock_t lastTick;//the tick from the last update
clock_t deltaTick;//currTick - lastTick

float elapsedSeconds;// time since created in seconds
float deltaSeconds;// time since last tick in seconds

[/highlight]

Now we need to declare our class methods

[Timer.h]
[highlight=cpp]
public:
/*
Constructor
*/
Timer();

/*
Deconstructor
*/
~Timer();

/*
Update Timer (to be called once per main loop[more often for more accuracy])
*/
void update();

/*
Return Elapsed time since the timer was created
*/
float elapsedTime();

/*
Return Delta time since the timer was created
*/
float deltaTime();

/*
Reset elapsed time to 0
*/
void reset();
};
[/highlight]

Seems simple enough so far, now we get into the actual code.

[Timer.cpp]
[highlight=cpp]
/*
Constructor
*/
Timer::Timer(){
startTick = clock();//Obtain current tick
currTick = startTick;//All ticks are the same since we have just been created
lastTick = currTick;//copy ^
deltaTick = 0;// X - X = 0

elapsedSeconds = 0.f;//no time has passed
deltaSeconds = 0.f;//ditto ^
}

/*
Deconstructor
*/
Timer::~Timer(){
//we did not allocate any dynamic data
}
[/highlight]

Ok simple enough so far, just initializing variables. Now for the part you all wanted the timer update.


[Timer.cpp]
[highlight=cpp]
/*
Update Timer (to be called once per main loop[more often for more accuracy])
*/
void Timer::update(){
lastTick = currTick;//store the currTick before we update it
currTick = clock();//update current tick
deltaTick = currTick - lastTick;//calculate the difference in ticks
deltaSeconds = (float)deltaTick/(float)CLOCKS_PER_SEC;//Simple division to calculate seconds based on the number of ticks
elapsedSeconds += deltaSeconds;// add to overall time
}
[/highlight]

Pretty Simple huh.
The rest here is self explanatory.

[highlight=cpp]

/*
Return Elapsed time since the timer was created
*/
float Timer::elapsedTime(){
return elapsedSeconds;
}

/*
Return Delta time since the timer was created
*/
float Timer::deltaTime(){
return deltaSeconds;
}

/*
Reset elapsed time to 0
*/
void reset(){
elapsedTime = 0.f;
}
[/highlight]

Thanks for hearing me through, I tried to make that as painless as possible.
If there are any needed corrections please PM me.
[Timer.h]
[highlight=cpp]
/*
Timer.cpp By: Zachry Thayer (c) 2009
*/

#include <time.h>

class Timer{
private:
clock_t startTick;//the tick for when we first create an instance
clock_t currTick;//the most recent tick read
clock_t lastTick;//the tick from the last update
clock_t deltaTick;//currTick - lastTick

float elapsedSeconds;// time since created in seconds
float deltaSeconds;// time since last tick in seconds
public:
/*
Constructor
*/
Timer();

/*
Deconstructor
*/
~Timer();

/*
Update Timer (to be called once per main loop[more often for more accuracy])
*/
void update();

/*
Return Elapsed time since the timer was created
*/
float elapsedTime();

/*
Return Delta time since the timer was updated
*/
float deltaTime();

/*
Reset elapsed time to 0
*/
void reset();
};
[/highlight]

[Timer.cpp]
[highlight=cpp]
/*
Constructor
*/
Timer::Timer(){
startTick = clock();//Obtain current tick
currTick = startTick;//All ticks are the same since we have just been created
lastTick = currTick;//copy ^
deltaTick = 0;// X - X = 0

elapsedSeconds = 0.f;//no time has passed
deltaSeconds = 0.f;//ditto ^
}

/*
Deconstructor
*/

Timer::~Timer(){
//we did not allocate any dynamic data
}

/*
Update Timer (to be called once per main loop[more often for more accuracy])
*/
void Timer::update(){
lastTick = currTick;//store the currTick before we update it
currTick = clock();//update current tick
deltaTick = currTick - lastTick;//calculate the difference in ticks
deltaSeconds = (float)deltaTick/(float)CLOCKS_PER_SEC;//Simple division to calculate seconds based on the number of ticks
elapsedSeconds += deltaSeconds;// add to overall time
}


/*
Return Elapsed time since the timer was created
*/
float Timer::elapsedTime(){
return elapsedSeconds;
}

/*
Return Delta time since the timer was updated
*/
float Timer::deltaTime(){
return deltaSeconds;
}

/*
Reset elapsed time to 0
*/
void reset(){
elapsedTime = 0.f;
}
[/highlight]

Check Back soon for Callback implementation.
 

NeilR

eXo Admin
Enforcer Team
Nice tutorial. I realize this isn't strictly for beginners but with them in mind I would suggest to use variable prefix notation. When you start collaborating with a lot of people on software which is constantly evolving it becomes quite the godsend.

Anyways, thanks for sharing and I look forward to checking out your next one. :tup:
 

NeilR

eXo Admin
Enforcer Team
Yeah it's never necessary but it's good to instill good coding practices.
 

yaustar

New Member
A couple of minor niggles:

- Use #include <ctime> (C++ time header) over #include <time.h> (C time header). The former may have changes for C++ compilers.
- Make the accessor functions const.
- No need to declare and define the destructor at all if there is nothing in it.

Any other niggles I have is style based.
 

Hardrive

Contributor
A couple of minor niggles:

- Use #include <ctime> (C++ time header) over #include <time.h> (C time header). The former may have changes for C++ compilers.
- Make the accessor functions const.
- No need to declare and define the destructor at all if there is nothing in it.

Any other niggles I have is style based.

Good to see you here yaustar :)
 

A_Nub

Developer
Yaustar the tutorial is only half done, im finishing up the second half, Timer Based callbacks. and Ill make them const ;)
 
Top