1// tTimer.h 
2// 
3// Simple timer class. Like a stopwatch. Supports keeping track of time in a number of different units. Accuracy is all 
4// up to you - you call the update function. This code does not access low-level timer hardware. 
5// 
6// Copyright (c) 2005, 2017, 2019, 2020 Tristan Grimmer. 
7// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
8// granted, provided that the above copyright notice and this permission notice appear in all copies. 
9// 
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
11// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
12// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
13// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
14// PERFORMANCE OF THIS SOFTWARE. 
15 
16#pragma once 
17#include <ctime> 
18#include <Foundation/tPlatform.h> 
19#include <Foundation/tAssert.h> 
20#include <Foundation/tUnits.h> 
21namespace tSystem 
22
23 
24 
25// High accuracy cross platform timing functions. For windows the frequency is whatever the HW reports. For other 
26// platforms it's 1/1ns = 1000000000Hz but counts increment by whatever the internal timer resulution is in ns. 
27int64 tGetHardwareTimerFrequency(); 
28int64 tGetHardwareTimerCount(); 
29 
30 
31// Gets the number of seconds since the absolute time reference of 00:00:00 Coordinated Universal Time (UTC), 
32// Thursday, 1 January 1970. The std::time_t is essentially a big integer. 
33std::time_t tGetTimeUTC(); 
34std::time_t tGetTimeGMT(); 
35 
36 
37// Gets the current local time. Takes into account your timezone, DST, etc. 
38// std::tm is a field-based time format, HH, MM, SS etc. 
39std::tm tGetTimeLocal(); 
40std::tm tConvertTimeToLocal(std::time_t); 
41 
42 
43// Return a timepoint as a string. 
44enum class tTimeFormat 
45
46 Standard, // Eg. 2020-01-14 01:47:12 
47 Extended, // Eg. Tuesday January 14 2020 - 01:36:34 
48 Short, // Eg. Tue Jan 14 14:38:58 2020 
49}; 
50tString tConvertTimeToString(std::tm, tTimeFormat = tTimeFormat::Standard); 
51 
52 
53// Gets the number of seconds since application start. Uses the high-performance counter, 
54float tGetTime(); 
55double tGetTimeDouble(); 
56void tSleep(int milliSeconds); 
57 
58 
59class tTimer 
60
61public
62 // Creates a timer. You can specify whether the timer is constructed started or not. Internally a floating-point 
63 // (double) member is used to keep track of the elapsed time. You can choose the units it represents, which has 
64 // implications for overall timer precision. In general, use an internal unit that matches your domain - timing 
65 // oscillations of visible light? Use nanoseconds. If unit is Unspecified seconds are used. 
66 tTimer(bool start = true, tUnit::tTime unit = tUnit::tTime::Second) : UnitInternal(unit), Running(start), Time(0.0f) { if (UnitInternal == tUnit::tTime::Unspecified) UnitInternal = tUnit::tTime::Second; } 
67 
68 // Call this frequently. If Unit is not specified, internal units are used. 
69 void Update(float timeElapsed, tUnit::tTime = tUnit::tTime::Unspecified); 
70 
71 // Does nothing (idempotent) if timer already started (or stopped). 
72 void Start() { Running = true; } 
73 void Stop() { Running = false; } 
74 void Reset(bool start = true) { Time = 0.0; Running = start; } 
75 
76 // Returns the time in the units of Unit. If Unit is not specified, uses internal units. 
77 float GetTime(tUnit::tTime = tUnit::tTime::Unspecified) const
78 bool IsRunning() const { return Running; } 
79 tUnit::tTime GetInternalUnit() const { return UnitInternal; } 
80 
81 static double Convert(double time, tUnit::tTime from, tUnit::tTime to); 
82 
83private
84 // @todo Add getters that format the time into a number of different string formats. 
85 const static double UnitConversionTable[int(tUnit::tTime::NumTimeUnits)][int(tUnit::tTime::NumTimeUnits)]; 
86 
87 tUnit::tTime UnitInternal
88 bool Running
89 double Time
90 
91public
92 // For developers only. Easily add a new unit and recreate the unit conversion table. 
93 static void PrintHighPrecisionConversionTable(const char* outputFile); 
94}; 
95 
96 
97
98