1 /* 2 * DSFML - The Simple and Fast Multimedia Library for D 3 * 4 * Copyright (c) 2013 - 2018 Jeremy DeHaan (dehaan.jeremiah@gmail.com) 5 * 6 * This software is provided 'as-is', without any express or implied warranty. 7 * In no event will the authors be held liable for any damages arising from the 8 * use of this software. 9 * 10 * Permission is granted to anyone to use this software for any purpose, 11 * including commercial applications, and to alter it and redistribute it 12 * freely, subject to the following restrictions: 13 * 14 * 1. The origin of this software must not be misrepresented; you must not claim 15 * that you wrote the original software. If you use this software in a product, 16 * an acknowledgment in the product documentation would be appreciated but is 17 * not required. 18 * 19 * 2. Altered source versions must be plainly marked as such, and must not be 20 * misrepresented as being the original software. 21 * 22 * 3. This notice may not be removed or altered from any source distribution 23 * 24 * 25 * DSFML is based on SFML (Copyright Laurent Gomila) 26 */ 27 28 /** 29 * $(U Time) encapsulates a time value in a flexible way. It allows to define a 30 * time value either as a number of seconds, milliseconds or microseconds. It 31 * also works the other way round: you can read a time value as either a number 32 * of seconds, milliseconds or microseconds. 33 * 34 * By using such a flexible interface, the API doesn't impose any fixed type or 35 * resolution for time values, and let the user choose its own favorite 36 * representation. 37 * 38 * Time values support the usual mathematical operations: 39 * you can add or subtract two times, multiply or divide a time by a number, 40 * compare two times, etc. 41 * 42 * Since they represent a time span and not an absolute time value, times can 43 * also be negative. 44 * 45 * Example: 46 * --- 47 * Time t1 = seconds(0.1f); 48 * Int milli = t1.asMilliseconds(); // 100 49 * 50 * Time t2 = sf::milliseconds(30); 51 * long micro = t2.asMicroseconds(); // 30000 52 * 53 * Time t3 = sf::microseconds(-800000); 54 * float sec = t3.asSeconds(); // -0.8 55 * --- 56 * 57 * --- 58 * void update(Time elapsed) 59 * { 60 * position += speed * elapsed.asSeconds(); 61 * } 62 * 63 * update(milliseconds(100)); 64 * --- 65 * 66 * See_Also: 67 * $(CLOCK_LINK) 68 */ 69 module nudsfml.system.time; 70 71 public import core.time: Duration; 72 import core.time: usecs; 73 74 import std.traits: isNumeric; 75 76 /** 77 * Represents a time value. 78 */ 79 struct Time { 80 private long m_microseconds; 81 82 //Internal constructor 83 package this(long microseconds) { 84 m_microseconds = microseconds; 85 } 86 87 /** 88 * Return the time value as a number of seconds. 89 * 90 * Returns: Time in seconds. 91 */ 92 float asSeconds() const { 93 return m_microseconds/1_000_000f; 94 } 95 96 /** 97 * Return the time value as a number of milliseconds. 98 * 99 * Returns: Time in milliseconds. 100 */ 101 int asMilliseconds() const { 102 return cast(int)(m_microseconds / 1_000); 103 } 104 105 /** 106 * Return the time value as a number of microseconds. 107 * 108 * Returns: Time in microseconds. 109 */ 110 long asMicroseconds() const { 111 return m_microseconds; 112 } 113 114 /** 115 * Return the time value as a Duration. 116 */ 117 Duration asDuration() const { 118 return usecs(m_microseconds); 119 } 120 121 122 /** 123 * Predefined "zero" time value. 124 */ 125 static immutable(Time) Zero; 126 127 bool opEquals(const ref Time rhs) const { 128 return m_microseconds == rhs.m_microseconds; 129 } 130 131 int opCmp(const ref Time rhs) const { 132 if(opEquals(rhs)) { 133 return 0; 134 } else if(m_microseconds < rhs.m_microseconds) { 135 return -1; 136 } else { 137 return 1; 138 } 139 140 141 } 142 143 /** 144 * Overload of unary - operator to negate a time value. 145 */ 146 Time opUnary(string s)() const 147 if (s == "-") { 148 return microseconds(-m_microseconds); 149 } 150 151 152 /** 153 * Overload of binary + and - operators toadd or subtract two time values. 154 */ 155 Time opBinary(string op)(Time rhs) const 156 if((op == "+") || (op == "-")) { 157 static if (op == "+") { 158 return microseconds(m_microseconds + rhs.m_microseconds); 159 } 160 static if(op == "-") { 161 return microseconds(m_microseconds - rhs.m_microseconds); 162 } 163 } 164 165 /** 166 * Overload of += and -= assignment operators. 167 */ 168 ref Time opOpAssign(string op)(Time rhs) 169 if((op == "+") || (op == "-")) { 170 static if(op == "+") { 171 m_microseconds += rhs.m_microseconds; 172 return this; 173 } 174 static if(op == "-"){ 175 m_microseconds -= rhs.m_microseconds; 176 return this; 177 } 178 } 179 180 181 /** 182 * Overload of binary * and / operators to scale a time value. 183 */ 184 Time opBinary (string op, E)(E num) const 185 if(isNumeric!(E) && ((op == "*") || (op == "/"))) { 186 static if (op == "*") { 187 return microseconds(m_microseconds * num); 188 } 189 static if(op == "/") { 190 return microseconds(m_microseconds / num); 191 } 192 } 193 194 /** 195 * Overload of *= and /= assignment operators. 196 */ 197 ref Time opOpAssign(string op,E)(E num) 198 if(isNumeric!(E) && ((op == "*") || (op == "/"))) { 199 static if(op == "*") { 200 m_microseconds *= num; 201 return this; 202 } 203 static if(op == "/") { 204 m_microseconds /= num; 205 return this; 206 } 207 } 208 209 } 210 /** 211 * Construct a time value from a number of seconds. 212 * 213 * Params: 214 * amount = Number of seconds. 215 * 216 * Returns: Time value constructed from the amount of microseconds. 217 */ 218 Time seconds(float amount) { 219 return Time(cast(long)(amount * 1_000_000)); 220 } 221 /** 222 *Construct a time value from a number of milliseconds. 223 * 224 * Params: 225 * amount = Number of milliseconds. 226 * 227 * Returns: Time value constructed from the amount of microseconds. 228 */ 229 Time milliseconds(int amount) { 230 return Time(amount*1000); 231 } 232 233 /** 234 * Construct a time value from a number of microseconds. 235 * 236 * Params: 237 * amount = Number of microseconds. 238 * 239 * Returns: Time value constructed from the amount of microseconds. 240 */ 241 Time microseconds(long amount) { 242 return Time(amount); 243 } 244 245 /** 246 * Construct a time value from a Duration. 247 * 248 * Params: 249 * dur = The time duration. 250 * 251 * Returns: Time value constructed from the time duration. 252 */ 253 Time duration(Duration dur) { 254 return Time(dur.total!"usecs"()); 255 } 256 257 unittest 258 { 259 version(DSFML_Unittest_System) 260 { 261 262 import std.stdio; 263 264 writeln("Unit test for Time Struct"); 265 266 auto time = seconds(1); 267 268 assert(time.asSeconds() == 1); 269 270 assert((time*2).asSeconds() == 2); 271 272 assert((time/2).asSeconds() == .5f); 273 274 assert((time+seconds(1)).asSeconds() == 2); 275 276 assert((time-seconds(1)).asSeconds() == 0); 277 278 time += seconds(1); 279 280 assert(time.asSeconds() == 2); 281 282 time -= seconds(1); 283 284 assert(time.asSeconds() == 1); 285 286 time/=2; 287 288 assert(time.asSeconds() == .5f); 289 290 time*=2; 291 292 assert(time.asSeconds() == 1); 293 294 writeln("Time Struct passes all tests."); 295 writeln(); 296 } 297 }