xmscore  1.0
Observer.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
6 //------------------------------------------------------------------------------
7 
8 //----- Included files ---------------------------------------------------------
9 
10 // 1. Precompiled header
11 
12 // 2. My own header
13 #include <xmscore/misc/Observer.h>
14 
15 // 3. Standard library headers
16 
17 // 4. External library headers
18 #pragma warning(push)
19 #pragma warning(disable : 4103)
20 #include <boost/timer/timer.hpp>
21 #pragma warning(pop)
22 
23 // 5. Shared code headers
24 
25 // 6. Non-shared code headers
26 
27 //----- Forward declarations ---------------------------------------------------
28 
29 //----- External globals -------------------------------------------------------
30 
31 //----- Namespace declaration --------------------------------------------------
32 namespace xms
33 {
34 //----- Constants / Enumerations -----------------------------------------------
35 
36 //----- Classes / Structs ------------------------------------------------------
37 
38 //----- Internal functions -----------------------------------------------------
39 
40 //----- Class / Function definitions -------------------------------------------
43 {
44 public:
45  impl()
47  {
48  }
49  ~impl() {}
50 
51  void BeginOperationString();
52  void EndOperation();
53  double ElapsedTimeInSeconds();
54  double EstimatedTimeRemainingInSec(double a_percentComplete, double a_elapsedTime);
55 
56  boost::timer::cpu_timer m_timer;
58 };
59 
60 //------------------------------------------------------------------------------
62 //------------------------------------------------------------------------------
63 Observer::Observer()
64 : m_p(new Observer::impl())
65 {
66 }
67 //------------------------------------------------------------------------------
69 //------------------------------------------------------------------------------
70 Observer::~Observer()
71 {
72 }
73 //------------------------------------------------------------------------------
77 //------------------------------------------------------------------------------
78 bool Observer::ProgressStatus(double a_percentComplete)
79 {
80  if (a_percentComplete > m_p->m_percentComplete + .02)
81  {
82  double elapsedTime = m_p->ElapsedTimeInSeconds();
83  m_p->m_percentComplete = a_percentComplete;
84  OnProgressStatus(a_percentComplete);
85 
86  TimeElapsedInSeconds(elapsedTime);
87  double rem = m_p->EstimatedTimeRemainingInSec(a_percentComplete, elapsedTime);
89  return true;
90  }
91  return false;
92 } // Observer::ProgressStatus
93 //------------------------------------------------------------------------------
97 //------------------------------------------------------------------------------
98 void Observer::TimeRemainingInSeconds(double a_remainingSeconds)
99 {
100  (void)a_remainingSeconds;
101 } // Observer::TimeRemainingInSeconds
102 //------------------------------------------------------------------------------
105 //------------------------------------------------------------------------------
106 void Observer::TimeElapsedInSeconds(double a_elapsedSeconds)
107 {
108  (void)a_elapsedSeconds;
109 } // Observer::TimeElapsedInSeconds
110 //------------------------------------------------------------------------------
115 //------------------------------------------------------------------------------
116 void Observer::BeginOperationString(const std::string& a_operation)
117 {
118  m_p->BeginOperationString();
119  OnBeginOperationString(a_operation);
120  ProgressStatus(0.0);
121 } // Observer::BeginOperationString
122 //------------------------------------------------------------------------------
124 //------------------------------------------------------------------------------
126 {
127  m_p->EndOperation();
128  OnEndOperation();
129  ProgressStatus(0.0);
130 } // Observer::EndOperation
131 //------------------------------------------------------------------------------
134 //------------------------------------------------------------------------------
135 void Observer::UpdateMessage(const std::string& a_message)
136 {
137  OnUpdateMessage(a_message);
138 }
139 //------------------------------------------------------------------------------
143 //------------------------------------------------------------------------------
144 void Observer::OnBeginOperationString(const std::string& a_operation)
145 {
146  (void)a_operation;
147 } // Observer::OnBeginOperationString
148 //------------------------------------------------------------------------------
150 //------------------------------------------------------------------------------
152 {
153 } // Observer::OnEndOperation
154 //------------------------------------------------------------------------------
157 //------------------------------------------------------------------------------
158 void Observer::OnUpdateMessage(const std::string& a_message)
159 {
160  (void)a_message; // For Doxygen
161 } // Observer::OnUpdateMessage
162 //------------------------------------------------------------------------------
165 //------------------------------------------------------------------------------
167 {
168  m_timer.start();
169  m_percentComplete = 0;
170 } // Observer::impl::BeginOperationString
171 //------------------------------------------------------------------------------
173 //------------------------------------------------------------------------------
175 {
176  m_timer.stop();
177 } // Observer::impl::EndOperation
178 //------------------------------------------------------------------------------
181 //------------------------------------------------------------------------------
183 {
184  boost::timer::cpu_times const elapsed_times(m_timer.elapsed());
185  boost::timer::nanosecond_type time = elapsed_times.wall;
186  const double NANO_PER_SEC = 1e9;
187  double seconds = time / NANO_PER_SEC;
188  return seconds;
189 } // Observer::impl::ElapsedTimeInSeconds
190 //------------------------------------------------------------------------------
195 //------------------------------------------------------------------------------
196 double Observer::impl::EstimatedTimeRemainingInSec(double a_percentComplete, double a_elapsedTime)
197 {
198  if (a_percentComplete < .01)
199  return 60;
200 
201  double percentRemaining = 1 - a_percentComplete;
202  double timeRemaining = (a_elapsedTime * percentRemaining) / a_percentComplete;
203  return timeRemaining;
204 } // Observer::impl::EstimatedTimeRemainingInSec
205 
206 } // namespace xms
207 
208 #ifdef CXX_TEST
209 #include <xmscore/misc/Observer.t.h>
210 
211 #include <boost/thread/thread.hpp>
212 
213 #include <xmscore/math/math.h>
215 
219 {
220 public:
223  m_elapsedSeconds;
224  std::stringstream m_info;
225 
226 private:
227  //------------------------------------------------------------------------------
230  //------------------------------------------------------------------------------
231  virtual void OnProgressStatus(double a_percentComplete) override
232  {
233  m_percentComplete = a_percentComplete;
234  int i = (int)(xms::Round(m_percentComplete * 100));
235  m_info << "Percent complete: " << i << "%.\n";
236  }
237  //------------------------------------------------------------------------------
239  //------------------------------------------------------------------------------
240  virtual void OnBeginOperationString(const std::string& a_operation) override
241  {
242  if (!m_info.str().empty())
243  m_info << "\n";
244  m_info << "Begin operation: " << a_operation << ".\n";
245  }
246  //------------------------------------------------------------------------------
248  //------------------------------------------------------------------------------
249  virtual void TimeElapsedInSeconds(double a_elapsedSeconds) override
250  {
251  m_elapsedSeconds = a_elapsedSeconds;
252  int i = (int)(xms::Round(m_elapsedSeconds * 10));
253  m_info << "Elapsed seconds: 0." << i << ".\n";
254  }
255 
256  //------------------------------------------------------------------------------
259  //------------------------------------------------------------------------------
260  virtual void TimeRemainingInSeconds(double a_secondsRemaining) override
261  {
262  m_remainingSeconds = a_secondsRemaining;
263  int i = (int)(xms::Round(m_remainingSeconds * 10));
264  m_info << "Time remaining (seconds): 0." << i << ".\n";
265  }
266 };
269 {
270 public:
271  MockMesher() {}
272  ~MockMesher() {}
273 
274  //------------------------------------------------------------------------------
277  //------------------------------------------------------------------------------
278  void SetObserver(BSHP<xms::Observer> a_) { m_prog = a_; }
279  //------------------------------------------------------------------------------
283  //------------------------------------------------------------------------------
284  void WaitForNextTenthSecond(boost::timer::cpu_timer& a_timer, int& a_count)
285  {
286  ++a_count;
287  const long long tenth_second = 100000000LL;
288  while (a_timer.elapsed().wall < tenth_second * a_count)
289  {
290  }
291  // boost::this_thread::sleep(boost::posix_time::millisec(100));
292  }
294  //------------------------------------------------------------------------------
296  //------------------------------------------------------------------------------
298  {
299  if (!m_prog)
300  return;
301 
302  boost::timer::cpu_timer timer;
303  int count = 0;
304 
305  m_prog->BeginOperationString("Generating mesh points");
306  for (int i = 0; i < 4; ++i)
307  {
308  WaitForNextTenthSecond(timer, count);
309  m_prog->ProgressStatus((double)(i + 1) / 4);
310  }
311 
312  m_prog->BeginOperationString("Triangulating");
313  for (int i = 0; i < 5; ++i)
314  {
315  WaitForNextTenthSecond(timer, count);
316  m_prog->ProgressStatus((double)(i + 1) / 5);
317  }
318 
319  m_prog->BeginOperationString("Generating unstructured grid");
320  for (int i = 0; i < 3; ++i)
321  {
322  WaitForNextTenthSecond(timer, count);
323  m_prog->ProgressStatus((double)(i + 1) / 3);
324  }
325  }
326 
327  BSHP<xms::Observer> m_prog;
328 };
333 //------------------------------------------------------------------------------
336 //------------------------------------------------------------------------------
337 #ifndef CXXTEST4
338 //------------------------------------------------------------------------------
340 //------------------------------------------------------------------------------
341 const CxxTest::TestGroup& ObserverIntermediateTests::group()
342 {
343  return *CxxTest::TestGroup::GetGroup(CxxTest::TG_INTERMEDIATE);
344  // return CxxTest::TestSuite::group();
345 } // ObserverIntermediateTests::group
346 #endif
347 //------------------------------------------------------------------------------
349 //------------------------------------------------------------------------------
351 {
352  MockObserver o;
353  o.BeginOperationString("Test Operation");
354  boost::this_thread::sleep(boost::posix_time::millisec(100));
355  o.ProgressStatus(.2);
356  double remaining = (o.m_elapsedSeconds * .8) / .2;
357  const double DELTA = 1e-5;
358  TS_ASSERT_DELTA(remaining, o.m_remainingSeconds, DELTA);
359 } // ObserverIntermediateTests::testTimeRemaining
361 //------------------------------------------------------------------------------
363 //------------------------------------------------------------------------------
365 {
366  // create an object derived off of Observer
367  BSHP<MockObserver> p(new MockObserver());
368  // create a mock meshing class
369  MockMesher m;
370  // set the observer on the mesher
371  m.SetObserver(p);
372  // execute the mesher
373  m.PretendMeshing();
374  // capture the output from the observer class and verify it
375  std::string outStr(p->m_info.str());
376  std::string baseStr =
377  "Begin operation: Generating mesh points.\n"
378  "Percent complete: 25%.\n"
379  "Elapsed seconds: 0.1.\n"
380  "Time remaining (seconds): 0.3.\n"
381  "Percent complete: 50%.\n"
382  "Elapsed seconds: 0.2.\n"
383  "Time remaining (seconds): 0.2.\n"
384  "Percent complete: 75%.\n"
385  "Elapsed seconds: 0.3.\n"
386  "Time remaining (seconds): 0.1.\n"
387  "Percent complete: 100%.\n"
388  "Elapsed seconds: 0.4.\n"
389  "Time remaining (seconds): 0.0.\n"
390  "\n"
391  "Begin operation: Triangulating.\n"
392  "Percent complete: 20%.\n"
393  "Elapsed seconds: 0.1.\n"
394  "Time remaining (seconds): 0.4.\n"
395  "Percent complete: 40%.\n"
396  "Elapsed seconds: 0.2.\n"
397  "Time remaining (seconds): 0.3.\n"
398  "Percent complete: 60%.\n"
399  "Elapsed seconds: 0.3.\n"
400  "Time remaining (seconds): 0.2.\n"
401  "Percent complete: 80%.\n"
402  "Elapsed seconds: 0.4.\n"
403  "Time remaining (seconds): 0.1.\n"
404  "Percent complete: 100%.\n"
405  "Elapsed seconds: 0.5.\n"
406  "Time remaining (seconds): 0.0.\n"
407  "\n"
408  "Begin operation: Generating unstructured grid.\n"
409  "Percent complete: 33%.\n"
410  "Elapsed seconds: 0.1.\n"
411  "Time remaining (seconds): 0.2.\n"
412  "Percent complete: 67%.\n"
413  "Elapsed seconds: 0.2.\n"
414  "Time remaining (seconds): 0.1.\n"
415  "Percent complete: 100%.\n"
416  "Elapsed seconds: 0.3.\n"
417  "Time remaining (seconds): 0.0.\n";
418  TS_ASSERT_EQUALS(baseStr, outStr);
419 } // ObserverIntermediateTests::testMockObserver
421 
422 #endif
void testTimeRemaining()
tests the estimated time remaining
Definition: Observer.cpp:350
double m_percentComplete
percent complete
Definition: Observer.cpp:57
virtual void TimeRemainingInSeconds(double a_remainingSeconds)
Virtual method to publish the time remaining.
Definition: Observer.cpp:98
virtual void TimeElapsedInSeconds(double a_elapsedSeconds)
Virtual method to publish the elasped time.
Definition: Observer.cpp:106
void PretendMeshing()
mock meshing method
Definition: Observer.cpp:297
virtual void TimeRemainingInSeconds(double a_secondsRemaining) override
Definition: Observer.cpp:260
void WaitForNextTenthSecond(boost::timer::cpu_timer &a_timer, int &a_count)
wait until next tenth second passed
Definition: Observer.cpp:284
double EstimatedTimeRemainingInSec(double a_percentComplete, double a_elapsedTime)
Returns the elapsed time for the operation being observed.
Definition: Observer.cpp:196
virtual void OnProgressStatus(double a_percentComplete) override
captures the progress of an operation
Definition: Observer.cpp:231
void testMockObserver()
[snip_test_Example_Observer]
Definition: Observer.cpp:364
void UpdateMessage(const std::string &a_message)
Updates the message but not the percent complete.
Definition: Observer.cpp:135
virtual void OnEndOperation()
Virtual function for derived class to get end operation event.
Definition: Observer.cpp:151
void BeginOperationString(const std::string &a_operation)
Publishes the name of the operation and starts the timing of the operation.
Definition: Observer.cpp:116
double m_remainingSeconds
seconds remaining
Definition: Observer.cpp:221
Implementation of the observer class.
Definition: Observer.cpp:42
virtual const CxxTest::TestGroup & group()
Defines the test group.
Definition: Observer.cpp:341
void EndOperation()
Stops the timer.
Definition: Observer.cpp:174
BSHP< xms::Observer > m_prog
observer class to report progress
Definition: Observer.cpp:327
mock meshing class to show how the observer works
Definition: Observer.cpp:268
virtual void OnUpdateMessage(const std::string &a_message)
Definition: Observer.cpp:158
bool ProgressStatus(double a_percentComplete)
Method to publish the progress status.
Definition: Observer.cpp:78
virtual void OnBeginOperationString(const std::string &a_operation) override
Definition: Observer.cpp:240
std::stringstream m_info
string info captured by the class
Definition: Observer.cpp:224
BSHP< impl > m_p
implementation class
Definition: Observer.h:48
virtual void OnBeginOperationString(const std::string &a_operation)
Virtual function for derived class to get the operation string.
Definition: Observer.cpp:144
virtual void OnProgressStatus(double a_percentComplete)=0
void EndOperation()
Ends the operation.
Definition: Observer.cpp:125
boost::timer::cpu_timer m_timer
timer to get elapsed time
Definition: Observer.cpp:56
void BeginOperationString()
Starts the timer to know the elapsed time for the operation and to estimate the time remaining...
Definition: Observer.cpp:166
double m_elapsedSeconds
seconds elapsed
Definition: Observer.cpp:221
Derived class used for testing use of Observer class.
Definition: Observer.cpp:218
Class used with the observer pattern.
Definition: Observer.h:26
virtual void TimeElapsedInSeconds(double a_elapsedSeconds) override
Definition: Observer.cpp:249
void SetObserver(BSHP< xms::Observer > a_)
set the observer class
Definition: Observer.cpp:278
double ElapsedTimeInSeconds()
Returns the elapsed time for the operation being observed.
Definition: Observer.cpp:182