Fawkes API  Fawkes Development Version
clock.cpp
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 <core/exception.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 
00044 /** Constructor. */
00045 Clock::Clock()
00046 {
00047   ext_timesource = 0;
00048   ext_default = false;
00049 }
00050 
00051 
00052 /** Destructor. */
00053 Clock::~Clock()
00054 {
00055   delete ext_timesource;
00056 }
00057 
00058 
00059 /** Clock initializer.
00060  * This one is static and has to be called to instantiate a Clock object.
00061  * In further calls it just returns a pointer to the Clock object.
00062  * @return a pointer to the Clock object
00063  */
00064 Clock *
00065 Clock::instance()
00066 {
00067   if (NULL == _instance) {
00068     _instance = new Clock();
00069   }
00070   
00071   return _instance;
00072 }
00073 
00074 
00075 /** Finalize. */
00076 void
00077 Clock::finalize()
00078 {
00079   delete _instance;
00080   _instance = NULL;
00081 }
00082 
00083 
00084 /** Register an external time source.
00085  * 
00086  * @param ts a pointer to the external time source
00087  * @param make_default if true, this time source is made the default
00088  * timesource which means that for every call of get_time() the time
00089  * of the external time source is returned
00090  */
00091 void
00092 Clock::register_ext_timesource(TimeSource* ts, bool make_default)
00093 {
00094   ext_timesource = ts;
00095 
00096   if (make_default) {
00097     ext_default = true;
00098   }
00099 }
00100 
00101 
00102 /** Remove external time source.
00103  * If an external timesource is currently set it is removed. The time source
00104  * will not be deleted but only the reference to it is removed.
00105  * @param ts only remove time source if it equals ts, if NULL remove no matter what.
00106  */
00107 void
00108 Clock::remove_ext_timesource(TimeSource *ts)
00109 {
00110   if ( (ts == NULL) || (ext_timesource == ts) ) {
00111     ext_timesource = NULL;
00112     ext_default = false;
00113   } else {
00114     throw Exception("Time sources do not match. Not removing.");
00115   }
00116 }
00117 
00118 
00119 /** Set/unset the external time source as the default time source.
00120  * @param ext_is_default true to make external time source the default,
00121  * false to disable it as the default.
00122  */
00123 void
00124 Clock::set_ext_default_timesource(bool ext_is_default)
00125 {
00126   if ( ext_is_default ) {
00127     if (NULL != ext_timesource) {
00128       ext_default = true;
00129     } else {
00130       throw Exception("Trying to make the external timesource the default timesource but there is no external timesource");
00131     }
00132   } else {
00133     ext_default = false;
00134   }
00135 }
00136 
00137 
00138 /** Checks whether the external time source is the default time soucre.
00139  * @return true if external time source is default time source
00140  */
00141 bool
00142 Clock::is_ext_default_timesource() const
00143 {
00144   return ext_default;
00145 }
00146 
00147 
00148 /** Returns the time of the selected time source.
00149  * @param tv pointer to a timeval struct where the time is written to
00150  * @param sel allows to select the time source
00151  */
00152 void
00153 Clock::get_time(struct timeval* tv, TimesourceSelector sel) const
00154 {
00155   if ( (DEFAULT == sel && !ext_default) ||
00156        REALTIME == sel)
00157     {
00158       gettimeofday(tv, 0);
00159     }
00160   else if ( (EXTERNAL == sel) && 
00161             (NULL == ext_timesource) )
00162     {
00163       throw Exception("No external time source registered");
00164     }
00165   else
00166     {
00167       ext_timesource->get_time(tv);
00168     }
00169 }
00170 
00171 
00172 /** Returns the time of the selected time source.
00173  * @param tv pointer to a timeval struct where the time is written to
00174  */
00175 void
00176 Clock::get_time(struct timeval* tv) const
00177 {
00178   if ( ext_default ) {
00179     if ( NULL == ext_timesource ) {
00180       throw Exception("No external time source registered");
00181     }
00182     ext_timesource->get_time(tv);
00183   } else {
00184     gettimeofday(tv, NULL);
00185   }
00186 }
00187 
00188 
00189 /** Returns the time of the selected time source.
00190  * @param time reference to a time where the result is stored
00191  */
00192 void
00193 Clock::get_time(Time &time) const
00194 {
00195   get_time(&(time.__time));
00196 }
00197 
00198 
00199 
00200 
00201 /** Returns the time of the selected time source.
00202  * @param time reference to a time where the result is stored
00203  * @param sel allows to select the time source
00204  */
00205 void
00206 Clock::get_time(Time &time, TimesourceSelector sel) const
00207 {
00208   get_time(&(time.__time), sel);
00209 }
00210 
00211 
00212 /** Returns the time of the selected time source.
00213  * @param time pointer to a Time instance
00214  */
00215 void
00216 Clock::get_time(Time *time) const
00217 {
00218   get_time(&(time->__time));
00219 }
00220 
00221 
00222 
00223 
00224 /** Returns the time of the selected time source.
00225  * @param time pointer to a Time instance where the time is stored
00226  * @param sel allows to select the time source
00227  */
00228 void
00229 Clock::get_time(Time *time, TimesourceSelector sel) const
00230 {
00231   get_time(&(time->__time), sel);
00232 }
00233 
00234 
00235 /** Returns the system time.
00236  * @param tv pointer to a timeval struct where the time is written to
00237  */
00238 void
00239 Clock::get_systime(struct timeval* tv) const
00240 {
00241   gettimeofday(tv, 0);
00242 }
00243 
00244 
00245 /** Returns the time of the selected time source.
00246  * @param time reference to Time instance where the time is stored
00247  */
00248 void
00249 Clock::get_systime(Time &time) const
00250 {
00251   gettimeofday(&(time.__time), 0);
00252 }
00253 
00254 
00255 /** Returns the time of the selected time source.
00256  * @param time pointer to Time instance where the time is stored
00257  */
00258 void
00259 Clock::get_systime(Time *time) const
00260 {
00261   gettimeofday(&(time->__time), 0);
00262 }
00263 
00264 
00265 /** Get the current time.
00266  * @return current time
00267  */
00268 Time
00269 Clock::now() const
00270 {
00271   Time t(_instance);
00272   return t.stamp();
00273 }
00274 
00275 
00276 /** How much time has elapsed since t?
00277  * Calculated as "now - t" in seconds.
00278  * @param t time
00279  * @return elapsed seconds
00280  */
00281 float
00282 Clock::elapsed(Time *t) const
00283 {
00284   Time nowt(_instance);
00285   return nowt - t;
00286 }
00287 
00288 
00289 /** How much system time has elapsed since t?
00290  * Use only for system time criteria like timeouts.
00291  * @param t time
00292  * @return elapsed system seconds
00293  */
00294 float
00295 Clock::sys_elapsed(Time *t) const
00296 {
00297   struct timeval nowt;
00298   gettimeofday(&nowt, NULL);
00299   return time_diff_sec(nowt, t->__time);
00300 }
00301 
00302 
00303 /** Convert a time given w.r.t. the external time source into the system time.
00304  * @param t the time that is converted to the system time
00305  * @return the time in system time
00306  */ 
00307 Time
00308 Clock::ext_to_realtime(const Time& t)
00309 {
00310   timeval tv;
00311   Time ret;
00312   
00313   if (NULL != ext_timesource) 
00314     {
00315       tv = ext_timesource->conv_to_realtime(t.get_timeval());
00316       ret.set_time(&tv); 
00317     }
00318   else 
00319     {
00320       ret = t;
00321     }
00322 
00323   return ret;
00324 }
00325 
00326 
00327 /** Check whether an external time source is registered.
00328  * @return true if an external time source is registered
00329  */
00330 bool
00331 Clock::has_ext_timesource() const
00332 {
00333   if (0 != ext_timesource) {
00334     return true;
00335   } else {
00336     return false;
00337   }
00338 }
00339 
00340 } // end namespace fawkes