1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2011-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 
17 #include "C4Include.h"
18 #include "platform/C4TimeMilliseconds.h"
19 #include <limits>
20 
21 #ifdef _WIN32
22 
23 #include "platform/C4windowswrapper.h"
24 #include <mmsystem.h>
25 
Now()26 C4TimeMilliseconds C4TimeMilliseconds::Now()
27 {
28 	return C4TimeMilliseconds(timeGetTime());
29 }
30 
31 #else
32 
33 #ifdef __APPLE__
34 #include <sys/time.h>
35 #else
36 #include <time.h>
37 #endif
38 
Now()39 C4TimeMilliseconds C4TimeMilliseconds::Now()
40 {
41 #ifdef __APPLE__
42 	static time_t sec_offset;
43 	timeval tv;
44 	gettimeofday(&tv, 0);
45 	if (!sec_offset) sec_offset = tv.tv_sec;
46 	return C4TimeMilliseconds((tv.tv_sec - sec_offset) * 1000 + tv.tv_usec / 1000);
47 #else
48 	timespec tv;
49 	clock_gettime(CLOCK_MONOTONIC, &tv);
50 	static time_t sec_offset = tv.tv_sec;
51 	return C4TimeMilliseconds((tv.tv_sec - sec_offset) * 1000 + tv.tv_nsec / 1000000);
52 #endif
53 }
54 
55 #endif
56 
AsString() const57 StdCopyStrBuf C4TimeMilliseconds::AsString() const
58 {
59 	if (inf == PositiveInfinity)
60 	{
61 		return StdCopyStrBuf("POSITIVE INFINITY");
62 	}
63 	if (inf == NegativeInfinity)
64 	{
65 		return StdCopyStrBuf("NEGATIVE INFINITY");
66 	}
67 	StdCopyStrBuf string;
68 	string.Format("%u:%02u:%02u:%03u:",time / 1000 / 60 / 60, (time / 1000 / 60) % 60, (time / 1000) % 60, time % 1000);
69 	return StdCopyStrBuf(string);
70 }
71 
72 C4TimeMilliseconds& C4TimeMilliseconds::operator=(const C4TimeMilliseconds& rhs) = default;
73 
operator ==(const C4TimeMilliseconds & lhs,const C4TimeMilliseconds & rhs)74 bool operator==( const C4TimeMilliseconds& lhs, const C4TimeMilliseconds& rhs )
75 {
76 	return lhs.inf == rhs.inf &&
77 	       lhs.time == rhs.time;
78 }
79 
operator <(const C4TimeMilliseconds & lhs,const C4TimeMilliseconds & rhs)80 bool operator<( const C4TimeMilliseconds& lhs, const C4TimeMilliseconds& rhs )
81 {
82 	if (lhs.inf != C4TimeMilliseconds::NoInfinity ||
83 	    rhs.inf != C4TimeMilliseconds::NoInfinity)
84 	{
85 		return lhs.inf < rhs.inf;
86 	}
87 	return lhs.time < rhs.time;
88 }
89 
operator -(const C4TimeMilliseconds & lhs,const C4TimeMilliseconds & rhs)90 int32_t operator-(const C4TimeMilliseconds& lhs, const C4TimeMilliseconds& rhs)
91 {
92 	// if infinity is set, nothing else than infinity matters (infinity + 100 == infinity)
93 	if (lhs.inf != C4TimeMilliseconds::NoInfinity ||
94 	    rhs.inf != C4TimeMilliseconds::NoInfinity)
95 	{
96 		int infinityTo = lhs.inf - rhs.inf;
97 
98 		if (infinityTo < 0) return std::numeric_limits<int32_t>::min();
99 		if (infinityTo > 0) return std::numeric_limits<int32_t>::max();
100 		return 0;
101 	}
102 	// otherwise, as usual
103 	return int32_t(lhs.time - rhs.time);
104 }
105