bug in RC
[anna.git] / include / anna / core / util / DelayMeter.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_core_util_DelayMeter_hpp
10 #define anna_core_util_DelayMeter_hpp
11
12 #include <string>
13
14 namespace anna {
15
16 /**
17    Facilita la medicion de los tiempos empleados las distintas partes de nuestra aplicacion.
18
19    Permite calcular tiempos acumulados como tiempos individuales. Por ejemplo:
20
21    \code
22
23    #include <anna/core/DelayMeter.hpp>
24
25    void foo () {
26       DelayMeter <_TimeUnit> meter;
27
28       goo ();
29       _TimeUnit gooTime = meter.getValue ();
30
31       hoo ();
32       _TimeUnit goohooTime = meter.setControlPoint ();
33
34       joo ();
35       _TimeUnit jooTime = meter.getValue ();
36    }
37    \endcode
38
39    Dónde _TimeUnit podria ser anna::Second, anna::Millisecond, anna::Microsecond
40 */
41 template <class _TimeUnit> class DelayMeter {
42 public:
43   /**
44      Constructor
45      Inicializa la cuenta de temporizacion.
46   */
47   DelayMeter() { a_timestamp = _TimeUnit::getTime(); }
48
49   /**
50    * Constructor copia.
51    * Copia la cuenta de utilizacion de la instancia recibida como parametro.
52    * \param other Instancia de la copiar los parametros para calcular el tiempo transcurrido.
53    */
54   DelayMeter(const DelayMeter& other) : a_timestamp(other.a_timestamp), a_topReference(other.a_topReference) { ;}
55
56   /**
57    * Inicializa la cuenta de temporizacion. Este metodo es invocado automaticamente desde el contructor la clase
58    * por lo que si vamos usar esta instancia para tomar un unica medida no es necesario invocarlo.
59    * \warning Elimina el punto de referencia temporal que puediera haberse establecido con #setTopReference.
60    * \return El número de milisegundos transcurridos desde la última vez que inicializamos la cuenta de temporizacion.
61    */
62   void setControlPoint() throw() {
63     a_timestamp = _TimeUnit::getTime();
64     clearTopReference();
65   }
66
67   /**
68    * Inicializa la cuenta de temporizacion. Este metodo es invocado automaticamente desde el contructor la clase
69    * por lo que si vamos usar esta instancia para tomar un unica medida no es necesario invocarlo.
70    * \warning Elimina el punto de referencia temporal que puediera haberse establecido con #setTopReference.
71    * \return El número de milisegundos transcurridos desde la última vez que inicializamos la cuenta de temporizacion.
72    *
73    * \param timestamp Valor de referencia a establecer.
74    */
75   void setControlPoint(const _TimeUnit& timestamp) throw() {
76     a_timestamp = timestamp;
77     clearTopReference();
78   }
79
80   /**
81    * Se da la posiblidad de establecer un punto de referencia temporal de forma
82    * que cuando se invoque a DelayMeter::getValue, el calculo de la diferencia de tiempo
83    * no se hará entre la marca de tiempo y el tiempo actual, sino la marca de
84    * tiempo y ésta marca de referencia.
85    *
86    * Esta funcionalidad ha sido requerida para medir el tiempo de ejecución "real"
87    * de tareas que se ejecutan dentro de un thread. Ya que puede pasar un tiempo
88    * indeterminado desde que se termina la tarea MT (momento en el que se establecerá
89    * la marca de tiempo) y el núcleo y demás partes pueden tener conocimiento de que
90    * esa tarea ha sido finalidad.
91    */
92   void setTopReference(const _TimeUnit& topReference) throw() { a_topReference = topReference; }
93
94   /**
95    * Elimina el punto de referencia temporal.
96    */
97   void clearTopReference() throw() { a_topReference = _TimeUnit(0); }
98
99   /**
100    * Inicializa el valor del punto de referencia.
101    */
102   void clear() throw() { a_timestamp = 0; }
103
104   /**
105    * Devuelve el número de milisegundos transcurridos desde la última vez que inicializamos la cuenta de temporización.
106    * Si se ha establecido un punto de referencia mediante #setTopReference, devolverá la diferencia entre el
107    * el punto de control y la referencia, en otro caso, devolverá la diferencia entre el punto de control y el
108    * momento actual.
109    * \return El número de milisegundos transcurridos desde la última vez que inicializamos la cuenta de temporizacion.
110    * \warning Si detecta algun fallo devolvera 0.
111    */
112   _TimeUnit getValue() const throw() {
113     a_now = (a_topReference == _TimeUnit(0)) ? _TimeUnit::getTime() : a_topReference;
114     return (a_now > a_timestamp) ? (a_now - a_timestamp) : _TimeUnit(0);
115   }
116
117   /**
118    * Devuelve el número de milisegundos transcurridos desde la última vez que inicializamos la cuenta de temporización.
119    * Si se ha establecido un punto de referencia mediante #setTopReference, devolverá la diferencia entre el
120    * el punto de control y la referencia, en otro caso, devolverá la diferencia entre el punto de control y el
121    * momento actual.
122    * \param now Valor temporal tomado como referencia.
123    * \return El número de milisegundos transcurridos desde la última vez que inicializamos la cuenta de temporizacion.
124    * \warning Si detecta algun fallo devolvera 0.
125    */
126   _TimeUnit getValue(const _TimeUnit& now) const throw() {
127     return ((a_now = now) > a_timestamp) ? (a_now - a_timestamp) : _TimeUnit(0);
128   }
129
130   /**
131    * Devuelve el tiempo que se usó como referencia al calcular el retardo en #getValue
132    * \return El tiempo que se usó como referencia al calcular el retardo en #getValue
133    */
134   const _TimeUnit& getNow() const throw() { return a_now; }
135
136   /**
137    * Operador copia.
138    * \param other Instancia de la que copiar.
139    */
140   DelayMeter& operator= (const DelayMeter& other) throw() { a_timestamp = other.a_timestamp; a_topReference = other.a_topReference; return *this; }
141
142   /**
143    * Compara el retardo acumulado por esta instancia con el valor recibido.
144    * \param left Valor numérico con el comparar.
145    * \return \em true si el retardo acumulado es mayor que el parámetro recibido o \em false en otro caso.
146    */
147   bool operator> (const _TimeUnit& left) const throw() { return getValue() > left; }
148
149   /**
150    * Compara el retardo acumulado por esta instancia con el valor recibido.
151    * \param left Valor numérico con el comparar.
152    * \return \em true si el retardo acumulado es mayor que el parámetro recibido o \em false en otro caso.
153    */
154   bool operator< (const _TimeUnit& left) const throw() { return getValue() < left; }
155
156   /**
157    * Devuelve la cadena que muestra el tiempo medido por esta instancia.
158    * \return la cadena que muestra el tiempo medido por esta instancia.
159    */
160   std::string asString() const throw() { return getValue().asString(); }
161
162   /**
163    * Devuelve la cadena de depuración de esta instancia.
164    * \param whatis Texto con el nombre lógico de esta instancia.
165    * \return la cadena de depuración de esta instancia.
166    */
167   std::string asDebugString(const char* whatis) const throw() {
168     std::string result(whatis);
169     result += " { TopReference: ";
170     result += a_topReference.asString();
171     result += " | TimeStamp: ";
172     result += a_timestamp.asString();
173     result += " | Now: ";
174     result += a_now.asString();
175     return result += " }";
176   }
177
178 private:
179   _TimeUnit a_topReference;
180   _TimeUnit a_timestamp;
181   mutable _TimeUnit a_now;
182 };
183
184 }
185
186 #endif
187
188