Edit comment text.
[synfig.git] / ETL / trunk / ETL / _clock_base.h
1 /*! ========================================================================
2 ** Extended Template and Library
3 ** Clock Abstraction Implementation
4 ** $Id$
5 **
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
7 **
8 ** This package is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU General Public License as
10 ** published by the Free Software Foundation; either version 2 of
11 ** the License, or (at your option) any later version.
12 **
13 ** This package is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ** General Public License for more details.
17 **
18 ** === N O T E S ===========================================================
19 **
20 ** This is an internal header file, included by other ETL headers.
21 ** You should not attempt to use it directly.
22 **
23 ** ========================================================================= */
24
25 /* === S T A R T =========================================================== */
26
27 #ifndef __ETL__CLOCK_H
28 #define __ETL__CLOCK_H
29
30 /* === H E A D E R S ======================================================= */
31
32 #ifndef WIN32
33 #include <unistd.h>
34 #else
35 inline void sleep(int i) { Sleep(i*1000); }
36 #endif
37
38 /* === M A C R O S ========================================================= */
39
40 /* === T Y P E D E F S ===================================================== */
41
42 /* === C L A S S E S & S T R U C T S ======================================= */
43
44 _ETL_BEGIN_NAMESPACE
45
46 inline void yield() { sleep(0); }
47
48 /*! ========================================================================
49 ** \class       clock_base
50 ** \brief       clock abstraction
51 **
52 ** A more detailed description needs to be written.
53 */
54 template <class DESC>
55 class clock_base : public DESC
56 {
57 public:
58         typedef typename DESC::value_type value_type;
59
60 private:
61         typedef clock_base<DESC> _clock;
62         typedef typename DESC::timestamp timestamp;
63
64         timestamp base_time;
65
66         using DESC::get_current_time;
67         using DESC::realtime;
68         using DESC::one_second;
69 public:
70
71         clock_base() { reset(); }
72
73         void reset()
74         { get_current_time(base_time); }
75
76         value_type operator()()const
77         { return timestamp_to_seconds(get_current_time()-base_time); }
78
79         value_type pop_time()
80         {
81                 // Grab the old base time
82                 timestamp old_time=base_time;
83
84                 // Put the current time into base_time
85                 get_current_time(base_time);
86
87                 return timestamp_to_seconds(base_time-old_time);
88         }
89
90         static void
91         sleep(const value_type &length)
92         {
93                 if(!realtime())
94                         ::sleep((int)(length+0.5));
95                 else
96                 {
97                         _clock timer;
98                         timer.reset();
99                         value_type val;
100                         for(val=timer();one_second()<length-val;val=timer())
101                                 ::sleep((int)((length-val)/2.0+0.4));
102                         while(timer()<length)
103                           ;
104                 }
105
106
107                 /* This is a different waiting mechanism that uses
108                 ** the native timestamp type of the clock rather
109                 ** than converting it to a double (or whatever).
110                 ** You would think that this would be at least a
111                 ** few microseconds faster, but a few tests on my
112                 ** PowerBook G4 have proved otherwise. Indeed I loose
113                 ** several microseconds using this "optimized" method.
114                 ** Bizarre.
115                 **      - darco (8-17-2002)
116                 {
117                         timestamp endtime=get_current_time()+seconds_to_timestamp(length);
118                         timestamp loopendtime=get_current_time()+seconds_to_timestamp(length-1.0);
119                         while(get_current_time()<loopendtime)
120                                 ::sleep((int)timestamp_to_seconds(loopendtime-get_current_time())/2.0);
121                         while(get_current_time()<endtime);
122                 }
123                 */
124
125                 return;
126         }
127 };
128
129 _ETL_END_NAMESPACE
130
131 /* === E N D =============================================================== */
132
133 #endif