Merge pull request #1236 from theuni/android-rebase-11
[vuplus_xbmc] / xbmc / threads / Timer.cpp
1 /*
2  *      Copyright (C) 2012 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16   *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include <algorithm>
22
23 #include "Timer.h"
24 #include "SystemClock.h"
25 #include "utils/log.h"
26
27 CTimer::CTimer(ITimerCallback *callback)
28   : CThread("CTimer"),
29     m_callback(callback),
30     m_timeout(0),
31     m_interval(false),
32     m_endTime(0)
33 { }
34
35 CTimer::~CTimer()
36 {
37   Stop(true);
38 }
39
40 bool CTimer::Start(uint32_t timeout, bool interval /* = false */)
41 {
42   if (m_callback == NULL || timeout == 0 || IsRunning())
43   {
44     CLog::Log(LOGWARNING, "CTimer: can't start timer");
45     return false;
46   }
47
48   m_timeout = timeout;
49   m_interval = interval;
50
51   CLog::Log(LOGDEBUG, "CTimer: starting for %d ms %s", m_timeout, m_interval ? "(interval)" : "");
52   Create();
53   return true;
54 }
55
56 bool CTimer::Stop(bool wait /* = false */)
57 {
58   if (!IsRunning())
59     return false;
60
61   CLog::Log(LOGDEBUG, "CTimer: stopping %s", wait ? "(wait)" : "");
62   m_bStop = true;
63   m_eventTimeout.Set();
64   StopThread(wait);
65
66   return true;
67 }
68
69 float CTimer::GetElapsedSeconds() const
70 {
71   return GetElapsedMilliseconds() / 1000.0f;
72 }
73
74 float CTimer::GetElapsedMilliseconds() const
75 {
76   if (!IsRunning())
77     return 0.0f;
78
79   return (float)(XbmcThreads::SystemClockMillis() - (m_endTime - m_timeout));
80 }
81
82 void CTimer::Process()
83 {
84   uint32_t currentTime = XbmcThreads::SystemClockMillis();
85   m_endTime = currentTime + m_timeout;
86
87   while (!m_bStop)
88   {
89     // wait the necessary time
90     if (!m_eventTimeout.WaitMSec(m_endTime - currentTime))
91     {
92       currentTime = XbmcThreads::SystemClockMillis();
93       if (m_endTime <= currentTime)
94       {
95         CLog::Log(LOGDEBUG, "CTimer: timeout");
96         // execute OnTimeout() callback
97         m_callback->OnTimeout();
98
99         // stop if this is not an interval timer
100         if (!m_interval)
101           break;
102
103         CLog::Log(LOGDEBUG, "CTimer: restart");
104         m_endTime = currentTime + m_timeout;
105       }
106     }
107   }
108
109   CLog::Log(LOGDEBUG, "CTimer: finished");
110 }