librf
timer.h
1 #pragma once
2 
3 namespace resumef
4 {
5  struct timer_manager;
6  typedef std::shared_ptr<timer_manager> timer_mgr_ptr;
7  typedef std::weak_ptr<timer_manager> timer_mgr_wptr;
8 
9  namespace detail
10  {
11  typedef std::chrono::system_clock timer_clock_type;
12  typedef std::function<void(bool)> timer_callback_type;
13 
17  struct timer_target : public std::enable_shared_from_this<timer_target>
18  {
19  friend timer_manager;
20  private:
21  enum struct State : uint32_t
22  {
23  Invalid,
24  Added,
25  Runing,
26  };
27  timer_clock_type::time_point tp;
28  timer_callback_type cb;
29  State st = State::Invalid;
30 #if _DEBUG
31  private:
32  timer_manager * _manager = nullptr;
33 #endif
34  public:
35  timer_target(const timer_clock_type::time_point & tp_, const timer_callback_type & cb_)
36  : tp(tp_)
37  , cb(cb_)
38  {
39  }
40  timer_target(const timer_clock_type::time_point & tp_, timer_callback_type && cb_)
41  : tp(tp_)
42  , cb(std::forward<timer_callback_type>(cb_))
43  {
44  }
45  private:
46  timer_target() = delete;
47  timer_target(const timer_target &) = delete;
48  timer_target(timer_target && right_) = delete;
49  timer_target & operator = (const timer_target &) = delete;
50  timer_target & operator = (timer_target && right_) = delete;
51  };
52 
53  typedef std::shared_ptr<timer_target> timer_target_ptr;
54  typedef std::weak_ptr<timer_target> timer_target_wptr;
55  }
56 
62  {
63  private:
64  timer_mgr_wptr _manager;
65  detail::timer_target_wptr _target;
66  public:
67 #ifndef DOXYGEN_SKIP_PROPERTY
68  timer_handler() = default;
69  timer_handler(const timer_handler &) = default;
70  timer_handler(timer_handler && right_) noexcept;
71  timer_handler & operator = (const timer_handler &) = default;
72  timer_handler & operator = (timer_handler && right_) noexcept;
73 #endif //DOXYGEN_SKIP_PROPERTY
74  timer_handler(timer_manager * manager_, const detail::timer_target_ptr & target_);
75 
76  void reset();
77  bool stop();
78  bool expired() const;
79  };
80 
84  struct timer_manager : public std::enable_shared_from_this<timer_manager>
85  {
86 #ifndef DOXYGEN_SKIP_PROPERTY
87  typedef detail::timer_target timer_target;
88  typedef detail::timer_target_ptr timer_target_ptr;
89  typedef detail::timer_clock_type clock_type;
90  typedef clock_type::duration duration_type;
91  typedef clock_type::time_point time_point_type;
92 
93  typedef std::vector<timer_target_ptr> timer_vector_type;
94  typedef std::multimap<clock_type::time_point, timer_target_ptr> timer_map_type;
95 #endif
96  public:
97  timer_manager();
98  ~timer_manager();
99 
100  template<class _Rep, class _Period, class _Cb>
101  timer_target_ptr add(const std::chrono::duration<_Rep, _Period> & dt_, _Cb && cb_)
102  {
103  return add_(std::chrono::duration_cast<duration_type>(dt_), std::forward<_Cb>(cb_));
104  }
105  template<class _Clock, class _Duration = typename _Clock::duration, class _Cb>
106  timer_target_ptr add(const std::chrono::time_point<_Clock, _Duration> & tp_, _Cb && cb_)
107  {
108  return add_(std::chrono::time_point_cast<duration_type>(tp_), std::forward<_Cb>(cb_));
109  }
110  template<class _Rep, class _Period, class _Cb>
111  timer_handler add_handler(const std::chrono::duration<_Rep, _Period> & dt_, _Cb && cb_)
112  {
113  return{ this, add(dt_, std::forward<_Cb>(cb_)) };
114  }
115  template<class _Clock, class _Duration = typename _Clock::duration, class _Cb>
116  timer_handler add_handler(const std::chrono::time_point<_Clock, _Duration> & tp_, _Cb && cb_)
117  {
118  return{ this, add(tp_, std::forward<_Cb>(cb_)) };
119  }
120 
121  bool stop(const timer_target_ptr & sptr);
122 
123  inline bool empty() const
124  {
125  return _runing_timers.empty() && _added_timers.empty();
126  }
127  void clear();
128  void update();
129 
130 #ifndef DOXYGEN_SKIP_PROPERTY
131  template<class _Cb>
132  timer_target_ptr add_(const duration_type & dt_, _Cb && cb_)
133  {
134  return add_(std::make_shared<timer_target>(clock_type::now() + dt_, std::forward<_Cb>(cb_)));
135  }
136  template<class _Cb>
137  timer_target_ptr add_(const time_point_type & tp_, _Cb && cb_)
138  {
139  return add_(std::make_shared<timer_target>(tp_, std::forward<_Cb>(cb_)));
140  }
141  private:
142  spinlock _added_mtx;
143  timer_vector_type _added_timers;
144  timer_map_type _runing_timers;
145 
146  timer_target_ptr add_(const timer_target_ptr & sptr);
147  static void call_target_(const timer_target_ptr & sptr, bool canceld);
148 #endif
149  };
150 
151 
152  inline timer_handler::timer_handler(timer_manager * manager_, const detail::timer_target_ptr & target_)
153  : _manager(manager_->shared_from_this())
154  , _target(target_)
155  {
156  }
157  inline timer_handler::timer_handler(timer_handler && right_) noexcept
158  : _manager(std::move(right_._manager))
159  , _target(std::move(right_._target))
160  {
161  }
162 
163  inline timer_handler & timer_handler::operator = (timer_handler && right_) noexcept
164  {
165  if (this != &right_)
166  {
167  _manager = std::move(right_._manager);
168  _target = std::move(right_._target);
169  }
170  return *this;
171  }
172 
173  inline void timer_handler::reset()
174  {
175  _manager.reset();
176  _target.reset();
177  }
178 
179  inline bool timer_handler::stop()
180  {
181  bool result = false;
182 
183  if (!_target.expired())
184  {
185  auto sptr = _manager.lock();
186  if (sptr)
187  result = sptr->stop(_target.lock());
188  _target.reset();
189  }
190  _manager.reset();
191 
192  return result;
193  }
194 
195  inline bool timer_handler::expired() const
196  {
197  return _target.expired();
198  }
199 }
resumef::timer_manager
定时器管理器。
Definition: timer.h:84
resumef::detail::timer_target
定时器对象。
Definition: timer.h:17
resumef::spinlock
一个自旋锁实现。
Definition: spinlock.h:14
resumef::timer_handler
定时器句柄。
Definition: timer.h:61