Kodi Development 22.0
for Binary and Script based Add-Ons
 
Loading...
Searching...
No Matches
Timer.h
1/*
2 * Copyright (C) 2005-2020 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#pragma once
10
11#ifdef __cplusplus
12
13#include "Thread.h"
14
15#include <functional>
16
17namespace kodi
18{
19namespace tools
20{
21
22//==============================================================================
58class CTimer : protected CThread
59{
60public:
61 class ITimerCallback;
62
63 //============================================================================
71 : CTimer(std::bind(&ITimerCallback::OnTimeout, callback))
72 {
73 }
74 //----------------------------------------------------------------------------
75
76 //============================================================================
88 explicit CTimer(std::function<void()> const& callback) : m_callback(callback) {}
89 //----------------------------------------------------------------------------
90
91 //============================================================================
95 ~CTimer() override { Stop(true); }
96 //----------------------------------------------------------------------------
97
98 //============================================================================
112 bool Start(uint64_t timeout, bool interval = false)
113 {
114 using namespace std::chrono;
115
116 if (m_callback == nullptr || timeout == 0 || IsRunning())
117 return false;
118
119 m_timeout = milliseconds(timeout);
120 m_interval = interval;
121
122 CreateThread();
123 return true;
124 }
125 //----------------------------------------------------------------------------
126
127 //============================================================================
136 bool Stop(bool wait = false)
137 {
138 if (!IsRunning())
139 return false;
140
141 m_threadStop = true;
142 m_eventTimeout.notify_all();
143 StopThread(wait);
144
145 return true;
146 }
147 //----------------------------------------------------------------------------
148
149 //============================================================================
159 bool Restart()
160 {
161 using namespace std::chrono;
162
163 if (!IsRunning())
164 return false;
165
166 Stop(true);
167 return Start(duration_cast<milliseconds>(m_timeout).count(), m_interval);
168 }
169 //----------------------------------------------------------------------------
170
171 //============================================================================
177 void RestartAsync(uint64_t timeout)
178 {
179 using namespace std::chrono;
180
181 m_timeout = milliseconds(timeout);
182 const auto now = system_clock::now();
183 m_endTime = now.time_since_epoch() + m_timeout;
184 m_eventTimeout.notify_all();
185 }
186 //----------------------------------------------------------------------------
187
188 //============================================================================
194 bool IsRunning() const { return CThread::IsRunning(); }
195 //----------------------------------------------------------------------------
196
197 //============================================================================
203 float GetElapsedSeconds() const { return GetElapsedMilliseconds() / 1000.0f; }
204 //----------------------------------------------------------------------------
205
206 //============================================================================
213 {
214 using namespace std::chrono;
215
216 if (!IsRunning())
217 return 0.0f;
218
219 const auto now = system_clock::now();
220 return static_cast<float>(
221 duration_cast<milliseconds>(now.time_since_epoch() - (m_endTime - m_timeout)).count());
222 }
223 //----------------------------------------------------------------------------
224
225 //============================================================================
232 {
233 public:
234 //==========================================================================
238 virtual ~ITimerCallback() = default;
239 //--------------------------------------------------------------------------
240
241 //==========================================================================
268 virtual void OnTimeout() = 0;
269 //--------------------------------------------------------------------------
270 };
271 //----------------------------------------------------------------------------
272
273protected:
274 void Process() override
275 {
276 using namespace std::chrono;
277
278 while (!m_threadStop)
279 {
280 auto currentTime = system_clock::now();
281 m_endTime = currentTime.time_since_epoch() + m_timeout;
282
283 // wait the necessary time
284 std::mutex mutex;
285 std::unique_lock<std::mutex> lock(mutex);
286 const auto waitTime = duration_cast<milliseconds>(m_endTime - currentTime.time_since_epoch());
287 if (m_eventTimeout.wait_for(lock, waitTime) == std::cv_status::timeout)
288 {
289 currentTime = system_clock::now();
290 if (m_endTime.count() <= currentTime.time_since_epoch().count())
291 {
292 // execute OnTimeout() callback
293 m_callback();
294
295 // continue if this is an interval timer, or if it was restarted during callback
296 if (!m_interval && m_endTime.count() <= currentTime.time_since_epoch().count())
297 break;
298 }
299 }
300 }
301 }
302
303private:
304 bool m_interval = false;
305 std::function<void()> m_callback;
306 std::chrono::system_clock::duration m_timeout;
307 std::chrono::system_clock::duration m_endTime;
308 std::condition_variable_any m_eventTimeout;
309};
311//------------------------------------------------------------------------------
312
313} /* namespace tools */
314} /* namespace kodi */
315
316#endif /* __cplusplus */
Definition Thread.h:91
Definition Timer.h:59
void Process() override
The function to be added by the addon as a child to carry out the process thread.
Definition Timer.h:274
std::atomic< bool > m_threadStop
Atomic bool to indicate thread is active.
Definition Thread.h:381
void StopThread(bool wait=true)
Stop a running thread.
Definition Thread.h:267
bool IsRunning() const
Check thread inside this class is running and active.
Definition Thread.h:143
void CreateThread(bool autoDelete=false)
Create a new thread defined by this class on child.
Definition Thread.h:170
virtual ~ITimerCallback()=default
Class destructor.
virtual void OnTimeout()=0
Callback function to implement if constructor CTimer(kodi::tools::CTimer::ITimerCallback* callback) i...
void RestartAsync(uint64_t timeout)
Restart the timer with new timeout without touch of his thread.
Definition Timer.h:177
float GetElapsedSeconds() const
Get elapsed time as floating point of timer as seconds.
Definition Timer.h:203
bool Start(uint64_t timeout, bool interval=false)
Start the timer by given time in milliseconds to make his call by arrive of them.
Definition Timer.h:112
bool Stop(bool wait=false)
Stop the timer if it is active.
Definition Timer.h:136
bool Restart()
Restart timer complete by stop and restart his thread again.
Definition Timer.h:159
CTimer(kodi::tools::CTimer::ITimerCallback *callback)
Class constructor to pass individual other class as callback.
Definition Timer.h:70
~CTimer() override
Class destructor.
Definition Timer.h:95
bool IsRunning() const
Check timer is still active to wait for next call.
Definition Timer.h:194
float GetElapsedMilliseconds() const
Get elapsed time as floating point of timer as milliseconds.
Definition Timer.h:212
CTimer(std::function< void()> const &callback)
Class constructor to pass individual function as callback.
Definition Timer.h:88