1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
/*
* Copyright (C) 2005-2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#include "AlarmClock.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogKaiToast.h"
#include "events/EventLog.h"
#include "events/NotificationEvent.h"
#include "guilib/LocalizeStrings.h"
#include "log.h"
#include "messaging/ApplicationMessenger.h"
#include "utils/StringUtils.h"
#include <mutex>
#include <utility>
using namespace std::chrono_literals;
CAlarmClock::CAlarmClock() : CThread("AlarmClock")
{
}
CAlarmClock::~CAlarmClock() = default;
void CAlarmClock::Start(const std::string& strName, float n_secs, const std::string& strCommand, bool bSilent /* false */, bool bLoop /* false */)
{
// make lower case so that lookups are case-insensitive
std::string lowerName(strName);
StringUtils::ToLower(lowerName);
Stop(lowerName);
SAlarmClockEvent event;
event.m_fSecs = static_cast<double>(n_secs);
event.m_strCommand = strCommand;
event.m_loop = bLoop;
if (!m_bIsRunning)
{
StopThread();
Create();
m_bIsRunning = true;
}
uint32_t labelAlarmClock;
uint32_t labelStarted;
if (StringUtils::EqualsNoCase(strName, "shutdowntimer"))
{
labelAlarmClock = 20144;
labelStarted = 20146;
}
else
{
labelAlarmClock = 13208;
labelStarted = 13210;
}
EventPtr alarmClockActivity(new CNotificationEvent(
labelAlarmClock,
StringUtils::Format(g_localizeStrings.Get(labelStarted), static_cast<int>(event.m_fSecs) / 60,
static_cast<int>(event.m_fSecs) % 60)));
auto eventLog = CServiceBroker::GetEventLog();
if (eventLog)
{
if (bSilent)
eventLog->Add(alarmClockActivity);
else
eventLog->AddWithNotification(alarmClockActivity);
}
event.watch.StartZero();
std::unique_lock<CCriticalSection> lock(m_events);
m_event.insert(make_pair(lowerName,event));
CLog::Log(LOGDEBUG, "started alarm with name: {}", lowerName);
}
void CAlarmClock::Stop(const std::string& strName, bool bSilent /* false */)
{
std::unique_lock<CCriticalSection> lock(m_events);
std::string lowerName(strName);
StringUtils::ToLower(lowerName); // lookup as lowercase only
std::map<std::string,SAlarmClockEvent>::iterator iter = m_event.find(lowerName);
if (iter == m_event.end())
return;
uint32_t labelAlarmClock;
if (StringUtils::EqualsNoCase(strName, "shutdowntimer"))
labelAlarmClock = 20144;
else
labelAlarmClock = 13208;
std::string strMessage;
float elapsed = 0.f;
if (iter->second.watch.IsRunning())
elapsed = iter->second.watch.GetElapsedSeconds();
if (elapsed > static_cast<float>(iter->second.m_fSecs))
strMessage = g_localizeStrings.Get(13211);
else
{
float remaining = static_cast<float>(iter->second.m_fSecs) - elapsed;
strMessage = StringUtils::Format(g_localizeStrings.Get(13212), static_cast<int>(remaining) / 60,
static_cast<int>(remaining) % 60);
}
if (iter->second.m_strCommand.empty() || static_cast<float>(iter->second.m_fSecs) > elapsed)
{
EventPtr alarmClockActivity(new CNotificationEvent(labelAlarmClock, strMessage));
auto eventLog = CServiceBroker::GetEventLog();
if (eventLog)
{
if (bSilent)
eventLog->Add(alarmClockActivity);
else
eventLog->AddWithNotification(alarmClockActivity);
}
}
else
{
CServiceBroker::GetAppMessenger()->PostMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr,
iter->second.m_strCommand);
if (iter->second.m_loop)
{
iter->second.watch.Reset();
return;
}
}
iter->second.watch.Stop();
m_event.erase(iter);
}
void CAlarmClock::Process()
{
while( !m_bStop)
{
std::string strLast;
{
std::unique_lock<CCriticalSection> lock(m_events);
for (std::map<std::string,SAlarmClockEvent>::iterator iter=m_event.begin();iter != m_event.end(); ++iter)
if (iter->second.watch.IsRunning() &&
iter->second.watch.GetElapsedSeconds() >= static_cast<float>(iter->second.m_fSecs))
{
Stop(iter->first);
if ((iter = m_event.find(strLast)) == m_event.end())
break;
}
else
strLast = iter->first;
}
CThread::Sleep(100ms);
}
}
|