1 //-----------------------------------------------------------------------------
2 /** @file libboardgame_base/IntervalChecker.h
3     @author Markus Enzenberger
4     @copyright GNU General Public License version 3 or later */
5 //-----------------------------------------------------------------------------
6 
7 #ifndef LIBBOARDGAME_BASE_INTERVAL_CHECKER_H
8 #define LIBBOARDGAME_BASE_INTERVAL_CHECKER_H
9 
10 #include <functional>
11 #include "TimeSource.h"
12 
13 namespace libboardgame_base {
14 
15 using namespace std;
16 
17 //-----------------------------------------------------------------------------
18 
19 /** Reduces regular calls to an expensive function to a given time interval.
20     The class assumes that its check() function is called in regular time
21     intervals and forwards only every n'th call to the expensive function with
22     n being adjusted dynamically to a given time interval. check() returns
23     true, if the expensive function was called and returned true in the
24     past. */
25 class IntervalChecker
26 {
27 public:
28     /** Constructor.
29         @param time_source The time source. The lifetime of this
30         parameter must exceed the lifetime of the class instance.
31         @param time_interval The time interval in seconds
32         @param f The expensive function */
33     IntervalChecker(TimeSource& time_source, double time_interval,
34                     const function<bool()>& f);
35 
36     bool operator()();
37 
38     /** Disable the dynamic updating of the interval.
39         Can be used if the non-reproducability of the time measurement used
40         for dynamic updating of the check interval is undesirable.
41         @param interval The fixed interval (number of calls) to use for calling
42         the expensive function. (Must be greater zero). */
43     void set_deterministic(unsigned interval);
44 
45 protected:
46     TimeSource& m_time_source;
47 
48 private:
49     bool m_is_first_check = true;
50 
51     bool m_is_deterministic = false;
52 
53     bool m_result = false;
54 
55     unsigned m_count = 1;
56 
57     unsigned m_count_interval = 1;
58 
59     double m_time_interval;
60 
61     double m_last_time;
62 
63     function<bool()> m_function;
64 
65     bool check_expensive();
66 };
67 
operator()68 inline bool IntervalChecker::operator()()
69 {
70     if (--m_count == 0)
71         return check_expensive();
72     return m_result;
73 }
74 
75 //-----------------------------------------------------------------------------
76 
77 } // namespace libboardgame_base
78 
79 #endif // LIBBOARDGAME_BASE_INTERVAL_CHECKER_H
80