nanovega: DiD fix
[iv.d.git] / timer.d
blob18773cdb10920c39f0744dde1b73c73bf3fa174f
1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 // this essentially duplicates std.datetime.StopWatch, but meh...
19 module iv.timer;
21 import iv.pxclock;
24 struct Timer {
25 private:
26 ulong mSTimeMicro;
27 ulong mAccumMicro;
28 State mState = State.Stopped;
30 public:
31 enum State {
32 Stopped,
33 Running,
34 Paused,
37 public:
38 string toString () const @trusted {
39 char[128] buf = void;
40 auto t = toBuffer(buf[]);
41 return t.idup;
44 nothrow @trusted @nogc:
45 this (State initState) @trusted {
46 if (initState == State.Running) start();
49 this (bool startit) @trusted {
50 if (startit) start();
53 @property const pure {
54 auto state () { pragma(inline, true); return mState; }
55 bool stopped () { pragma(inline, true); return (mState == State.Stopped); }
56 bool running () { pragma(inline, true); return (mState == State.Running); }
57 bool paused () { pragma(inline, true); return (mState == State.Paused); }
60 @property ulong micro () const {
61 final switch (mState) {
62 case State.Stopped: case State.Paused: return mAccumMicro;
63 case State.Running: return mAccumMicro+(clockMicro-mSTimeMicro);
67 @property ulong milli () const { pragma(inline, true); return micro/1000; }
69 void reset () {
70 mAccumMicro = 0;
71 mSTimeMicro = clockMicro;
74 void restart () {
75 mAccumMicro = 0;
76 mState = State.Running;
77 mSTimeMicro = clockMicro;
80 void start () {
81 mAccumMicro = 0;
82 mState = State.Running;
83 mSTimeMicro = clockMicro;
86 void stop () {
87 if (mState == State.Running) {
88 mAccumMicro += clockMicro-mSTimeMicro;
89 mState = State.Stopped;
93 void pause () {
94 if (mState == State.Running) {
95 mAccumMicro += clockMicro-mSTimeMicro;
96 mState = State.Paused;
100 void resume () {
101 if (mState == State.Paused) {
102 mState = State.Running;
103 mSTimeMicro = clockMicro;
104 } else if (mState == State.Stopped) {
105 start();
109 // 128 chars should be enough for everyone
110 char[] toBuffer (char[] dest) const nothrow @trusted @nogc {
111 import core.stdc.stdio : snprintf;
112 char[128] buf = void;
113 ulong d;
114 final switch (mState) {
115 case State.Stopped: case State.Paused: d = mAccumMicro; break;
116 case State.Running: d = mAccumMicro+(clockMicro-mSTimeMicro); break;
118 immutable uint micro = cast(uint)(d%1000);
119 d /= 1000;
120 immutable uint milli = cast(uint)(d%1000);
121 d /= 1000;
122 immutable uint seconds = cast(uint)(d%60);
123 d /= 60;
124 immutable uint minutes = cast(uint)(d%60);
125 d /= 60;
126 immutable uint hours = cast(uint)d;
127 uint len;
128 if (hours) len = cast(uint)snprintf(buf.ptr, buf.length, "%u:%02u:%02u.%03u", hours, minutes, seconds, milli);
129 else if (minutes) len = cast(uint)snprintf(buf.ptr, buf.length, "%u:%02u.%03u", minutes, seconds, milli);
130 else if (seconds) len = cast(uint)snprintf(buf.ptr, buf.length, "%u.%03u", seconds, milli);
131 else if (micro != 0) len = cast(uint)snprintf(buf.ptr, buf.length, "%ums:%umcs", milli, micro);
132 else len = cast(uint)snprintf(buf.ptr, buf.length, "%ums", milli);
133 if (len > dest.length) len = dest.length;
134 dest.ptr[0..len] = buf.ptr[0..len];
135 return dest.ptr[0..len];