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 }