Last active
October 26, 2016 18:19
-
-
Save vasumahesh1/7403eb78b73ff2310ffe094526298afb to your computer and use it in GitHub Desktop.
Game Timer Source File
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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