diff options
Diffstat (limited to 'util/fbcompose/TickTracker.cc')
-rw-r--r-- | util/fbcompose/TickTracker.cc | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/util/fbcompose/TickTracker.cc b/util/fbcompose/TickTracker.cc new file mode 100644 index 0000000..ef0f649 --- /dev/null +++ b/util/fbcompose/TickTracker.cc | |||
@@ -0,0 +1,156 @@ | |||
1 | /** TickTracker.cc file for the fluxbox compositor. */ | ||
2 | |||
3 | // Copyright (c) 2011 Gediminas Liktaras (gliktaras at gmail dot com) | ||
4 | // | ||
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | // of this software and associated documentation files (the "Software"), to deal | ||
7 | // in the Software without restriction, including without limitation the rights | ||
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | // copies of the Software, and to permit persons to whom the Software is | ||
10 | // furnished to do so, subject to the following conditions: | ||
11 | // | ||
12 | // The above copyright notice and this permission notice shall be included in | ||
13 | // all copies or substantial portions of the Software. | ||
14 | // | ||
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
21 | // THE SOFTWARE. | ||
22 | |||
23 | |||
24 | #include "TickTracker.hh" | ||
25 | |||
26 | #include "Logging.hh" | ||
27 | |||
28 | using namespace FbCompositor; | ||
29 | |||
30 | |||
31 | //--- CONSTANTS ---------------------------------------------------------------- | ||
32 | |||
33 | // The accuracy of the timer (1.0 = 1 second). | ||
34 | const double EPSILON = 1e-6; | ||
35 | |||
36 | |||
37 | //--- CONSTRUCTORS AND DESTRUCTORS --------------------------------------------- | ||
38 | |||
39 | // Constructor. | ||
40 | TickTracker::TickTracker() { | ||
41 | m_is_running = false; | ||
42 | m_tick_size = 1000000; | ||
43 | m_ticks_per_second = 1.0; | ||
44 | } | ||
45 | |||
46 | // Copy constructor. | ||
47 | TickTracker::TickTracker(const TickTracker &other) : | ||
48 | m_is_running(other.m_is_running), | ||
49 | m_startTime(other.m_startTime), | ||
50 | m_tick_size(other.m_tick_size), | ||
51 | m_ticks_per_second(other.m_ticks_per_second), | ||
52 | m_observed_ticks(other.m_observed_ticks) { | ||
53 | } | ||
54 | |||
55 | // Assignment operator. | ||
56 | TickTracker &TickTracker::operator=(const TickTracker &other) { | ||
57 | if (this != &other) { | ||
58 | m_is_running = other.m_is_running; | ||
59 | m_startTime = other.m_startTime; | ||
60 | m_tick_size = other.m_tick_size; | ||
61 | m_ticks_per_second = other.m_ticks_per_second; | ||
62 | m_observed_ticks = other.m_observed_ticks; | ||
63 | } | ||
64 | return *this; | ||
65 | } | ||
66 | |||
67 | // Destructor. | ||
68 | TickTracker::~TickTracker() { } | ||
69 | |||
70 | |||
71 | //--- TIMER MANIPULATION ------------------------------------------------------- | ||
72 | |||
73 | // Starts the timer. | ||
74 | void TickTracker::start() { | ||
75 | if (gettimeofday(&m_startTime, NULL)) { | ||
76 | throw TimeException("Cannot obtain the current time."); | ||
77 | } | ||
78 | m_observed_ticks = 0; | ||
79 | m_is_running = true; | ||
80 | } | ||
81 | |||
82 | /** Stops the timer. */ | ||
83 | void TickTracker::stop() { | ||
84 | m_is_running = false; | ||
85 | } | ||
86 | |||
87 | |||
88 | //--- TIMER QUERIES ------------------------------------------------------------ | ||
89 | |||
90 | // Returns the new number of elapsed ticks since last call of this function. | ||
91 | int TickTracker::newElapsedTicks() { | ||
92 | int total_ticks = totalElapsedTicks(); | ||
93 | int new_ticks = total_ticks - m_observed_ticks; | ||
94 | m_observed_ticks = total_ticks; | ||
95 | |||
96 | if (new_ticks < 0) { | ||
97 | return 0; | ||
98 | } else { | ||
99 | return new_ticks; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | // Returns the total number of elapsed ticks. | ||
104 | int TickTracker::totalElapsedTicks() { | ||
105 | static timeval now; | ||
106 | |||
107 | if (gettimeofday(&now, NULL)) { | ||
108 | throw TimeException("Cannot obtain the current time."); | ||
109 | } | ||
110 | |||
111 | return tickDifference(now, m_startTime); | ||
112 | } | ||
113 | |||
114 | |||
115 | // Sets the size of a tick. | ||
116 | void TickTracker::setTickSize(int usec) { | ||
117 | if (usec < 1) { | ||
118 | throw TimeException("Invalid tick size."); | ||
119 | } | ||
120 | |||
121 | m_tick_size = usec; | ||
122 | m_ticks_per_second = 1000000.0 / usec; | ||
123 | } | ||
124 | |||
125 | |||
126 | //--- INTERNAL FUNTIONS -------------------------------------------------------- | ||
127 | |||
128 | // Returns the difference in time between two timevals. | ||
129 | // Function adapted from http://www.gnu.org/s/libc/manual/html_node/Elapsed-Time.html. | ||
130 | timeval TickTracker::timeDifference(timeval t1, timeval t2) { | ||
131 | int n_sec; | ||
132 | |||
133 | if (t1.tv_usec < t2.tv_usec) { | ||
134 | n_sec = (t2.tv_usec - t1.tv_usec) / 1000000 + 1; | ||
135 | t2.tv_usec -= 1000000 * n_sec; | ||
136 | t2.tv_sec += n_sec; | ||
137 | } | ||
138 | if (t1.tv_usec - t2.tv_usec > 1000000) { | ||
139 | n_sec = (t1.tv_usec - t2.tv_usec) / 1000000; | ||
140 | t2.tv_usec += 1000000 * n_sec; | ||
141 | t2.tv_sec -= n_sec; | ||
142 | } | ||
143 | |||
144 | timeval diff; | ||
145 | diff.tv_sec = t1.tv_sec - t2.tv_sec; | ||
146 | diff.tv_usec = t1.tv_usec - t2.tv_usec; | ||
147 | return diff; | ||
148 | } | ||
149 | |||
150 | // Returns the difference between two timevals in ticks. | ||
151 | int TickTracker::tickDifference(const timeval &t1, const timeval &t2) { | ||
152 | timeval diff = timeDifference(t1, t2); | ||
153 | |||
154 | double raw_diff = diff.tv_sec * m_ticks_per_second + (double(diff.tv_usec) / m_tick_size); | ||
155 | return int(raw_diff + EPSILON); | ||
156 | } | ||