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 dsfml.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 { 81 private long m_microseconds; 82 83 //Internal constructor 84 package this(long microseconds) 85 { 86 m_microseconds = microseconds; 87 } 88 89 /** 90 * Return the time value as a number of seconds. 91 * 92 * Returns: Time in seconds. 93 */ 94 float asSeconds() const 95 { 96 return m_microseconds/1_000_000f; 97 } 98 99 /** 100 * Return the time value as a number of milliseconds. 101 * 102 * Returns: Time in milliseconds. 103 */ 104 int asMilliseconds() const 105 { 106 return cast(int)(m_microseconds / 1_000); 107 } 108 109 /** 110 * Return the time value as a number of microseconds. 111 * 112 * Returns: Time in microseconds. 113 */ 114 long asMicroseconds() const 115 { 116 return m_microseconds; 117 } 118 119 /** 120 * Return the time value as a Duration. 121 */ 122 Duration asDuration() const 123 { 124 return usecs(m_microseconds); 125 } 126 127 128 /** 129 * Predefined "zero" time value. 130 */ 131 static immutable(Time) Zero; 132 133 bool opEquals(const ref Time rhs) const 134 { 135 return m_microseconds == rhs.m_microseconds; 136 } 137 138 int opCmp(const ref Time rhs) const 139 { 140 if(opEquals(rhs)) 141 { 142 return 0; 143 } 144 else if(m_microseconds < rhs.m_microseconds) 145 { 146 return -1; 147 } 148 else 149 { 150 return 1; 151 } 152 153 154 } 155 156 /** 157 * Overload of unary - operator to negate a time value. 158 */ 159 Time opUnary(string s)() const 160 if (s == "-") 161 { 162 return microseconds(-m_microseconds); 163 } 164 165 166 /** 167 * Overload of binary + and - operators toadd or subtract two time values. 168 */ 169 Time opBinary(string op)(Time rhs) const 170 if((op == "+") || (op == "-")) 171 { 172 static if (op == "+") 173 { 174 return microseconds(m_microseconds + rhs.m_microseconds); 175 } 176 static if(op == "-") 177 { 178 return microseconds(m_microseconds - rhs.m_microseconds); 179 } 180 } 181 182 /** 183 * Overload of += and -= assignment operators. 184 */ 185 ref Time opOpAssign(string op)(Time rhs) 186 if((op == "+") || (op == "-")) 187 { 188 static if(op == "+") 189 { 190 m_microseconds += rhs.m_microseconds; 191 return this; 192 } 193 static if(op == "-") 194 { 195 m_microseconds -= rhs.m_microseconds; 196 return this; 197 } 198 } 199 200 201 /** 202 * Overload of binary * and / operators to scale a time value. 203 */ 204 Time opBinary (string op, E)(E num) const 205 if(isNumeric!(E) && ((op == "*") || (op == "/"))) 206 { 207 static if (op == "*") 208 { 209 return microseconds(m_microseconds * num); 210 } 211 static if(op == "/") 212 { 213 return microseconds(m_microseconds / num); 214 } 215 } 216 217 /** 218 * Overload of *= and /= assignment operators. 219 */ 220 ref Time opOpAssign(string op,E)(E num) 221 if(isNumeric!(E) && ((op == "*") || (op == "/"))) 222 { 223 static if(op == "*") 224 { 225 m_microseconds *= num; 226 return this; 227 } 228 static if(op == "/") 229 { 230 m_microseconds /= num; 231 return this; 232 } 233 } 234 235 } 236 /** 237 * Construct a time value from a number of seconds. 238 * 239 * Params: 240 * amount = Number of seconds. 241 * 242 * Returns: Time value constructed from the amount of microseconds. 243 */ 244 Time seconds(float amount) 245 { 246 return Time(cast(long)(amount * 1000000)); 247 } 248 /** 249 *Construct a time value from a number of milliseconds. 250 * 251 * Params: 252 * amount = Number of milliseconds. 253 * 254 * Returns: Time value constructed from the amount of microseconds. 255 */ 256 Time milliseconds(int amount) 257 { 258 return Time(amount*1000); 259 } 260 261 /** 262 * Construct a time value from a number of microseconds. 263 * 264 * Params: 265 * amount = Number of microseconds. 266 * 267 * Returns: Time value constructed from the amount of microseconds. 268 */ 269 Time microseconds(long amount) 270 { 271 return Time(amount); 272 } 273 274 /** 275 * Construct a time value from a Duration. 276 * 277 * Params: 278 * dur = The time duration. 279 * 280 * Returns: Time value constructed from the time duration. 281 */ 282 Time duration(Duration dur) 283 { 284 return Time(dur.total!"usecs"()); 285 } 286 287 unittest 288 { 289 version(DSFML_Unittest_System) 290 { 291 292 import std.stdio; 293 294 writeln("Unit test for Time Struct"); 295 296 auto time = seconds(1); 297 298 assert(time.asSeconds() == 1); 299 300 assert((time*2).asSeconds() == 2); 301 302 assert((time/2).asSeconds() == .5f); 303 304 assert((time+seconds(1)).asSeconds() == 2); 305 306 assert((time-seconds(1)).asSeconds() == 0); 307 308 time += seconds(1); 309 310 assert(time.asSeconds() == 2); 311 312 time -= seconds(1); 313 314 assert(time.asSeconds() == 1); 315 316 time/=2; 317 318 assert(time.asSeconds() == .5f); 319 320 time*=2; 321 322 assert(time.asSeconds() == 1); 323 324 writeln("Time Struct passes all tests."); 325 writeln(); 326 } 327 }