1 /* Copyright 2010 Jukka Jyl�nki
2
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6
7        http://www.apache.org/licenses/LICENSE-2.0
8
9    Unless required by applicable law or agreed to in writing, software
10    distributed under the License is distributed on an "AS IS" BASIS,
11    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12    See the License for the specific language governing permissions and
13    limitations under the License. */
14 #pragma once
15
16 /** @file Clock.h
17         @brief The Clock class. Supplies timing facilities. */
18
19 #ifdef __EMSCRIPTEN__
20
21 // The native type for high-resolution timing is double, use
22 // that instead of uint64, which is not natively supported but
23 // must be emulated, which is slow.
24 #define MATH_TICK_IS_FLOAT
25 #include <limits>
26 #endif
27
28 #include "../Math/MathNamespace.h"
29
30 MATH_BEGIN_NAMESPACE
31
32 /// A tick is the basic unit of the high-resolution timer. If MATH_TICK_IS_FLOAT is defined,
33 /// then tick_t is a floating-point type. Otherwise a 64-bit unsigned integer is used instead.
34 #ifdef MATH_TICK_IS_FLOAT
35 typedef double tick_t;
36 const tick_t TICK_INF = std::numeric_limits<double>::infinity();
37 #else
38 typedef unsigned long long tick_t;
39 const tick_t TICK_INF = 0xFFFFFFFFFFFFFFFFULL;
40 #endif
41
42 /** @brief High-resolution timing and system time.
43
44         Gives out timing information in various forms. Use this rather than
45         any platform-dependent perf-counters or rdtsc or whatever.*/
46 class Clock
47 {
48 public:
49         Clock();
50 //      ~Clock() {}
51
52         /// Sleeps the current thread for the given amount of milliseconds.
53         static void Sleep(int milliseconds);
54
55         /// @return The current year.
56         static int Year();
57
58         /// @return The current month, [1,12]
59         static int Month();
60
61         /// @return The current day of month, [1,31]
62         static int Day();
63
64         /// @return The current hour of day, [0,23]
65         static int Hour();
66
67         /// @return The current clock minute, [0,59]
68         static int Min();
69
70         /// @return The current clock second, [0,59]
71         static int Sec();
72
73         /// @return The current system time counter in milliseconds.
74         static unsigned long SystemTime();
75
76         /// @return The number of milliseconds since application start.
77         static unsigned long Time();
78
79         /// @return The low part of the current tick-time (using whatever high-resolution counter available)
80         static unsigned long TickU32();
81
82         /// @return The current tick-time (using whatever high-resolution counter available)
83         static tick_t Tick();
84
85         /// @return How many ticks make up a second.
86         static tick_t TicksPerSec();
87
88         static inline tick_t TicksPerMillisecond() { return TicksPerSec() / 1000; }
89
90         /// Returns the number of ticks occurring between the two wallclock times.
91         static inline tick_t TicksInBetween(tick_t newTick, tick_t oldTick)
92         {
93                 return (tick_t)(newTick - oldTick);
94         }
95
96         /// Returns true if newTick represents a later wallclock time than oldTick.
97         static inline bool IsNewer(tick_t newTick, tick_t oldTick)
98         {
99 #ifdef MATH_TICK_IS_FLOAT
100                 return newTick >= oldTick;
101 #else
102                 return TicksInBetween(newTick, oldTick) < ((tick_t)(-1) >> 1);
103 #endif
104         }
105
106         static inline float MillisecondsSinceF(tick_t oldTick) { return TimespanToMillisecondsF(oldTick, Tick()); }
107         static inline double MillisecondsSinceD(tick_t oldTick) { return TimespanToMillisecondsD(oldTick, Tick()); }
108
109         static inline float SecondsSinceF(tick_t oldTick) { return TimespanToSecondsF(oldTick, Tick()); }
110         static inline double SecondsSinceD(tick_t oldTick) { return TimespanToSecondsD(oldTick, Tick()); }
111
112         static inline float TicksToMillisecondsF(tick_t ticks) { return ticks * 1000.f / TicksPerSec(); }
113         static inline double TicksToMillisecondsD(tick_t ticks) { return ticks * 1000.0 / TicksPerSec(); }
114
115         static inline float TicksToSecondsF(tick_t ticks) { return ticks / (float)TicksPerSec(); }
116         static inline double TicksToSecondsD(tick_t ticks) { return ticks / (double)TicksPerSec(); }
117
118         static inline float TimespanToMillisecondsF(tick_t oldTick, tick_t newTick) { return TicksToMillisecondsF(TicksInBetween(newTick, oldTick)); }
119         static inline double TimespanToMillisecondsD(tick_t oldTick, tick_t newTick) { return TicksToMillisecondsD(TicksInBetween(newTick, oldTick)); }
120
121         static inline float TimespanToSecondsF(tick_t oldTick, tick_t newTick) { return TicksToSecondsF(TicksInBetween(newTick, oldTick)); }
122         static inline double TimespanToSecondsD(tick_t oldTick, tick_t newTick) { return TicksToSecondsD(TicksInBetween(newTick, oldTick)); }
123
124         static unsigned long long Rdtsc();
125
126 private:
127         static tick_t appStartTime;      ///< Application startup time in ticks.
128
129         /// Initializes clock tick frequency and marks the application startup time.
130         static void InitClockData();
131
132 #ifdef WIN32
133         // The following two are actually used as LARGE_INTEGERs, but to avoid having to pull Windows.h in Clock.h, define them
134         // as identically sized u64 instead.
135         static u64/*LARGE_INTEGER*/ ddwTimerFrequency; ///< Ticks per second.
136 #endif
137 #ifdef __APPLE__
138         static tick_t ticksPerSecond;
139 #endif
140 };
141
142 MATH_END_NAMESPACE

Go back to previous page