1 module polyplex.core.time;
2 import std.format;
3 import polyplex.utils.strutils;
4 
5 /**
6 	An ingame timespan
7 */
8 class GameTimeSpan {
9 private:
10 	double ticks;
11 
12 public:
13 	/**
14 		Gets the base value (a tick)
15 	*/
16 	@property double BaseValue() {
17 		return ticks;
18 	}
19 
20 	/**
21 		Sets the base value (a tick)
22 	*/
23 	@property void BaseValue(double ticks) {
24 		this.ticks = ticks;
25 	}
26 
27 	/**
28 		Gets the amount of milliseconds as a long
29 	*/
30 	@property ulong LMilliseconds() {
31 		return cast(ulong)Milliseconds;
32 	}
33 
34 	/**
35 		Gets the amount of seconds as a long
36 	*/
37 	@property ulong LSeconds() {
38 		return cast(ulong)Seconds;
39 	}
40 
41 	/**
42 		Gets the amount of minutes as a long
43 	*/
44 	@property ulong LMinutes() {
45 		return cast(ulong)Minutes;
46 	}
47 
48 	/**
49 		Gets the amount of hours as a long
50 	*/
51 	@property ulong LHours() {
52 		return cast(ulong)Hours;
53 	}
54 
55 	/**
56 		Gets the amount of milliseconds as a double
57 	*/
58 	@property double Milliseconds() {
59 		return ticks;
60 	}
61 
62 	/**
63 		Gets the amount of milliseconds as a double
64 	*/
65 	@property double Seconds() {
66 		return ticks / 1000;
67 	}
68 
69 	/**
70 		Gets the amount of milliseconds as a double
71 	*/
72 	@property double Minutes() {
73 		return Seconds / 60;
74 	}
75 
76 	/**
77 		Gets the amount of milliseconds as a double
78 	*/
79 	@property double Hours() {
80 		return Minutes / 60;
81 	}
82 
83 	/**
84 		Constructs a new game timespan instance
85 	*/
86 	this(ulong ticks) {
87 		this.ticks = ticks;
88 	}
89 
90 	static {
91 
92 		/**
93 			Create a new time span from specified seconds
94 		*/
95 		GameTimeSpan FromSeconds(ulong seconds) {
96 			return new GameTimeSpan(seconds * 1000);
97 		}
98 
99 		/**
100 			Create a new time span from specified minutes
101 		*/
102 		GameTimeSpan FromMinutes(ulong minutes) {
103 			return FromSeconds(minutes * 60);
104 		}
105 		
106 		/**
107 			Create a new time span from specified hours
108 		*/
109 		GameTimeSpan FromHours(ulong hours) {
110 			return FromMinutes(hours * 60);
111 		}
112 	}
113 
114 	/// Binary op
115 	GameTimeSpan opBinary(string op)(GameTimeSpan other) {
116 		return new GameTime(mixin(q{this.ticks %s other.ticks}.format(op)));
117 	}
118 
119 	/**
120 		Calculates the ratio of this timespan compared to the other timespan
121 	*/
122 	float RatioOf(GameTimeSpan other) {
123 		return cast(float) this.ticks / cast(float) other.ticks;
124 	}
125 
126 	/**
127 		Returns a human-friendly timespan string
128 	*/
129 	override
130 	string toString() {
131 		return "%d:%d:%d:%d".format(LHours, LMinutes % 60, LSeconds % 60, LMilliseconds % 60);
132 	}
133 
134 	/**
135 		Format time using the polyplex formatter
136 	*/
137 	deprecated
138 	string FormatTime(string formatstring) {
139 		return Format(formatstring, LHours, LMinutes % 60, LSeconds % 60, LMilliseconds % 60);
140 	}
141 }
142 
143 /**
144 	A container for game time
145 */
146 class GameTime {
147 public:
148 	/**
149 		Creates a new gametime instance
150 	*/
151 	this(GameTimeSpan total, GameTimeSpan delta) {
152 		TotalTime = total;
153 		DeltaTime = delta;
154 	}
155 
156 	/**
157 		The total time the game has been running
158 	*/
159 	GameTimeSpan TotalTime;
160 
161 	/**
162 		The time between this and the last frame
163 	*/
164 	GameTimeSpan DeltaTime;
165 
166 package(polyplex.core):
167 
168 	/*
169 		Internal tools to update the delta and total time a bit more cleanly
170 	*/
171 
172 	void updateDelta(double delta) {
173 		DeltaTime.BaseValue = delta;
174 	}
175 
176 	void updateTotal(double total) {
177 		TotalTime.BaseValue = total;
178 	}
179 }