tracking down insane socket tester bugs on windoze, where the main culprit so far...
[feisty_meow.git] / nucleus / library / timely / time_stamp.h
1 #ifndef TIME_STAMP_CLASS
2 #define TIME_STAMP_CLASS
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : time_stamp                                                        *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
9 *******************************************************************************
10 * Copyright (c) 1995-$now By Author.  This program is free software; you can  *
11 * redistribute it and/or modify it under the terms of the GNU General Public  *
12 * License as published by the Free Software Foundation; either version 2 of   *
13 * the License or (at your option) any later version.  This is online at:      *
14 *     http://www.fsf.org/copyleft/gpl.html                                    *
15 * Please send any updates to: fred@gruntose.com                               *
16 \*****************************************************************************/
17
18 #include <basis/astring.h>
19 #include <basis/contracts.h>
20 #include <basis/definitions.h>
21
22 // forward.
23 class rollover_record;
24 struct timeval;
25
26 namespace timely {
27
28 //! Represents a point in time relative to the operating system startup time.
29 /*!
30   This duration is measured in milliseconds.  This class provides a handy way
31   of measuring relative durations at the millisecond time scale.
32   Unfortunately, operating systems that reckon their millisecond uptime in
33   32 bit integers will suffer from a rollover problem every 49 days or so,
34   but this class corrects this issue.
35 */
36
37 class time_stamp : public virtual basis::orderable
38 {
39 public:
40   DEFINE_CLASS_NAME("time_stamp");
41
42   typedef double time_representation;
43     //!< the representation of time for this universe, measured in milliseconds.
44
45   time_stamp();
46     //!< creates a time_stamp containing the current time.
47
48   time_stamp(time_representation offset);
49     //!< creates a stamp after the current time by "offset" milliseconds.
50     /*!< negative offsets are allowed, in which case the stamp will be
51     prior to the current time. */
52
53   static double rolling_uptime();
54     //!< give the OS uptime in a more durable form that handles rollovers.
55
56   void reset();
57     //!< sets the stamp time back to now.
58   void reset(time_representation offset);
59     //!< sets the stamp forward by "offset" similar to the second constructor.
60
61   time_representation value() const { return c_stamp; }
62     //!< returns the time_stamp in terms of the lower level type.
63
64   enum stamp_display_style { STAMP_RELATIVE, STAMP_ABSOLUTE };
65
66   basis::astring text_form(stamp_display_style style = STAMP_RELATIVE) const;
67     //!< returns a simple textual representation of the time_stamp.
68     /*!< if the "style" is ABSOLUTE, then the stamp is shown in H:M:S.ms
69     form based on the system uptime.  if the "style" is RELATIVE, then the
70     stamp is shown as an offset from now. */
71
72   static basis::astring notarize(bool add_space = true);
73     //!< a useful method for getting a textual version of the time "right now".
74     /*!< this was formerly known as a very useful method called 'utility::timestamp'.
75     that naming was fairly abusive to keep straight from the time_stamp class, so the
76     functionality has been absorbed. */
77
78   // standard operators: keep in mind that time is represented by an ever
79   // increasing number.  so, if a value A is less than a value B, that means
80   // that A is older than B, since it occurred at an earlier time.
81   virtual bool less_than(const basis::orderable &that) const {
82     const time_stamp *cast = dynamic_cast<const time_stamp *>(&that);
83     if (!cast) return false;
84     return c_stamp < cast->c_stamp;
85   }
86
87   virtual bool equal_to(const basis::equalizable &that) const {
88     const time_stamp *cast = dynamic_cast<const time_stamp *>(&that);
89     if (!cast) return false;
90     return c_stamp == cast->c_stamp;
91   }
92
93   // helper functions for using the OS's time support.
94
95   static void fill_timeval_ms(timeval &time_point, int milliseconds);
96     //!< returns a timeval system object that represents the "milliseconds".
97     /*!< if "milliseconds" is zero, then the returned timeval will
98     represent zero time passing (rather than infinite duration as some
99     functions assume). */
100
101 private:
102   time_representation c_stamp;  //!< the low-level time stamp is held here.
103
104   void fill_in_time();  //!< stuffs the current time into the held value.
105
106   static time_representation get_time_now();
107     //!< platform specific function that gets uptime.
108
109   static rollover_record &rollover_rover();
110 };
111
112 } //namespace.
113
114 #endif
115