Merge pull request #26278 from basilgello/taglib2-fix-piers
[xbmc.git] / xbmc / threads / Timer.cpp
blobd06ba4056b0f053cc9395013477ef8e99dc9f5af
1 /*
2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "Timer.h"
11 #include <algorithm>
13 using namespace std::chrono_literals;
15 CTimer::CTimer(std::function<void()> const& callback)
16 : CThread("Timer"), m_callback(callback), m_timeout(0ms), m_interval(false)
17 { }
19 CTimer::CTimer(ITimerCallback *callback)
20 : CTimer(std::bind(&ITimerCallback::OnTimeout, callback))
21 { }
23 CTimer::~CTimer()
25 Stop(true);
28 bool CTimer::Start(std::chrono::milliseconds timeout, bool interval /* = false */)
30 if (m_callback == NULL || timeout == 0ms || IsRunning())
31 return false;
33 m_timeout = timeout;
34 m_interval = interval;
36 Create();
37 return true;
40 bool CTimer::Stop(bool wait /* = false */)
42 if (!IsRunning())
43 return false;
45 m_bStop = true;
46 m_eventTimeout.Set();
47 StopThread(wait);
49 return true;
52 void CTimer::RestartAsync(std::chrono::milliseconds timeout)
54 m_timeout = timeout;
55 m_endTime = std::chrono::steady_clock::now() + timeout;
56 m_eventTimeout.Set();
59 bool CTimer::Restart()
61 if (!IsRunning())
62 return false;
64 Stop(true);
66 return Start(m_timeout, m_interval);
69 float CTimer::GetElapsedSeconds() const
71 return GetElapsedMilliseconds() / 1000.0f;
74 float CTimer::GetElapsedMilliseconds() const
76 if (!IsRunning())
77 return 0.0f;
79 auto now = std::chrono::steady_clock::now();
80 std::chrono::duration<float, std::milli> duration = (now - (m_endTime - m_timeout));
82 return duration.count();
85 void CTimer::Process()
87 while (!m_bStop)
89 auto currentTime = std::chrono::steady_clock::now();
90 m_endTime = currentTime + m_timeout;
92 // wait the necessary time
93 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(m_endTime - currentTime);
95 if (!m_eventTimeout.Wait(duration))
97 currentTime = std::chrono::steady_clock::now();
98 if (m_endTime <= currentTime)
100 // execute OnTimeout() callback
101 m_callback();
103 // continue if this is an interval timer, or if it was restarted during callback
104 if (!m_interval && m_endTime <= currentTime)
105 break;