Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * clock.cpp - A central clock 00004 * 00005 * Created: Sun Jun 03 00:23:59 2007 00006 * Copyright 2007 Daniel Beck 00007 * 2007-2008 Tim Niemueller [www.niemueller.de] 00008 * 00009 ****************************************************************************/ 00010 00011 /* This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. A runtime exception applies to 00015 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00016 * 00017 * This program is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU Library General Public License for more details. 00021 * 00022 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00023 */ 00024 00025 #include <utils/time/clock.h> 00026 #include <utils/time/timesource.h> 00027 #include <utils/logging/liblogger.h> 00028 00029 #include <cstdlib> 00030 00031 namespace fawkes { 00032 00033 /** @class Clock clock.h <utils/time/clock.h> 00034 * This is supposed to be the central clock in Fawkes. 00035 * It is implemented as a singleton to ensure that there is only 00036 * one object. So-called TimeSources can be registered at the Clock 00037 * their current time can be retrieved through the Clock. 00038 * @author Daniel Beck, Tim Niemueller 00039 */ 00040 00041 /** initialize static members */ 00042 Clock* Clock::_instance = NULL; 00043 bool Clock::destruct_ok = false; 00044 00045 /** Constructor. */ 00046 Clock::Clock() 00047 { 00048 destruct_ok = false; 00049 ext_timesource = 0; 00050 ext_default = false; 00051 } 00052 00053 00054 /** Destructor. 00055 * Generates a log message if Clock::finalize wasn't called beforehand 00056 */ 00057 Clock::~Clock() 00058 { 00059 if ( !destruct_ok ) { 00060 LibLogger::log_error("Clock", "dtor called without calling Clock::finalize() first"); 00061 } 00062 00063 delete ext_timesource; 00064 } 00065 00066 00067 /** Clock initializer. 00068 * This one is static and has to be called to instantiate a Clock object. 00069 * In further calls it just returns a pointer to the Clock object. 00070 * @return a pointer to the Clock object 00071 */ 00072 Clock * 00073 Clock::instance() 00074 { 00075 if ( NULL == _instance ) 00076 { 00077 _instance = new Clock(); 00078 } 00079 00080 return _instance; 00081 } 00082 00083 00084 /** Finalize. 00085 * Sets a boolean flag which prevents a log message from being generated in 00086 * the destructor. 00087 */ 00088 void 00089 Clock::finalize() 00090 { 00091 destruct_ok = true; 00092 delete _instance; 00093 _instance = NULL; 00094 } 00095 00096 00097 /** Register an external time source. 00098 * 00099 * @param ts a pointer to the external time source 00100 * @param make_default if true, this time source is made the default 00101 * timesource which means that for every call of get_time() the time 00102 * of the external time source is returned 00103 */ 00104 void 00105 Clock::register_ext_timesource(TimeSource* ts, bool make_default) 00106 { 00107 ext_timesource = ts; 00108 00109 if (make_default) { 00110 ext_default = true; 00111 } 00112 } 00113 00114 00115 /** Remove external time source. 00116 * If an external timesource is currently set it is removed. The time source 00117 * will not be deleted but only the reference to it is removed. 00118 * @param ts only remove time source if it equals ts, if NULL remove no matter what. 00119 */ 00120 void 00121 Clock::remove_ext_timesource(TimeSource *ts) 00122 { 00123 if ( (ts == NULL) || (ext_timesource == ts) ) { 00124 ext_timesource = NULL; 00125 ext_default = false; 00126 } else { 00127 throw Exception("Time sources do not match. Not removing."); 00128 } 00129 } 00130 00131 00132 /** Set/unset the external time source as the default time source. 00133 * @param ext_is_default true to make external time source the default, 00134 * false to disable it as the default. 00135 */ 00136 void 00137 Clock::set_ext_default_timesource(bool ext_is_default) 00138 { 00139 if ( ext_is_default ) { 00140 if (NULL != ext_timesource) { 00141 ext_default = true; 00142 } else { 00143 throw Exception("Trying to make the external timesource the default timesource but there is no external timesource"); 00144 } 00145 } else { 00146 ext_default = false; 00147 } 00148 } 00149 00150 00151 /** Checks whether the external time source is the default time soucre. 00152 * @return true if external time source is default time source 00153 */ 00154 bool 00155 Clock::is_ext_default_timesource() const 00156 { 00157 return ext_default; 00158 } 00159 00160 00161 /** Returns the time of the selected time source. 00162 * @param tv pointer to a timeval struct where the time is written to 00163 * @param sel allows to select the time source 00164 */ 00165 void 00166 Clock::get_time(struct timeval* tv, TimesourceSelector sel) const 00167 { 00168 if ( (DEFAULT == sel && !ext_default) || 00169 REALTIME == sel) 00170 { 00171 gettimeofday(tv, 0); 00172 } 00173 else if ( (EXTERNAL == sel) && 00174 (NULL == ext_timesource) ) 00175 { 00176 throw Exception("No external time source registered"); 00177 } 00178 else 00179 { 00180 ext_timesource->get_time(tv); 00181 } 00182 } 00183 00184 00185 /** Returns the time of the selected time source. 00186 * @param tv pointer to a timeval struct where the time is written to 00187 */ 00188 void 00189 Clock::get_time(struct timeval* tv) const 00190 { 00191 if ( ext_default ) { 00192 if ( NULL == ext_timesource ) { 00193 throw Exception("No external time source registered"); 00194 } 00195 ext_timesource->get_time(tv); 00196 } else { 00197 gettimeofday(tv, NULL); 00198 } 00199 } 00200 00201 00202 /** Returns the time of the selected time source. 00203 * @param time reference to a time where the result is stored 00204 */ 00205 void 00206 Clock::get_time(Time &time) const 00207 { 00208 get_time(&(time.__time)); 00209 } 00210 00211 00212 00213 00214 /** Returns the time of the selected time source. 00215 * @param time reference to a time where the result is stored 00216 * @param sel allows to select the time source 00217 */ 00218 void 00219 Clock::get_time(Time &time, TimesourceSelector sel) const 00220 { 00221 get_time(&(time.__time), sel); 00222 } 00223 00224 00225 /** Returns the time of the selected time source. 00226 * @param time pointer to a Time instance 00227 */ 00228 void 00229 Clock::get_time(Time *time) const 00230 { 00231 get_time(&(time->__time)); 00232 } 00233 00234 00235 00236 00237 /** Returns the time of the selected time source. 00238 * @param time pointer to a Time instance where the time is stored 00239 * @param sel allows to select the time source 00240 */ 00241 void 00242 Clock::get_time(Time *time, TimesourceSelector sel) const 00243 { 00244 get_time(&(time->__time), sel); 00245 } 00246 00247 00248 /** Returns the system time. 00249 * @param tv pointer to a timeval struct where the time is written to 00250 */ 00251 void 00252 Clock::get_systime(struct timeval* tv) const 00253 { 00254 gettimeofday(tv, 0); 00255 } 00256 00257 00258 /** Returns the time of the selected time source. 00259 * @param time reference to Time instance where the time is stored 00260 */ 00261 void 00262 Clock::get_systime(Time &time) const 00263 { 00264 gettimeofday(&(time.__time), 0); 00265 } 00266 00267 00268 /** Returns the time of the selected time source. 00269 * @param time pointer to Time instance where the time is stored 00270 */ 00271 void 00272 Clock::get_systime(Time *time) const 00273 { 00274 gettimeofday(&(time->__time), 0); 00275 } 00276 00277 00278 /** Get the current time. 00279 * @return current time 00280 */ 00281 Time 00282 Clock::now() const 00283 { 00284 Time t(_instance); 00285 return t.stamp(); 00286 } 00287 00288 00289 /** How much time has elapsed since t? 00290 * Calculated as "now - t" in seconds. 00291 * @param t time 00292 * @return elapsed seconds 00293 */ 00294 float 00295 Clock::elapsed(Time *t) const 00296 { 00297 Time nowt(_instance); 00298 return nowt - t; 00299 } 00300 00301 00302 /** How much system time has elapsed since t? 00303 * Use only for system time criteria like timeouts. 00304 * @param t time 00305 * @return elapsed system seconds 00306 */ 00307 float 00308 Clock::sys_elapsed(Time *t) const 00309 { 00310 struct timeval nowt; 00311 gettimeofday(&nowt, NULL); 00312 return time_diff_sec(nowt, t->__time); 00313 } 00314 00315 00316 /** Convert a time given w.r.t. the external time source into the system time. 00317 * @param t the time that is converted to the system time 00318 * @return the time in system time 00319 */ 00320 Time 00321 Clock::ext_to_realtime(const Time& t) 00322 { 00323 timeval tv; 00324 Time ret; 00325 00326 if (NULL != ext_timesource) 00327 { 00328 tv = ext_timesource->conv_to_realtime(t.get_timeval()); 00329 ret.set_time(&tv); 00330 } 00331 else 00332 { 00333 ret = t; 00334 } 00335 00336 return ret; 00337 } 00338 00339 00340 /** Check whether an external time source is registered. 00341 * @return true if an external time source is registered 00342 */ 00343 bool 00344 Clock::has_ext_timesource() const 00345 { 00346 if (0 != ext_timesource) { 00347 return true; 00348 } else { 00349 return false; 00350 } 00351 } 00352 00353 } // end namespace fawkes