Skip to content

Instantly share code, notes, and snippets.

@vasumahesh1
Last active October 26, 2016 18:19
Show Gist options
  • Save vasumahesh1/7403eb78b73ff2310ffe094526298afb to your computer and use it in GitHub Desktop.
Save vasumahesh1/7403eb78b73ff2310ffe094526298afb to your computer and use it in GitHub Desktop.
Game Timer Source File
#include "AzuraTimer.h"
#include <exception>
#include <stdint.h>
using namespace Azura;
/// <summary>
/// Constructor for Default Stopwatch Config
/// </summary>
Timer::Timer() :
mSecondsPerTick(0.0),
mCountdownLimit(0.0),
mDeltaTime(-1.0),
mBaseTime(0),
mPausedTime(0),
mStopTime(0),
mPrevTime(0),
mCurrTime(0),
mType(AzuraTimerType::Stopwatch) {
init();
}
/// <summary>
/// Constructor with Timer Type
/// </summary>
/// <param name="type">The Type of Timer to Construct</param>
Timer::Timer(AzuraTimerType type) :
mSecondsPerTick(0.0),
mCountdownLimit(0.0),
mDeltaTime(-1.0),
mBaseTime(0),
mPausedTime(0),
mStopTime(0),
mPrevTime(0),
mCurrTime(0),
mType(type) {
init();
}
/// <summary>
/// Internal Init Code
/// </summary>
void Timer::init() {
mDeltaTime = 0.0;
mPrevTime = getCurrentTime();
// Reset Countdown Variables
mCurrCountdown = mCountdownLimit;
__int64 ticksPerSec;
if (!QueryPerformanceFrequency((LARGE_INTEGER*)&ticksPerSec))
{
throw std::exception("QueryPerformanceFrequency");
}
mSecondsPerTick = 1.0 / (double)ticksPerSec;
}
/// <summary>
/// Pauses the Timer
/// </summary>
void Timer::Stop() {
// Already Stopped
if (mStopped) {
return;
}
mStopTime = getCurrentTime();
mStopped = true;
}
/// <summary>
/// Set the Timer Limit
/// </summary>
/// <param name="countdownLimit">The Timer Limit in Seconds</param>
void Timer::SetLimit(double countdownLimit) {
mCountdownLimit = countdownLimit;
mCurrCountdown = countdownLimit;
}
/// <summary>
/// Regular Function Callbacks
/// </summary>
/// <param name="callback">Callback Function void callback() type decl</param>
void Timer::OnCountdownEnd(void(*callback)()) {
mEventCountdownEnd = callback;
}
/// <summary>
/// Use a Boost Binded Member Function
/// </summary>
/// <param name="callback">AzuraBasicCallback</param>
void Timer::OnCountdownEnd(AzuraBasicCallback callback) {
mEventCountdownEnd = callback;
}
/// <summary>
/// Tick Function - To be executed on every call.
/// </summary>
/// <param name="callback">Callback Function to execute if provided</param>
void Timer::Tick(void(*callback)()) {
if (mStopped) {
mDeltaTime = 0.0;
return;
}
processTick();
if (callback != nullptr) {
callback();
}
if (mType == AzuraTimerType::Countdown) {
processCountdown();
}
}
/// <summary>
/// Tick Function - To be executed on every call.
/// </summary>
/// <param name="callback">Boost Bound Callback</param>
void Timer::Tick(AzuraBasicCallback callback) {
if (mStopped) {
mDeltaTime = 0.0;
return;
}
processTick();
if (callback != nullptr) {
callback();
}
if (mType == AzuraTimerType::Countdown) {
processCountdown();
}
}
/// <summary>
/// Process a Regular Tick
/// </summary>
void Timer::processTick() {
mCurrTime = getCurrentTime();
mDeltaTime = (mCurrTime - mPrevTime) * mSecondsPerTick;
mPrevTime = mCurrTime;
// Power Saving Fix or CPU Shuffled Fix
mDeltaTime = mDeltaTime >= 0.0 ? mDeltaTime : 0.0;
}
/// <summary>
/// Process a Countdown Tick
/// </summary>
void Timer::processCountdown() {
mCurrCountdown -= mDeltaTime;
mCurrCountdown = mCurrCountdown >= 0.0 ? mCurrCountdown : 0.0;
if (mCurrCountdown != 0.0) {
return;
}
if (mEventCountdownEnd != nullptr) {
mEventCountdownEnd();
}
Stop();
}
/// <summary>
/// Internal Function to get the Current Time
/// </summary>
/// <returns>Current Time from OS</returns>
__int64 Azura::Timer::getCurrentTime() {
__int64 currTime;
if (!QueryPerformanceCounter((LARGE_INTEGER*)&currTime))
{
throw std::exception("AzuraTimer - Tick - QueryPerformanceCounter");
}
return currTime;
}
/// <summary>
/// Returns the Timer Time total. Depends on if the Game has been paused or is under resume.
/// </summary>
/// <returns>Total Time Currently</returns>
double Timer::TotalTime() const {
if (mStopped) {
// If Paused mCurrTime is no longer updated per tick, instead mStopTime is used
return ((mStopTime - mPausedTime) - mBaseTime) * mSecondsPerTick;
}
else {
// If Playing we mCurrTime is latest.
return ((mCurrTime - mPausedTime) - mBaseTime) * mSecondsPerTick;
}
}
/// <summary>
/// Returns the Delta Time Elapsed between Frames
/// </summary>
/// <returns>Delta Time</returns>
double Timer::DeltaTime() const {
return mDeltaTime;
}
/// <summary>
/// Resets the Timer
/// </summary>
void Timer::Reset() {
__int64 currTime = getCurrentTime();
mBaseTime = currTime;
mPrevTime = currTime;
mStopTime = 0;
mStopped = false;
mCurrCountdown = mCountdownLimit;
}
/// <summary>
/// Start the Timer/Stopwatch
/// </summary>
void Timer::Start() {
// Not Stopped
if (!mStopped) {
return;
}
__int64 startTime = getCurrentTime();
// Is Stopped and trying to "Resume" hence record the deltas
mPausedTime += (startTime - mStopTime);
mPrevTime = startTime;
// Release the Stop Flags
mStopTime = 0;
mStopped = false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment