1 /** 
2  * Copyright: Enalye
3  * License: Zlib
4  * Authors: Enalye
5  */
6 module grimoire.stdlib.time;
7 
8 import std.datetime;
9 import std.conv : to;
10 import grimoire.assembly, grimoire.compiler, grimoire.runtime;
11 
12 package(grimoire.stdlib) void grLoadStdLibTime(GrLibrary library) {
13 	library.addPrimitive(&_clock, "clock", [], [grInt]);
14 
15 	library.addPrimitive(&_wait, "wait", [grInt]);
16 	library.addPrimitive(&_sleep, "sleep", [grInt]);
17 
18 	library.addPrimitive(&_seconds_i, "seconds", [grInt], [grInt]);
19 	library.addPrimitive(&_seconds_f, "seconds", [grFloat], [grInt]);
20 
21 	library.addPrimitive(&_minutes_i, "minutes", [grInt], [grInt]);
22 	library.addPrimitive(&_minutes_f, "minutes", [grFloat], [grInt]);
23 
24 	library.addPrimitive(&_hours_i, "hours", [grInt], [grInt]);
25 	library.addPrimitive(&_hours_f, "hours", [grFloat], [grInt]);
26 }
27 
28 private void _clock(GrCall call) {
29 	call.setInt(cast(GrInt)(Clock.currStdTime / 10_000));
30 }
31 
32 private void _wait(GrCall call) {
33 	final class WaitBlocker : GrBlocker {
34 		private {
35 			GrInt _count;
36 		}
37 
38 		this(GrInt count) {
39 			_count = count < 0 ? 0 : count;
40 		}
41 
42 		override bool run() {
43 			if (_count <= 1)
44 				return true;
45 			_count--;
46 			return false;
47 		}
48 	}
49 
50 	call.block(new WaitBlocker(call.getInt(0)));
51 }
52 
53 private void _sleep(GrCall call) {
54 	final class SleepBlocker : GrBlocker {
55 		private {
56 			GrInt _milliseconds;
57 			MonoTime _startTime;
58 		}
59 
60 		this(GrInt milliseconds) {
61 			_milliseconds = milliseconds < 0 ? 0 : milliseconds;
62 			_startTime = MonoTime.currTime();
63 		}
64 
65 		override bool run() {
66 			return (MonoTime.currTime() - _startTime).total!"msecs" > _milliseconds;
67 		}
68 	}
69 
70 	call.block(new SleepBlocker(call.getInt(0)));
71 }
72 
73 private void _seconds_i(GrCall call) {
74 	call.setInt(call.getInt(0) * 1_000);
75 }
76 
77 private void _seconds_f(GrCall call) {
78 	call.setInt(cast(GrInt)(call.getFloat(0) * 1_000f));
79 }
80 
81 private void _minutes_i(GrCall call) {
82 	call.setInt(call.getInt(0) * 60_000);
83 }
84 
85 private void _minutes_f(GrCall call) {
86 	call.setInt(cast(GrInt)(call.getFloat(0) * 60_000f));
87 }
88 
89 private void _hours_i(GrCall call) {
90 	call.setInt(call.getInt(0) * 3_600_000);
91 }
92 
93 private void _hours_f(GrCall call) {
94 	call.setInt(cast(GrInt)(call.getFloat(0) * 3_600_000f));
95 }