M module-apps/GuiTimer.cpp => module-apps/GuiTimer.cpp +6 -2
@@ 44,13 44,17 @@ namespace app
{}
GuiTimer::GuiTimer(const std::string &name, Application *parent, gui::ms timeout, gui::Timer::Type type)
- : sys::Timer(name, parent, timeout, toSysTimerType(type)), sysapi{*this}
+ : sys::Timer(name, parent, timeout, toSysTimerType(type), sys::UserTimerIDGenerator()), sysapi{*this, parent}
{}
void GuiTimer::Sysapi::connect(gui::Item *item)
{
if (item != nullptr) {
- parent.connect([item, this](sys::Timer &timer) { item->onTimer(parent); });
+ parent.connect([item, this](sys::Timer &timer) {
+ if (item->onTimer(parent)) {
+ app->refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
+ }
+ });
}
}
} // namespace app
M module-apps/GuiTimer.hpp => module-apps/GuiTimer.hpp +3 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 49,10 49,11 @@ namespace app
{
friend Application;
GuiTimer &parent;
+ Application *app = nullptr;
void connect(gui::Item *item);
public:
- Sysapi(GuiTimer &parent) : parent(parent)
+ Sysapi(GuiTimer &parent, Application *app) : parent(parent), app(app)
{}
} sysapi;
};
M module-apps/application-call/windows/CallWindow.cpp => module-apps/application-call/windows/CallWindow.cpp +0 -1
@@ 412,7 412,6 @@ namespace gui
updateDuration(std::chrono::system_clock::to_time_t(systemUnitDuration));
callDuration++;
LOG_DEBUG("Update duration timer callback - %" PRIu32, static_cast<uint32_t>(callDuration.count()));
- application->refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
return true;
};
timer->start();
M module-apps/application-meditation/widgets/MeditationTimer.cpp => module-apps/application-meditation/widgets/MeditationTimer.cpp +8 -12
@@ 50,6 50,11 @@ namespace gui
timer->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
timer->setEditMode(EditMode::Browse);
+ dimensionChangedCallback = [&](gui::Item &, const BoundingBox &newDim) -> bool {
+ setArea({newDim.x, newDim.y, newDim.w, newDim.h});
+ return true;
+ };
+
onReset();
}
@@ 64,7 69,6 @@ namespace gui
{
updateTimer();
progressBar->setPercentageValue(calculatePercentageValue());
- application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
}
void MeditationTimer::updateTimer()
@@ 76,19 80,12 @@ namespace gui
timer->setText(remainingDuration.str(Duration::DisplayedFormat::Fixed0M0S));
}
- auto MeditationTimer::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) -> bool
- {
- setPosition(newDim.x, newDim.y);
- setSize(newDim.w, newDim.h);
- return true;
- }
-
void MeditationTimer::reset(std::chrono::seconds _duration, std::chrono::seconds _intervalPeriod) noexcept
{
assert(_duration != std::chrono::seconds::zero()); // Pre-condition check.
- duration = _duration;
- elapsed = std::chrono::seconds::zero();
+ duration = _duration;
+ elapsed = std::chrono::seconds::zero();
intervalPeriod = _intervalPeriod;
hasInterval = _intervalPeriod != std::chrono::seconds::zero();
onReset();
@@ 113,8 110,7 @@ namespace gui
auto MeditationTimer::onTimerTimeout(Item &self, Timer &timerTask) -> bool
{
if (isStopped() || isFinished()) {
- timerTask.stop();
- detachTimer(timerTask);
+ application->getTimers().detachTimer("MeditationTimer");
if (isFinished() && timeoutCallback != nullptr) {
timeoutCallback();
M module-apps/application-meditation/widgets/MeditationTimer.hpp => module-apps/application-meditation/widgets/MeditationTimer.hpp +0 -2
@@ 25,8 25,6 @@ namespace gui
app::ApplicationMeditation *app,
Item *_parent = nullptr);
- [[nodiscard]] auto onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) -> bool override;
-
void start();
void stop();
void reset(std::chrono::seconds _duration, std::chrono::seconds period = std::chrono::seconds::zero()) noexcept;
M module-apps/application-meditation/windows/MeditationTimerWindow.cpp => module-apps/application-meditation/windows/MeditationTimerWindow.cpp +0 -2
@@ 68,12 68,10 @@ void MeditationTimerWindow::onBeforeShow(ShowMode mode, SwitchData *data)
setVisibleRunning();
auto onMeditationEnd = [&]() -> void {
setVisibleMeditationEnd();
- application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
};
timer->registerTimeoutCallback(onMeditationEnd);
timer->reset(meditationTime, meditationIntervalPeriod);
timer->start();
- application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
};
timer->registerTimeoutCallback(onPreparation);
M module-apps/application-settings-new/windows/DisplayLightWindow.cpp => module-apps/application-settings-new/windows/DisplayLightWindow.cpp +5 -7
@@ 21,21 21,20 @@ namespace gui
isDisplayLightSwitchOn = values.lightOn;
isAutoLightSwitchOn = values.mode == screen_light_control::ScreenLightMode::Automatic;
brightnessValue = values.parameters.manualModeBrightness;
+ timerName = "AmbientLightTimer";
setTitle(utils::localize.get("app_settings_display_display_light"));
- timerTask = std::make_unique<app::GuiTimer>(
- "AmbientLightTimer", application, gui::lighting::AMBIENT_LIGHT_TIMER_MS, Timer::Type::Continous);
+ auto timerTask = std::make_unique<app::GuiTimer>(
+ timerName, application, gui::lighting::AMBIENT_LIGHT_TIMER_MS, Timer::Type::Continous);
timerCallback = [this](Item &it, Timer &task) { return onTimerTimeout(it, task); };
timerTask->start();
application->connect(std::move(timerTask), this);
}
- DisplayLightWindow::~DisplayLightWindow()
+ void DisplayLightWindow::onClose()
{
- if (timerTask != nullptr) {
- timerTask->stop();
- }
+ application->detachTimer(timerName);
}
auto DisplayLightWindow::onTimerTimeout(Item &self, Timer &task) -> bool
@@ 43,7 42,6 @@ namespace gui
ambientLight = bsp::light_sensor::readout();
refreshOptionsList();
- application->refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
return true;
}
M module-apps/application-settings-new/windows/DisplayLightWindow.hpp => module-apps/application-settings-new/windows/DisplayLightWindow.hpp +2 -2
@@ 20,7 20,7 @@ namespace gui
{
public:
DisplayLightWindow(app::Application *app, app::settingsInterface::ScreenLightSettings *screenLightSettings);
- ~DisplayLightWindow();
+ void onClose() override;
private:
auto buildOptionsList() -> std::list<Option> override;
@@ 33,7 33,7 @@ namespace gui
std::uint8_t brightnessValue = 0;
app::settingsInterface::ScreenLightSettings *screenLightSettings = nullptr;
float ambientLight = 0.0;
- std::unique_ptr<app::GuiTimer> timerTask;
+ std::string timerName;
[[nodiscard]] auto onTimerTimeout(Item &self, Timer &task) -> bool;
};
} // namespace gui
M module-sys/Service/Service.hpp => module-sys/Service/Service.hpp +51 -14
@@ 3,23 3,24 @@
#pragma once
+#include "Timer.hpp"
#include "BusProxy.hpp"
#include "Common.hpp" // for ReturnCodes, ServicePriority, BusChannels
#include "Mailbox.hpp" // for Mailbox
#include "Message.hpp" // for MessagePointer
#include "ServiceManifest.hpp"
-#include "thread.hpp" // for Thread
-#include <algorithm> // for find, max
-#include <cstdint> // for uint32_t, uint64_t
-#include <functional> // for function
-#include <iterator> // for end
-#include <map> // for map
-#include <memory> // for allocator, shared_ptr, enable_shared_from_this
-#include <string> // for string
-#include <typeindex> // for type_index
-#include <utility> // for pair
-#include <vector> // for vector<>::iterator, vector
-#include <typeinfo> // for connect by type
+#include "thread.hpp" // for Thread
+#include <algorithm> // for find, max
+#include <cstdint> // for uint32_t, uint64_t
+#include <functional> // for function
+#include <iterator> // for end
+#include <map> // for map
+#include <memory> // for allocator, shared_ptr, enable_shared_from_this
+#include <string> // for string
+#include <typeindex> // for type_index
+#include <utility> // for pair
+#include <vector> // for vector<>::iterator, vector
+#include <typeinfo> // for connect by type
namespace sys
{
@@ 124,7 125,17 @@ namespace sys
void detach(Timer *timer)
{
- list.erase(std::find(list.begin(), list.end(), timer));
+ auto it = std::find(list.begin(), list.end(), timer);
+
+ if (it != list.end()) {
+ list.erase(it);
+ }
+ }
+
+ auto findTimer(const std::string &timerName) const
+ {
+ return std::find_if(
+ list.begin(), list.end(), [&, timerName](auto &el) -> bool { return el->getName() == timerName; });
}
public:
@@ 135,18 146,44 @@ namespace sys
return std::find(list.begin(), list.end(), timer);
}
+ [[nodiscard]] auto timerExists(const std::string &timerName) const
+ {
+ return findTimer(timerName) != list.end();
+ }
+
+ void detachTimer(const std::string &timerName)
+ {
+ auto it = findTimer(timerName);
+
+ if (it != list.end()) {
+ (*it)->stop();
+ detach((*it));
+ }
+ }
+
[[nodiscard]] auto noTimer() const
{
return std::end(list);
}
+
} timers;
public:
- auto getTimers() -> auto &
+ [[nodiscard]] auto getTimers() -> auto &
{
return timers;
}
+ [[nodiscard]] auto timerExists(const std::string &timerName) -> bool
+ {
+ return timers.timerExists(timerName);
+ }
+
+ void detachTimer(const std::string &timerName)
+ {
+ timers.detachTimer(timerName);
+ }
+
auto TimerHandle(SystemMessage &message) -> ReturnCodes;
};
M module-sys/Service/Timer.cpp => module-sys/Service/Timer.cpp +10 -11
@@ 1,6 1,7 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+#include "GuiTimer.hpp"
#include "Timer.hpp"
#include "Service.hpp"
#include "TimerMessage.hpp"
@@ 21,26 22,24 @@
namespace sys
{
-
const ms Timer::timeout_infinite = std::numeric_limits<ms>().max();
- static uint32_t timer_id;
-
- auto toName(const std::string &val, uint32_t no) -> std::string
- {
- return val + "_" + std::to_string(no);
- }
- Timer::Timer(const std::string &name, Service *service, ms interval, Type type)
- : cpp_freertos::Timer((toName(name, timer_id)).c_str(), pdMS_TO_TICKS(interval), type == Type::Periodic),
- parent(service), type(type), interval(interval), name(toName(name, timer_id))
+ Timer::Timer(const std::string &name, Service *service, ms interval, Type type, const TimerIDGenerator &generator)
+ : cpp_freertos::Timer(generator.generateID(name).c_str(), pdMS_TO_TICKS(interval), type == Type::Periodic),
+ parent(service), type(type), interval(interval), name(generator.generateID(name).c_str())
{
if (service != nullptr) {
+
+ if (service->timerExists(name)) {
+ throw std::runtime_error("Timer: " + name + " exits in service: " + service->GetName());
+ }
+
service->getTimers().attach(this);
+ generator.incrementID();
}
else {
log_error("Bad timer creation!");
}
- ++timer_id;
log_debug("Timer %s created %s", name.c_str(), type == Type::Periodic ? "periodic" : "singleshot");
}
M module-sys/Service/Timer.hpp => module-sys/Service/Timer.hpp +44 -1
@@ 18,6 18,45 @@ namespace sys
{
using ms = unsigned int;
+ class TimerIDGenerator
+ {
+ public:
+ virtual ~TimerIDGenerator() = default;
+
+ virtual void incrementID() const = 0;
+ [[nodiscard]] virtual std::string generateID(const std::string &val) const = 0;
+ };
+
+ class UserTimerIDGenerator : public TimerIDGenerator
+ {
+ public:
+ void incrementID() const override{};
+
+ [[nodiscard]] std::string generateID(const std::string &val) const override
+ {
+ return val;
+ }
+ };
+ class SystemTimerIDGenerator : public TimerIDGenerator
+ {
+ static uint32_t &getId() noexcept
+ {
+ static uint32_t timer_id = 0;
+ return timer_id;
+ }
+
+ public:
+ void incrementID() const override
+ {
+ getId()++;
+ };
+
+ [[nodiscard]] std::string generateID(const std::string &val) const override
+ {
+ return val + "_" + std::to_string(getId());
+ }
+ };
+
/// Base timer for all coarse timers in system
class Timer : private cpp_freertos::Timer
{
@@ 34,7 73,11 @@ namespace sys
/// @param name this will be name of timer + postfix
/// @param parent service on which behalf timer events will be sent and received
/// @param interval time for next timer event in
- Timer(const std::string &name, Service *parent, ms interval, Type type = Type::Periodic);
+ Timer(const std::string &name,
+ Service *parent,
+ ms interval,
+ Type type = Type::Periodic,
+ const TimerIDGenerator &generator = SystemTimerIDGenerator());
/// Create timer with default name `_<id_number>` and register it in parent
/// @param parent service on which behalf timer events will be sent and received