2 Copyright 2008 Thomas Steger
3 Copyright 2020 Chris Tallon
5 This file is part of VOMP.
7 VOMP is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 VOMP is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with VOMP. If not, see <https://www.gnu.org/licenses/>.
29 #include "messagequeue.h"
33 #include "sleeptimer.h"
35 SleepTimer::SleepTimer()
37 logger = Log::getInstance();
38 boxstack = BoxStack::getInstance();
39 timers = Timers::getInstance();
42 // --- Input Functions ----
44 void SleepTimer::go() // User presses GO, from Control
46 std::lock_guard<std::mutex> lg(stateLock);
48 if (state == 0) // inactive
52 vsleeptimer = new VSleepTimer();
53 vsleeptimer->setTime(timerText);
55 boxstack->add(vsleeptimer);
56 boxstack->update(vsleeptimer);
58 timers->setTimerD(this, 1, 3); // 3s remove vsleeptimer timer
59 timers->setTimerD(this, 2, sec - 31); // logic timer 31s before end
63 else if (state == 1) // counting, no displays - display current running time
67 vsleeptimer = new VSleepTimer();
68 vsleeptimer->setTime(liveText);
70 boxstack->add(vsleeptimer);
71 boxstack->update(vsleeptimer);
73 timers->setTimerD(this, 1, 3); // 3s remove vsleeptimer timer
76 else if (state == 2) // counting, modify display showing already.
80 vsleeptimer->setTime(timerText);
82 boxstack->update(vsleeptimer);
84 timers->setTimerD(this, 1, 3); // update existing remove vsleeptimer timer
87 timers->cancelTimer(this, 2);
88 state = 4; // user went beyond 2h, turning it off
92 timers->setTimerD(this, 2, sec - 31); // reset the logic timer 31s before end
95 else if (state == 3) // counting, countdown display showing. turn it off
97 timers->cancelTimer(this, 2);
99 vsleeptimer = new VSleepTimer(); // Show a new VSleepTimer OFF dialogue
100 vsleeptimer->setTime(tr("OFF"));
102 boxstack->add(vsleeptimer);
103 boxstack->update(vsleeptimer);
105 boxstack->remove(vcountdown); // this deletes vcountdown as well
108 timers->setTimerD(this, 1, 3); // 3s remove vsleeptimer timer
111 else if (state == 4) // not counting, OFF dialogue showing
113 boxstack->remove(vsleeptimer);
119 void SleepTimer::timercall(int clientReference)
121 std::lock_guard<std::mutex> lg(stateLock);
123 if (clientReference == 1) // Remove the VSleepTimer
125 if (state == 2 || state == 4) // modify display showing, counting or not
127 boxstack->remove(vsleeptimer);
129 if (state == 2) state = 1;
130 else if (state == 4) state = 0;
133 else if (clientReference == 2) // sleep timer logic
135 if (state == 0) // inactive
137 logger->log("SleepTimer", Log::ERR, "Received timercall when state 0");
139 else if (state == 1 || state == 2) // counting (either with or without modify display showing)
141 if (state == 2) // counting, modify display showing
143 // User has very recently pressed the sleeptimer button and the modify display / livetext is showing
144 // But now the logic timer has fired for the first time in the countdown.
145 // Delete the vsleeptimer before going on
147 boxstack->remove(vsleeptimer);
152 // To receive a timer now means we are starting the countdown
155 vcountdown = new VCountdown(); // Show a new VCountdown dialogue
156 vcountdown->setTime(sec);
158 boxstack->add(vcountdown);
159 boxstack->update(vcountdown);
161 timers->setTimerD(this, 2, 1); // logic timer every 1s
164 else if (state == 3) // counting, countdown display showing
168 if (sec > -1) // update countdown
170 vcountdown->setTime(sec);
172 boxstack->update(vcountdown);
173 timers->setTimerD(this, 2, 1); // logic timer every 1s
175 else // end of countdown
177 boxstack->remove(vcountdown);
181 Message* m = new Message();
182 m->message = Message::INPUT_EVENT;
183 m->p_to = Message::CONTROL;
185 m->parameter = Input::POWER;
186 MessageQueue::getInstance()->postMessage(m);
189 else if (state == 4) // not counting, off dialogue showing
191 logger->log("SleepTimer", Log::ERR, "Received timercall when state 4");
196 void SleepTimer::shutdown()
198 std::lock_guard<std::mutex> lg(stateLock);
200 // Cancel any logic timer
201 if (state == 1 || state == 2 || state == 3)
202 timers->cancelTimer(this, 2);
204 // Cancel any remove-vsleeptimer counter
205 if (state > 1) timers->cancelTimer(this, 1);
209 boxstack->remove(vsleeptimer);
215 boxstack->remove(vcountdown);
223 // ------------------------
225 void SleepTimer::calcNewTime()
227 if (sec < 890) { timerText = "0:15"; sec = 900; }
228 else if (sec < 1790) { timerText = "0:30"; sec = 1800; }
229 else if (sec < 2690) { timerText = "0:45"; sec = 2700; }
230 else if (sec < 3590) { timerText = "1:00"; sec = 3600; }
231 else if (sec < 4490) { timerText = "1:15"; sec = 4500; }
232 else if (sec < 5390) { timerText = "1:30"; sec = 5400; }
233 else if (sec < 6290) { timerText = "1:45"; sec = 6300; }
234 else if (sec < 7190) { timerText = "2:00"; sec = 7200; }
235 else { timerText = tr("OFF"); sec = -1; }
237 endTime = std::chrono::system_clock::now() + std::chrono::seconds(sec);
240 void SleepTimer::calcCurrentSec()
242 auto remainingTime = endTime - std::chrono::system_clock::now();
243 auto remainingTimeS = std::chrono::duration_cast<std::chrono::seconds>(remainingTime);
244 sec = static_cast<int>(remainingTimeS.count()); // I think this chrono stuff is a bit too ... wordy .........
245 SNPRINTF(liveText, 10, "0:%02d", sec / 60);
248 // ------------ VSleepTimer class
250 VSleepTimer::VSleepTimer()
254 if (Video::getInstance()->getFormat() == Video::PAL)
256 setPosition(100, 499);
260 setPosition(90, 400);
263 setBackgroundColour(DrawStyle::VIEWBACKGROUND);
265 wsClock.nextSymbol = WSymbol::CLOCK;
266 wsClock.setPosition(3, 0);
270 void VSleepTimer::setTime(const char* text)
272 displaySleeptimer = text;
275 void VSleepTimer::draw()
278 drawText(displaySleeptimer, 50, 2, DrawStyle::LIGHTTEXT);
281 // ------------ VCountdown class
283 VCountdown::VCountdown()
287 if (Video::getInstance()->getFormat() == Video::PAL)
289 setPosition(100, 499);
293 setPosition(90, 400);
296 setBackgroundColour(DrawStyle::VIEWBACKGROUND);
298 wsClock.nextSymbol = WSymbol::CLOCK;
299 wsClock.nextColour = DrawStyle::RED;
300 wsClock.setPosition(3, 0);
304 void VCountdown::setTime(int tsec)
309 void VCountdown::draw()
314 SNPRINTF(temp, 10, "0:%02d", sec);
315 drawText(temp, 50, 2, DrawStyle::RED);