wow. that was easy: git mv core nucleus
[feisty_meow.git] / nucleus / library / timely / stopwatch.cpp
diff --git a/nucleus/library/timely/stopwatch.cpp b/nucleus/library/timely/stopwatch.cpp
new file mode 100644 (file)
index 0000000..d5661cb
--- /dev/null
@@ -0,0 +1,103 @@
+/***********************
+*                                                                             *
+*  Name   : stopwatch
+*  Author : Chris Koeritz
+*                                                                             *
+*******************************************************************************
+* Copyright (c) 1991-$now By Author.  This program is free software; you can  *
+* redistribute it and/or modify it under the terms of the GNU General Public  *
+* License as published by the Free Software Foundation; either version 2 of   *
+* the License or (at your option) any later version.  This is online at:      *
+*     http://www.fsf.org/copyleft/gpl.html                                    *
+* Please send any updates to: fred@gruntose.com                               *
+\*****************************************************************************/
+
+#include "time_stamp.h"
+#include "stopwatch.h"
+
+#include <basis/definitions.h>
+#include <basis/functions.h>
+#include <basis/guards.h>
+
+using namespace basis;
+
+namespace timely {
+
+stopwatch::stopwatch()
+: _status(UNSTARTED),
+  _start_time(new time_stamp()),
+  _stop_time(new time_stamp()),
+  _total_so_far(0)
+{}
+
+stopwatch::stopwatch(const stopwatch &to_copy)
+: _status(UNSTARTED),
+  _start_time(new time_stamp()),
+  _stop_time(new time_stamp()),
+  _total_so_far(0)
+{ *this = to_copy; }
+
+stopwatch::~stopwatch()
+{
+  _status = UNSTARTED;
+  WHACK(_start_time);
+  WHACK(_stop_time);
+}
+
+stopwatch &stopwatch::operator =(const stopwatch &to_copy)
+{
+  if (this == &to_copy) return *this;
+  *_start_time = *to_copy._start_time;
+  *_stop_time = *to_copy._stop_time;
+  _status = to_copy._status;
+  _total_so_far = to_copy._total_so_far;
+  return *this;
+}
+
+void stopwatch::reset() { _status = UNSTARTED; _total_so_far = 0; }
+
+int stopwatch::milliseconds() { return common_measure(); }
+
+void stopwatch::start()
+{
+  if (_status == RUNNING) return;
+  *_start_time = time_stamp();
+  _status = RUNNING;
+}
+
+int stopwatch::compute_diff(const time_stamp &t1, const time_stamp &t2)
+{ return int(t2.value() - t1.value()); }
+
+void stopwatch::halt()
+{
+  if (_status == STOPPED) return;
+  else if (_status == UNSTARTED) return;
+
+  *_stop_time = time_stamp();
+  _total_so_far += compute_diff(*_start_time, *_stop_time);
+
+  _status = STOPPED;
+}
+
+int stopwatch::common_measure()
+{
+  bool restart = false;
+  int to_return = 0;
+  switch (_status) {
+    case UNSTARTED: break;
+    case RUNNING:
+      // stop stopwatch, restart afterwards.
+      halt();
+      restart = true;
+      // intentional fall through to default.
+    default:
+      // set the return value to the accumulated time.
+      to_return = _total_so_far;
+      break;
+  }
+  if (restart) start();  // crank the stopwatch back up if we were supposed to.
+  return to_return;
+}
+
+} //namespace.
+