From 6c900d7b38114cd939c12bd35d7666916af8b5b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ta=C5=84ski?= Date: Tue, 12 Jan 2021 12:23:43 +0100 Subject: [PATCH] [EGD-5166] Add query-callback synchronization mechanism Receiver object cancels the callbacks at the end of its lifecycle. --- changelog.md | 1 + module-apps/Application.cpp | 14 ++- module-apps/Application.hpp | 12 +- module-apps/AsyncTask.cpp | 68 +++++++++++ module-apps/AsyncTask.hpp | 108 ++++++++++++++++++ module-apps/CMakeLists.txt | 6 + module-apps/CallbackStorage.cpp | 59 ++++++++++ module-apps/CallbackStorage.hpp | 39 +++++++ .../ApplicationAlarmClock.cpp | 13 +-- .../models/AlarmsRepository.cpp | 19 +-- .../models/AlarmsRepository.hpp | 2 +- .../ApplicationCalendar.cpp | 17 +-- .../models/AllEventsModel.cpp | 8 +- .../models/AllEventsModel.hpp | 5 +- .../models/DayEventsModel.cpp | 9 +- .../models/DayEventsModel.hpp | 4 +- .../windows/CalendarMainWindow.cpp | 15 +-- .../windows/CalendarMainWindow.hpp | 3 +- .../ApplicationCallLog.cpp | 4 +- .../ApplicationDesktop.cpp | 3 +- .../ApplicationMessages.cpp | 82 ++++++------- .../ApplicationMessages.hpp | 3 +- .../models/BaseThreadsRecordModel.cpp | 5 - .../models/BaseThreadsRecordModel.hpp | 1 - .../models/SMSTemplateModel.cpp | 8 +- .../models/SMSTemplateModel.hpp | 5 +- .../models/SMSThreadModel.cpp | 8 +- .../models/SMSThreadModel.hpp | 4 +- .../models/ThreadsModel.cpp | 8 +- .../models/ThreadsModel.hpp | 2 +- .../models/ThreadsSearchResultsModel.cpp | 9 +- .../models/ThreadsSearchResultsModel.hpp | 2 +- .../windows/MessagesMainWindow.cpp | 10 +- .../windows/MessagesMainWindow.hpp | 2 +- .../windows/NewMessage.cpp | 30 ++--- .../windows/NewMessage.hpp | 3 +- .../windows/SMSThreadViewWindow.cpp | 9 +- .../windows/SMSThreadViewWindow.hpp | 2 +- .../application-notes/ApplicationNotes.cpp | 14 +-- .../model/NotesRepository.cpp | 31 ++--- .../model/NotesRepository.hpp | 2 +- .../ApplicationPhonebook.cpp | 18 +-- .../models/PhonebookModel.cpp | 12 +- .../models/PhonebookModel.hpp | 5 +- .../ApplicationSettings.cpp | 2 +- .../windows/BluetoothWindow.cpp | 6 +- module-apps/tests/CMakeLists.txt | 9 ++ module-apps/tests/test-CallbackStorage.cpp | 70 ++++++++++++ module-apps/tests/tests-main.cpp | 5 + .../service-cellular/ServiceCellular.cpp | 3 +- module-services/service-db/DBServiceAPI.cpp | 11 -- .../service-db/DBServiceAPI_GetByQuery.cpp | 7 +- module-services/service-db/ServiceDB.cpp | 9 -- .../service-db/service-db/DBServiceAPI.hpp | 12 +- .../calendarEvents/CalendarEventsHelper.cpp | 12 +- .../timeEvents/CalendarTimeEvents.cpp | 11 +- 56 files changed, 594 insertions(+), 247 deletions(-) create mode 100644 module-apps/AsyncTask.cpp create mode 100644 module-apps/AsyncTask.hpp create mode 100644 module-apps/CallbackStorage.cpp create mode 100644 module-apps/CallbackStorage.hpp create mode 100644 module-apps/tests/CMakeLists.txt create mode 100644 module-apps/tests/test-CallbackStorage.cpp create mode 100644 module-apps/tests/tests-main.cpp diff --git a/changelog.md b/changelog.md index 8591d5d40d240f77cbd431fa6f446c2e8445cdab..3b6712493acb6573fcd2deccae54de502ec2260a 100644 --- a/changelog.md +++ b/changelog.md @@ -6,6 +6,7 @@ * Battery Brownout detection * VoLTE ON/OFF switch in Settings Network window * Add PLL2 clock switching +* Support for asynchronous callbacks on application side. ### Changed diff --git a/module-apps/Application.cpp b/module-apps/Application.cpp index c331bbbc955b3a366ee7c033f978b24c460759c7..520229fb6d082503bb1053692bec951142074a53 100644 --- a/module-apps/Application.cpp +++ b/module-apps/Application.cpp @@ -69,8 +69,9 @@ namespace app StartInBackground startInBackground, uint32_t stackDepth, sys::ServicePriority priority) - : Service(name, parent, stackDepth, priority), default_window(gui::name::window::main_window), - windowsStack(this), startInBackground{startInBackground}, settings(std::make_unique(this)) + : Service(std::move(name), std::move(parent), stackDepth, priority), + default_window(gui::name::window::main_window), windowsStack(this), startInBackground{startInBackground}, + callbackStorage{std::make_unique()}, settings(std::make_unique(this)) { keyTranslator = std::make_unique(); busChannels.push_back(sys::BusChannels::ServiceCellularNotifications); @@ -85,7 +86,10 @@ namespace app [this](std::string value) { timeFormatChanged(value); }); } - Application::~Application() = default; + Application::~Application() noexcept + { + windowsStack.windows.clear(); + } Application::State Application::getState() { @@ -701,4 +705,8 @@ namespace app return timeFormat12; } + void Application::cancelCallbacks(AsyncCallbackReceiver::Ptr receiver) + { + callbackStorage->removeAll(receiver); + } } /* namespace app */ diff --git a/module-apps/Application.hpp b/module-apps/Application.hpp index f59bfc417da320d6c62e6d1a7ac7f498252b05c7..43728286961991fc9ecaf653f78fb331e4e3a230 100644 --- a/module-apps/Application.hpp +++ b/module-apps/Application.hpp @@ -3,8 +3,10 @@ #pragma once +#include "AsyncTask.hpp" #include "Audio/AudioCommon.hpp" // for Volume, Play... #include "Audio/Profiles/Profile.hpp" // for Profile, Pro... +#include "CallbackStorage.hpp" #include "Service/Bus.hpp" // for Bus #include "Service/Common.hpp" // for ReturnCodes #include "Service/Message.hpp" // for MessagePointer @@ -117,7 +119,7 @@ namespace app /// This is template for creating new applications. Main difference between Application and service is that: /// 1. Application has access to GUI and Input /// 2. Application lifetime is managed with app::manager::ApplicationManager - class Application : public sys::Service + class Application : public sys::Service, public AsyncCallbacksDeleter { public: /// state in which application is right now @@ -187,7 +189,7 @@ namespace app uint32_t stackDepth = 4096, sys::ServicePriority priority = sys::ServicePriority::Idle); - virtual ~Application(); + virtual ~Application() noexcept; Application::State getState(); void setState(State st); @@ -282,6 +284,8 @@ namespace app void toggleTorch(bsp::torch::ColourTemperature temperature); + void cancelCallbacks(AsyncCallbackReceiver::Ptr receiver) override; + /// @defgroup Application Application static functions /// All this functions are meant to be used in ApplicationManager only /// @note consider moving these as private elements of ApplicationManager i.e. under names @@ -351,6 +355,10 @@ namespace app /// set of rendering commands will carry information to GUI service that system needs to be closed. After /// displaying the screen GUI will notify application manager to request system shutdown. bool shutdownInProgress = false; + /// Storage for asynchronous tasks callbacks. + std::unique_ptr callbackStorage; + friend class AsyncTask; // Async tasks need access to application internals, e.g. callback storage, to make + // their API simple. /// informs self that there was key press /// used to provide a way for long press/multipress handling in application diff --git a/module-apps/AsyncTask.cpp b/module-apps/AsyncTask.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c110da6ab7513878d7ea4f88edbd1dadb523a477 --- /dev/null +++ b/module-apps/AsyncTask.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "AsyncTask.hpp" +#include "Application.hpp" + +namespace app +{ + AsyncCallbackReceiver::AsyncCallbackReceiver(AsyncCallbacksDeleter *deleter) noexcept : deleter{deleter} + {} + + AsyncCallbackReceiver::~AsyncCallbackReceiver() + { + if (deleter != nullptr) { + deleter->cancelCallbacks(this); + } + } + + void AsyncTask::execute(Application *application, AsyncCallbackReceiver::Ptr receiverObject) + { + const auto requestId = onExecute(application); + application->callbackStorage->registerCallback(requestId, receiverObject); + } + + std::unique_ptr AsyncQuery::createFromQuery(std::unique_ptr &&query, + db::Interface::Name target) + { + return std::make_unique(std::move(query), target); + } + + AsyncQuery::AsyncQuery(std::unique_ptr &&query, db::Interface::Name target) noexcept + : query{std::move(query)}, target{target} + {} + + void AsyncQuery::setCallback(std::unique_ptr &&listener) noexcept + { + query->setQueryListener(std::move(listener)); + } + + void AsyncQuery::setCallback(db::QueryCallbackFunction &&callback) noexcept + { + query->setQueryListener(db::QueryCallback::fromFunction(std::move(callback))); + } + + RequestId AsyncQuery::onExecute(Application *application) + { + const auto [_, id] = DBServiceAPI::GetQuery(application, target, std::move(query)); + return id; + } + + auto NullCallback::execute() -> bool + { + // Nothing to do. + return false; + } + + QueryCallback::QueryCallback(db::QueryResponse *response) : response{response} + {} + + auto QueryCallback::execute() -> bool + { + const auto result = response->getResult(); + if (result != nullptr && result->hasListener()) { + return result->handle(); + } + return false; + } +} // namespace app diff --git a/module-apps/AsyncTask.hpp b/module-apps/AsyncTask.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8fa479bf9e4560be9695bc1e4d51b88825b3fbf9 --- /dev/null +++ b/module-apps/AsyncTask.hpp @@ -0,0 +1,108 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include +#include + +#include + +namespace app +{ + class Application; // Forward declaration + + using RequestId = std::uint64_t; + class AsyncCallbackReceiver; + + class AsyncCallbacksDeleter + { + public: + virtual ~AsyncCallbacksDeleter() noexcept = default; + + virtual void cancelCallbacks(AsyncCallbackReceiver *receiver) = 0; + }; + + class AsyncCallbackReceiver + { + public: + using Ptr = AsyncCallbackReceiver *; + + explicit AsyncCallbackReceiver(AsyncCallbacksDeleter *deleter) noexcept; + virtual ~AsyncCallbackReceiver() = 0; + + private: + AsyncCallbacksDeleter *deleter; + }; + + /** + * Executes an operation on the sender's thread and saves the info about the receiver context for callback use. + * Intended to use in order to avoid callbacks called on invalid receiver contexts. + */ + class AsyncTask + { + public: + virtual ~AsyncTask() noexcept = default; + + /** + * Executes a task in application's thread and saves the receiver object. + * @param application Application + * @param receiverObject The context of receiver + */ + void execute(Application *application, AsyncCallbackReceiver::Ptr receiverObject); + + private: + /** + * The specific operation that is to be executed by a task. + * @param application Application + * @return Request identifier, to be matched with a response. + */ + [[nodiscard]] virtual auto onExecute(Application *application) -> RequestId = 0; + }; + + /** + * A database query that is using the mechanism of AsyncTask. + */ + class AsyncQuery : public AsyncTask + { + public: + [[nodiscard]] static auto createFromQuery(std::unique_ptr &&query, db::Interface::Name target) + -> std::unique_ptr; + + AsyncQuery(std::unique_ptr &&query, db::Interface::Name target) noexcept; + + void setCallback(db::QueryCallbackFunction &&callback) noexcept; + void setCallback(std::unique_ptr &&listener) noexcept; + + private: + [[nodiscard]] auto onExecute(Application *application) -> RequestId override; + + std::unique_ptr query; + db::Interface::Name target; + }; + + class AsyncCallback + { + public: + virtual ~AsyncCallback() noexcept = default; + + [[nodiscard]] virtual auto execute() -> bool = 0; + }; + + class NullCallback : public AsyncCallback + { + public: + [[nodiscard]] auto execute() -> bool override; + }; + + class QueryCallback : public AsyncCallback + { + public: + explicit QueryCallback(db::QueryResponse *response); + + [[nodiscard]] auto execute() -> bool override; + + private: + db::QueryResponse *response; + }; +} // namespace app diff --git a/module-apps/CMakeLists.txt b/module-apps/CMakeLists.txt index b624471ccf1b114e9a9973cfebe603f36bfe41b9..2c515d72ee7b6e69f99fac6ea7e1b39143c5c5e5 100644 --- a/module-apps/CMakeLists.txt +++ b/module-apps/CMakeLists.txt @@ -15,6 +15,8 @@ set( SOURCES "Application.cpp" "GuiTimer.cpp" "WindowsFactory.cpp" + "AsyncTask.cpp" + "CallbackStorage.cpp" "windows/AppWindow.cpp" "windows/OptionWindow.cpp" "windows/Options.cpp" @@ -156,3 +158,7 @@ target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_14 ) + +if (${ENABLE_TESTS}) + add_subdirectory(tests) +endif() diff --git a/module-apps/CallbackStorage.cpp b/module-apps/CallbackStorage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d47c9247f44c1b205ef26aa81004cc94823cd479 --- /dev/null +++ b/module-apps/CallbackStorage.cpp @@ -0,0 +1,59 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "CallbackStorage.hpp" + +#include "MessageType.hpp" + +#include + +namespace app +{ + CallbackStorage::CallbackEntry::CallbackEntry(RequestId id, AsyncCallbackReceiver::Ptr receiver) noexcept + : id{id}, receiver{receiver} + {} + + auto CallbackStorage::getCallback(sys::ResponseMessage *response) -> std::unique_ptr + { + if (containsCallbackFor(response)) { + remove(response); + return toCallback(response); + } + return std::make_unique(); + } + + auto CallbackStorage::containsCallbackFor(sys::ResponseMessage *response) const noexcept -> bool + { + return std::any_of( + entries.begin(), entries.end(), [response](const auto &entry) { return entry->id == response->uniID; }); + } + + void CallbackStorage::remove(sys::ResponseMessage *response) + { + const auto it = std::remove_if( + entries.begin(), entries.end(), [response](auto &&entry) { return entry->id == response->uniID; }); + entries.erase(it, entries.end()); + } + + auto CallbackStorage::toCallback(sys::ResponseMessage *response) -> std::unique_ptr + { + if (response->responseTo == MessageType::DBQuery) { + if (auto queryResponse = dynamic_cast(response); queryResponse != nullptr) { + return std::make_unique(queryResponse); + } + } + return std::make_unique(); + } + + void CallbackStorage::registerCallback(RequestId id, AsyncCallbackReceiver::Ptr receiver) + { + entries.push_back(std::make_unique(id, receiver)); + } + + void CallbackStorage::removeAll(AsyncCallbackReceiver::Ptr receiver) + { + const auto it = std::remove_if( + entries.begin(), entries.end(), [receiver](const auto &entry) { return entry->receiver == receiver; }); + entries.erase(it, entries.end()); + } +} // namespace app diff --git a/module-apps/CallbackStorage.hpp b/module-apps/CallbackStorage.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1f00a906c7f3bcac1c9aa401b64eb1f7ac8e2977 --- /dev/null +++ b/module-apps/CallbackStorage.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "AsyncTask.hpp" + +#include "module-sys/Service/Message.hpp" + +#include +#include + +namespace app +{ + class CallbackStorage + { + public: + [[nodiscard]] auto containsCallbackFor(sys::ResponseMessage *response) const noexcept -> bool; + [[nodiscard]] auto getCallback(sys::ResponseMessage *response) -> std::unique_ptr; + + void registerCallback(RequestId id, AsyncCallbackReceiver::Ptr receiver); + void removeAll(AsyncCallbackReceiver::Ptr receiver); + + private: + [[nodiscard]] static auto toCallback(sys::ResponseMessage *response) -> std::unique_ptr; + + void remove(sys::ResponseMessage *response); + + struct CallbackEntry + { + public: + CallbackEntry(RequestId id, AsyncCallbackReceiver::Ptr receiver) noexcept; + + RequestId id; + AsyncCallbackReceiver::Ptr receiver; + }; + std::list> entries; + }; +} // namespace app diff --git a/module-apps/application-alarm-clock/ApplicationAlarmClock.cpp b/module-apps/application-alarm-clock/ApplicationAlarmClock.cpp index 16d7f1144efceb044dec5a5f3ee69a093c99adf9..56199174819dcfd1b92b9f980d51c9a6760c5385 100644 --- a/module-apps/application-alarm-clock/ApplicationAlarmClock.cpp +++ b/module-apps/application-alarm-clock/ApplicationAlarmClock.cpp @@ -51,17 +51,8 @@ namespace app // handle database response if (resp != nullptr) { handled = true; - switch (resp->responseTo) { - case MessageType::DBQuery: { - if (auto queryResponse = dynamic_cast(resp)) { - auto result = queryResponse->getResult(); - if (result->hasListener() && result->handle()) { - refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); - } - } - } break; - default: - break; + if (auto command = callbackStorage->getCallback(resp); command->execute()) { + refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); } } if (handled) { diff --git a/module-apps/application-alarm-clock/models/AlarmsRepository.cpp b/module-apps/application-alarm-clock/models/AlarmsRepository.cpp index 6af79360c0ababb546aa0285cc8b6dd8baef35b6..bf956ad79eaacceab37f92b0b5ee1f91a993d253 100644 --- a/module-apps/application-alarm-clock/models/AlarmsRepository.cpp +++ b/module-apps/application-alarm-clock/models/AlarmsRepository.cpp @@ -9,15 +9,19 @@ #include #include +#include "AsyncTask.hpp" + namespace app::alarmClock { - AlarmsDBRepository::AlarmsDBRepository(Application *application) : application{application} + AlarmsDBRepository::AlarmsDBRepository(Application *application) + : AsyncCallbackReceiver{application}, application{application} {} void AlarmsDBRepository::getLimited(std::uint32_t offset, std::uint32_t limit, const OnGetCallback &callback) { auto query = std::make_unique(offset, limit); - query->setQueryListener(db::QueryCallback::fromFunction([callback](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Alarms); + task->setCallback([callback](auto response) { auto result = dynamic_cast(response); if (result == nullptr) { return false; @@ -26,15 +30,16 @@ namespace app::alarmClock callback(result->getResult(), result->getCountResult()); } return true; - })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Alarms, std::move(query)); + }); + task->execute(application, this); } template void AlarmsDBRepository::GetQuery(std::unique_ptr query, const AbstractAlarmsRepository::OnResultCallback &callback) { - query->setQueryListener(db::QueryCallback::fromFunction([callback](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Alarms); + task->setCallback([callback](auto response) { auto result = dynamic_cast(response); if (result == nullptr) { return false; @@ -43,8 +48,8 @@ namespace app::alarmClock callback(result->succeed()); } return true; - })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Alarms, std::move(query)); + }); + task->execute(application, this); } void AlarmsDBRepository::add(const AlarmsRecord &alarm, const AbstractAlarmsRepository::OnResultCallback &callback) diff --git a/module-apps/application-alarm-clock/models/AlarmsRepository.hpp b/module-apps/application-alarm-clock/models/AlarmsRepository.hpp index 573c337faee50d447ace65fe49142cc77e6cd7df..f480e76ca5937795559a3e2f2a4dc4ef2114660a 100644 --- a/module-apps/application-alarm-clock/models/AlarmsRepository.hpp +++ b/module-apps/application-alarm-clock/models/AlarmsRepository.hpp @@ -23,7 +23,7 @@ namespace app::alarmClock virtual void turnOffAll(const OnResultCallback &callback) = 0; }; - class AlarmsDBRepository : public AbstractAlarmsRepository + class AlarmsDBRepository : public AbstractAlarmsRepository, public AsyncCallbackReceiver { public: explicit AlarmsDBRepository(Application *app); diff --git a/module-apps/application-calendar/ApplicationCalendar.cpp b/module-apps/application-calendar/ApplicationCalendar.cpp index 3f3628c07086eb89c9bf040cb752ea06b32b4162..8736f5c47fb67d53fe2abb077bd75fa9a2a58273 100644 --- a/module-apps/application-calendar/ApplicationCalendar.cpp +++ b/module-apps/application-calendar/ApplicationCalendar.cpp @@ -81,21 +81,8 @@ namespace app // handle database response if (resp != nullptr) { handled = true; - switch (resp->responseTo) { - case MessageType::DBQuery: { - if (auto queryResponse = dynamic_cast(resp)) { - auto result = queryResponse->getResult(); - LOG_DEBUG("queryResponse != nullptr"); - if (result->hasListener()) { - LOG_DEBUG("Has listener"); - if (result->handle()) { - refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); - } - } - } - } break; - default: - break; + if (auto command = callbackStorage->getCallback(resp); command->execute()) { + refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); } } if (handled) { diff --git a/module-apps/application-calendar/models/AllEventsModel.cpp b/module-apps/application-calendar/models/AllEventsModel.cpp index e01404bfca12934aed0e60261177a00b37272e22..93872f1563fdc1f36a57ae0e9c3af8ed5aed4ddc 100644 --- a/module-apps/application-calendar/models/AllEventsModel.cpp +++ b/module-apps/application-calendar/models/AllEventsModel.cpp @@ -10,7 +10,7 @@ #include #include -AllEventsModel::AllEventsModel(app::Application *app) : DatabaseModel(app) +AllEventsModel::AllEventsModel(app::Application *app) : DatabaseModel(app), app::AsyncCallbackReceiver{app} { application = app; assert(app != nullptr); @@ -24,9 +24,9 @@ unsigned int AllEventsModel::requestRecordsCount() void AllEventsModel::requestRecords(const uint32_t offset, const uint32_t limit) { auto query = std::make_unique(offset, limit); - query->setQueryListener( - db::QueryCallback::fromFunction([this](auto response) { return handleQueryResponse(response); })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Events, std::move(query)); + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Events); + task->setCallback([this](auto response) { return handleQueryResponse(response); }); + task->execute(application, this); } unsigned int AllEventsModel::getMinimalItemHeight() const diff --git a/module-apps/application-calendar/models/AllEventsModel.hpp b/module-apps/application-calendar/models/AllEventsModel.hpp index 6e58f21cd8ecc890446cc5c2eda7fdfe0104e155..dd3ed33dbbfdd169a1730dd91624350e66434eba 100644 --- a/module-apps/application-calendar/models/AllEventsModel.hpp +++ b/module-apps/application-calendar/models/AllEventsModel.hpp @@ -8,13 +8,14 @@ #include #include -class AllEventsModel : public app::DatabaseModel, public gui::ListItemProvider +class AllEventsModel : public app::DatabaseModel, + public gui::ListItemProvider, + public app::AsyncCallbackReceiver { app::Application *application = nullptr; public: AllEventsModel(app::Application *app); - virtual ~AllEventsModel() override = default; void requestRecords(const uint32_t offset, const uint32_t limit) override; bool updateRecords(std::vector records) override; diff --git a/module-apps/application-calendar/models/DayEventsModel.cpp b/module-apps/application-calendar/models/DayEventsModel.cpp index 25b00f4792f7af10a2fd1bac9eb84d5b0c19d871..8c5f55e580af10b2caa77aeec825273521520e6c 100644 --- a/module-apps/application-calendar/models/DayEventsModel.cpp +++ b/module-apps/application-calendar/models/DayEventsModel.cpp @@ -11,7 +11,8 @@ #include #include -DayEventsModel::DayEventsModel(app::Application *app) : DatabaseModel(app), application(app) +DayEventsModel::DayEventsModel(app::Application *app) + : DatabaseModel(app), app::AsyncCallbackReceiver{app}, application(app) {} unsigned int DayEventsModel::requestRecordsCount() @@ -27,9 +28,9 @@ unsigned int DayEventsModel::getMinimalItemHeight() const void DayEventsModel::requestRecords(const uint32_t offset, const uint32_t limit) { auto query = std::make_unique(filterFrom, filterTill, offset, limit); - query->setQueryListener( - db::QueryCallback::fromFunction([this](auto response) { return handleQueryResponse(response); })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Events, std::move(query)); + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Events); + task->setCallback([this](auto response) { return handleQueryResponse(response); }); + task->execute(application, this); } gui::ListItem *DayEventsModel::getItem(gui::Order order) diff --git a/module-apps/application-calendar/models/DayEventsModel.hpp b/module-apps/application-calendar/models/DayEventsModel.hpp index fb611628f0b2f8cb86616a41c5435c00908f1e07..2cfac0f24460449c1ac60ae69850820e552031fc 100644 --- a/module-apps/application-calendar/models/DayEventsModel.hpp +++ b/module-apps/application-calendar/models/DayEventsModel.hpp @@ -9,7 +9,9 @@ #include #include -class DayEventsModel : public app::DatabaseModel, public gui::ListItemProvider +class DayEventsModel : public app::DatabaseModel, + public gui::ListItemProvider, + public app::AsyncCallbackReceiver { app::Application *application = nullptr; std::string dayMonthTitle; diff --git a/module-apps/application-calendar/windows/CalendarMainWindow.cpp b/module-apps/application-calendar/windows/CalendarMainWindow.cpp index 5cc49faf80a48c0f16a7a44fd29df8c6cad67034..91b5d3d3cb17a4a9bccc94528ebcb24f9385cac2 100644 --- a/module-apps/application-calendar/windows/CalendarMainWindow.cpp +++ b/module-apps/application-calendar/windows/CalendarMainWindow.cpp @@ -17,7 +17,8 @@ namespace gui { - CalendarMainWindow::CalendarMainWindow(app::Application *app, const std::string &name) : AppWindow(app, name) + CalendarMainWindow::CalendarMainWindow(app::Application *app, const std::string &name) + : AppWindow(app, name), app::AsyncCallbackReceiver{app} { auto appCalendar = dynamic_cast(application); assert(appCalendar != nullptr); @@ -185,9 +186,9 @@ namespace gui assert(application != nullptr); app->setEquivalentToEmptyWindow(EquivalentWindow::AllEventsWindow); auto query = std::make_unique(); - query->setQueryListener( - db::QueryCallback::fromFunction([this](auto response) { return handleQueryResponse(response); })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Events, std::move(query)); + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Events); + task->setCallback([this](auto response) { return handleQueryResponse(response); }); + task->execute(application, this); return true; } @@ -202,9 +203,9 @@ namespace gui auto filter_till = TimePointFromYearMonthDay(date_till); LOG_DEBUG("filter: %s", TimePointToString(filter_till).c_str()); auto query = std::make_unique(filter_from, filter_till); - query->setQueryListener( - db::QueryCallback::fromFunction([this](auto response) { return handleQueryResponse(response); })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Events, std::move(query)); + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Events); + task->setCallback([this](auto response) { return handleQueryResponse(response); }); + task->execute(application, this); } auto CalendarMainWindow::handleQueryResponse(db::QueryResult *queryResult) -> bool diff --git a/module-apps/application-calendar/windows/CalendarMainWindow.hpp b/module-apps/application-calendar/windows/CalendarMainWindow.hpp index f153f9d6bd17ecf6058c8a73a6fda26c0662ab6a..5ae9828e997c2f5539a1385a7a9f1393da291a7f 100644 --- a/module-apps/application-calendar/windows/CalendarMainWindow.hpp +++ b/module-apps/application-calendar/windows/CalendarMainWindow.hpp @@ -22,7 +22,7 @@ namespace db namespace gui { - class CalendarMainWindow : public gui::AppWindow + class CalendarMainWindow : public gui::AppWindow, public app::AsyncCallbackReceiver { bool isDayEmpty[31]; uint32_t offsetFromTop = 0; @@ -40,7 +40,6 @@ namespace gui public: CalendarMainWindow(app::Application *app, const std::string &name); - ~CalendarMainWindow() override = default; void rebuild() override; void refresh(); void filterRequest(); diff --git a/module-apps/application-calllog/ApplicationCallLog.cpp b/module-apps/application-calllog/ApplicationCallLog.cpp index fd68d0abf641d43f107829443505150736621231..b63aa4844d8ff237d27fc489720f25173f7eb5cd 100644 --- a/module-apps/application-calllog/ApplicationCallLog.cpp +++ b/module-apps/application-calllog/ApplicationCallLog.cpp @@ -135,9 +135,9 @@ namespace app DBServiceAPI::GetQuery(this, db::Interface::Name::Notifications, std::make_unique(NotificationsRecord::Key::Calls)); - - return DBServiceAPI::GetQuery( + const auto [succeed, _] = DBServiceAPI::GetQuery( this, db::Interface::Name::Calllog, std::make_unique()); + return succeed; } } /* namespace app */ diff --git a/module-apps/application-desktop/ApplicationDesktop.cpp b/module-apps/application-desktop/ApplicationDesktop.cpp index afcad2722803526cc8c13158e5f14c21a3e06938..352bc2282f740db7514b887f9eca6707a604d5d2 100644 --- a/module-apps/application-desktop/ApplicationDesktop.cpp +++ b/module-apps/application-desktop/ApplicationDesktop.cpp @@ -257,8 +257,9 @@ namespace app bool ApplicationDesktop::requestNotSeenNotifications() { - return DBServiceAPI::GetQuery( + const auto [succeed, _] = DBServiceAPI::GetQuery( this, db::Interface::Name::Notifications, std::make_unique()); + return succeed; } bool ApplicationDesktop::requestNotReadNotifications() diff --git a/module-apps/application-messages/ApplicationMessages.cpp b/module-apps/application-messages/ApplicationMessages.cpp index 640800547adf3970c2eb0a4380209771ef39be9f..4a0c010e7a2c1a808322c4663115db41e9b1cf82 100644 --- a/module-apps/application-messages/ApplicationMessages.cpp +++ b/module-apps/application-messages/ApplicationMessages.cpp @@ -38,7 +38,7 @@ namespace app { ApplicationMessages::ApplicationMessages(std::string name, std::string parent, StartInBackground startInBackground) - : Application(name, parent, startInBackground, 4096 * 2) + : Application(name, parent, startInBackground, 4096 * 2), AsyncCallbackReceiver{this} { busChannels.push_back(sys::BusChannels::ServiceDBNotifications); addActionReceiver(manager::actions::CreateSms, [this](auto &&data) { @@ -51,9 +51,6 @@ namespace app }); } - ApplicationMessages::~ApplicationMessages() - {} - // Invoked upon receiving data message sys::MessagePointer ApplicationMessages::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) { @@ -84,26 +81,8 @@ namespace app // handle database response if (resp != nullptr) { handled = true; - switch (resp->responseTo) { - case MessageType::DBThreadGetLimitOffset: - [[fallthrough]]; - case MessageType::DBSMSTemplateGetLimitOffset: - if (getCurrentWindow()->onDatabaseMessage(resp)) { - refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); - } - break; - case MessageType::DBQuery: - if (auto queryResponse = dynamic_cast(resp)) { - auto result = queryResponse->getResult(); - if (result && result->hasListener()) { - if (result->handle()) { - refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); - } - } - } - break; - default: - break; + if (auto command = callbackStorage->getCallback(resp); command->execute()) { + refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); } } @@ -193,7 +172,8 @@ namespace app LOG_DEBUG("Removing thread: %" PRIu32, record->ID); auto query = std::make_unique(record->contactID, true); - query->setQueryListener(db::QueryCallback::fromFunction([this, record](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Contact); + task->setCallback([this, record](auto response) { auto result = dynamic_cast(response); if (result != nullptr) { const auto &contact = result->getResult(); @@ -206,8 +186,9 @@ namespace app return true; } return false; - })); - return DBServiceAPI::GetQuery(this, db::Interface::Name::Contact, std::move(query)); + }); + task->execute(this, this); + return true; } bool ApplicationMessages::onRemoveSmsThreadConfirmed(const ThreadRecord &record) @@ -216,7 +197,8 @@ namespace app using db::query::ThreadRemoveResult; auto query = std::make_unique(record.ID); - query->setQueryListener(db::QueryCallback::fromFunction([this, threadId = record.ID](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMSThread); + task->setCallback([this, threadId = record.ID](auto response) { const auto result = dynamic_cast(response); if ((result != nullptr) && result->success()) { switchWindow(gui::name::window::main_window); @@ -224,12 +206,8 @@ namespace app } LOG_ERROR("ThreadRemove id=%" PRIu32 " failed", threadId); return false; - })); - - if (const auto ok = DBServiceAPI::GetQuery(this, db::Interface::Name::SMSThread, std::move(query)); !ok) { - LOG_ERROR("Unable to query DBServiceAPI"); - return false; - } + }); + task->execute(this, this); return true; } @@ -255,11 +233,13 @@ namespace app using db::query::ThreadGetByIDResult; auto query = std::make_unique(record.ID); - query->setQueryListener(db::QueryCallback::fromFunction([this, record](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMS); + task->setCallback([this, record](auto response) { auto result = dynamic_cast(response); if (result != nullptr && result->getResults()) { auto query = std::make_unique(record.threadID); - query->setQueryListener(db::QueryCallback::fromFunction([this](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMSThread); + task->setCallback([this](auto response) { const auto result = dynamic_cast(response); if (result != nullptr) { const auto thread = result->getRecord(); @@ -272,14 +252,15 @@ namespace app return true; } return false; - })); - return DBServiceAPI::GetQuery(this, db::Interface::Name::SMSThread, std::move(query)); + }); + task->execute(this, this); + return true; } LOG_ERROR("sSMSRemove id=%" PRIu32 " failed", record.ID); return false; - })); - - return DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::move(query)); + }); + task->execute(this, this); + return true; } bool ApplicationMessages::searchEmpty(const std::string &query) @@ -320,7 +301,9 @@ namespace app record.date = utils::time::getCurrentTimestamp().getTime(); using db::query::SMSUpdate; - return DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::make_unique(record)); + const auto [succeed, _] = + DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::make_unique(record)); + return succeed; } std::pair ApplicationMessages::createDraft(const utils::PhoneNumber::View &number, @@ -335,14 +318,17 @@ namespace app record.date = utils::time::getCurrentTimestamp().getTime(); using db::query::SMSAdd; - const auto success = DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::make_unique(record)); + const auto [success, _] = + DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::make_unique(record)); return std::make_pair(record, success); } bool ApplicationMessages::removeDraft(const SMSRecord &record) { using db::query::SMSRemove; - return DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::make_unique(record.ID)); + const auto [succeed, _] = + DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::make_unique(record.ID)); + return succeed; } bool ApplicationMessages::sendSms(const utils::PhoneNumber::View &number, const UTF8 &body) @@ -358,7 +344,9 @@ namespace app record.date = utils::time::getCurrentTimestamp().getTime(); using db::query::SMSAdd; - return DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::make_unique(record)); + const auto [succeed, _] = + DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::make_unique(record)); + return succeed; } bool ApplicationMessages::resendSms(const SMSRecord &record) @@ -370,7 +358,9 @@ namespace app // the the bottom, but this is correct using db::query::SMSUpdate; - return DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::make_unique(resendRecord)); + const auto [succeed, _] = + DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::make_unique(resendRecord)); + return succeed; } bool ApplicationMessages::handleSendSmsFromThread(const utils::PhoneNumber::View &number, const UTF8 &body) diff --git a/module-apps/application-messages/ApplicationMessages.hpp b/module-apps/application-messages/ApplicationMessages.hpp index fcc011d39cbdf2bfffdb6965a18f5f8882f68243..e4d49d662f17caef6108b02f64f938429ae63fd6 100644 --- a/module-apps/application-messages/ApplicationMessages.hpp +++ b/module-apps/application-messages/ApplicationMessages.hpp @@ -35,13 +35,12 @@ namespace app inline constexpr auto name_messages = "ApplicationMessages"; - class ApplicationMessages : public app::Application + class ApplicationMessages : public app::Application, public app::AsyncCallbackReceiver { public: ApplicationMessages(std::string name = name_messages, std::string parent = {}, StartInBackground startInBackground = {false}); - virtual ~ApplicationMessages(); sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override; sys::ReturnCodes InitHandler() override; diff --git a/module-apps/application-messages/models/BaseThreadsRecordModel.cpp b/module-apps/application-messages/models/BaseThreadsRecordModel.cpp index 9873b0095c0239ac12fe82fe3b6ea77aee55c2c5..70f13d1be6cbe15d05bd6da66e148645f2956f8b 100644 --- a/module-apps/application-messages/models/BaseThreadsRecordModel.cpp +++ b/module-apps/application-messages/models/BaseThreadsRecordModel.cpp @@ -21,8 +21,3 @@ bool BaseThreadsRecordModel::updateRecords(std::vector records list->onProviderDataUpdate(); return true; } - -void BaseThreadsRecordModel::requestRecords(uint32_t offset, uint32_t limit) -{ - DBServiceAPI::ThreadGetLimitOffset(application, offset, limit); -} diff --git a/module-apps/application-messages/models/BaseThreadsRecordModel.hpp b/module-apps/application-messages/models/BaseThreadsRecordModel.hpp index 3205fd7cfb947201ec2ad88cd270ac6515d742d1..c6a232b455835e9756a36b4d88de6ae538936805 100644 --- a/module-apps/application-messages/models/BaseThreadsRecordModel.hpp +++ b/module-apps/application-messages/models/BaseThreadsRecordModel.hpp @@ -33,7 +33,6 @@ class BaseThreadsRecordModel : public app::DatabaseModel, publ unsigned int requestRecordsCount() override; bool updateRecords(std::vector records) override; - void requestRecords(const uint32_t offset, const uint32_t limit) override; app::Application *getApplication(void) { diff --git a/module-apps/application-messages/models/SMSTemplateModel.cpp b/module-apps/application-messages/models/SMSTemplateModel.cpp index 903a7417af4cff33ee793d1ab384e3330adaa7f5..f85ad421fcd5bc56364b15809f1d7a0b99e731d1 100644 --- a/module-apps/application-messages/models/SMSTemplateModel.cpp +++ b/module-apps/application-messages/models/SMSTemplateModel.cpp @@ -8,7 +8,7 @@ #include #include -SMSTemplateModel::SMSTemplateModel(app::Application *app) : DatabaseModel(app) +SMSTemplateModel::SMSTemplateModel(app::Application *app) : DatabaseModel(app), app::AsyncCallbackReceiver{app} {} unsigned int SMSTemplateModel::requestRecordsCount() @@ -56,9 +56,9 @@ gui::ListItem *SMSTemplateModel::getItem(gui::Order order) void SMSTemplateModel::requestRecords(const uint32_t offset, const uint32_t limit) { auto query = std::make_unique(offset, limit); - query->setQueryListener( - db::QueryCallback::fromFunction([this](auto response) { return handleQueryResponse(response); })); - DBServiceAPI::GetQuery(application, db::Interface::Name::SMSTemplate, std::move(query)); + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMSTemplate); + task->setCallback([this](auto response) { return handleQueryResponse(response); }); + task->execute(application, this); } auto SMSTemplateModel::handleQueryResponse(db::QueryResult *queryResult) -> bool diff --git a/module-apps/application-messages/models/SMSTemplateModel.hpp b/module-apps/application-messages/models/SMSTemplateModel.hpp index f3714e9a634f6bbeacecad7859ee43e09f85e637..d7419beea6117ae5e9eb24836e78349740e25874 100644 --- a/module-apps/application-messages/models/SMSTemplateModel.hpp +++ b/module-apps/application-messages/models/SMSTemplateModel.hpp @@ -9,12 +9,13 @@ #include #include -class SMSTemplateModel : public app::DatabaseModel, public gui::ListItemProvider +class SMSTemplateModel : public app::DatabaseModel, + public gui::ListItemProvider, + public app::AsyncCallbackReceiver { public: SMSTemplateModel() = delete; SMSTemplateModel(app::Application *app); - virtual ~SMSTemplateModel() = default; unsigned int requestRecordsCount() override; bool updateRecords(std::vector records) override; diff --git a/module-apps/application-messages/models/SMSThreadModel.cpp b/module-apps/application-messages/models/SMSThreadModel.cpp index 54019fd7bde505d79ba43b246d6a5be54e874ac1..4761df0118aa41023565fbb87b822288c2012e06 100644 --- a/module-apps/application-messages/models/SMSThreadModel.cpp +++ b/module-apps/application-messages/models/SMSThreadModel.cpp @@ -12,7 +12,7 @@ #include "SMSThreadModel.hpp" #include "ListView.hpp" -SMSThreadModel::SMSThreadModel(app::Application *app) : DatabaseModel(app) +SMSThreadModel::SMSThreadModel(app::Application *app) : DatabaseModel(app), app::AsyncCallbackReceiver{app} { smsInput = new gui::SMSInputWidget(application); } @@ -52,9 +52,9 @@ unsigned int SMSThreadModel::requestRecordsCount() void SMSThreadModel::requestRecords(uint32_t offset, uint32_t limit) { auto query = std::make_unique(smsThreadID, offset, limit, numberID); - query->setQueryListener( - db::QueryCallback::fromFunction([this](auto response) { return handleQueryResponse(response); })); - DBServiceAPI::GetQuery(application, db::Interface::Name::SMS, std::move(query)); + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMS); + task->setCallback([this](auto response) { return handleQueryResponse(response); }); + task->execute(application, this); } bool SMSThreadModel::updateRecords(std::vector records) diff --git a/module-apps/application-messages/models/SMSThreadModel.hpp b/module-apps/application-messages/models/SMSThreadModel.hpp index f223b472b2403e86b99d6815cbfc0a23c9f61e85..9c1abf9757300af7c3ee450e886a8c08cc80f615 100644 --- a/module-apps/application-messages/models/SMSThreadModel.hpp +++ b/module-apps/application-messages/models/SMSThreadModel.hpp @@ -9,7 +9,9 @@ #include "Interface/SMSRecord.hpp" #include -class SMSThreadModel : public app::DatabaseModel, public gui::ListItemProvider +class SMSThreadModel : public app::DatabaseModel, + public gui::ListItemProvider, + public app::AsyncCallbackReceiver { public: unsigned int smsThreadID = 0; diff --git a/module-apps/application-messages/models/ThreadsModel.cpp b/module-apps/application-messages/models/ThreadsModel.cpp index 8d3b70978df54294aed8c561677439bfa1e81cde..3d8ced58220a529fc88be1bfd7143c84e903b6f9 100644 --- a/module-apps/application-messages/models/ThreadsModel.cpp +++ b/module-apps/application-messages/models/ThreadsModel.cpp @@ -15,7 +15,7 @@ #include #include -ThreadsModel::ThreadsModel(app::Application *app) : BaseThreadsRecordModel(app) +ThreadsModel::ThreadsModel(app::Application *app) : BaseThreadsRecordModel(app), app::AsyncCallbackReceiver{app} {} auto ThreadsModel::getMinimalItemHeight() const -> unsigned int @@ -66,9 +66,9 @@ auto ThreadsModel::getItem(gui::Order order) -> gui::ListItem * void ThreadsModel::requestRecords(uint32_t offset, uint32_t limit) { auto query = std::make_unique(offset, limit); - query->setQueryListener( - db::QueryCallback::fromFunction([this](auto response) { return handleQueryResponse(response); })); - DBServiceAPI::GetQuery(getApplication(), db::Interface::Name::SMSThread, std::move(query)); + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMSThread); + task->setCallback([this](auto response) { return handleQueryResponse(response); }); + task->execute(getApplication(), this); } auto ThreadsModel::handleQueryResponse(db::QueryResult *queryResult) -> bool diff --git a/module-apps/application-messages/models/ThreadsModel.hpp b/module-apps/application-messages/models/ThreadsModel.hpp index 9e9215511f68e0bf533297b73fcc048a3a8defc7..1c7c75dbd3b6886e85c92aaa665318949162f5c9 100644 --- a/module-apps/application-messages/models/ThreadsModel.hpp +++ b/module-apps/application-messages/models/ThreadsModel.hpp @@ -6,7 +6,7 @@ #include #include "BaseThreadsRecordModel.hpp" -class ThreadsModel : public BaseThreadsRecordModel +class ThreadsModel : public BaseThreadsRecordModel, public app::AsyncCallbackReceiver { public: explicit ThreadsModel(app::Application *app); diff --git a/module-apps/application-messages/models/ThreadsSearchResultsModel.cpp b/module-apps/application-messages/models/ThreadsSearchResultsModel.cpp index c3e605d66500c1e7bc653a0ac49b0db0007298e2..b7c630a716afe1b4cf0a77cf63da4d522ce94d86 100644 --- a/module-apps/application-messages/models/ThreadsSearchResultsModel.cpp +++ b/module-apps/application-messages/models/ThreadsSearchResultsModel.cpp @@ -14,7 +14,8 @@ namespace gui::model { - ThreadsSearchResultsModel::ThreadsSearchResultsModel(app::Application *app) : BaseThreadsRecordModel(app) + ThreadsSearchResultsModel::ThreadsSearchResultsModel(app::Application *app) + : BaseThreadsRecordModel(app), app::AsyncCallbackReceiver{app} {} auto ThreadsSearchResultsModel::getMinimalItemHeight() const -> unsigned int @@ -45,9 +46,9 @@ namespace gui::model { if (std::string(textToSearch).compare("") != 0) { auto query = std::make_unique(textToSearch, offset, limit); - query->setQueryListener( - db::QueryCallback::fromFunction([this](auto response) { return handleQueryResponse(response); })); - DBServiceAPI::GetQuery(getApplication(), db::Interface::Name::SMSThread, std::move(query)); + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMSThread); + task->setCallback([this](auto response) { return handleQueryResponse(response); }); + task->execute(application, this); } } diff --git a/module-apps/application-messages/models/ThreadsSearchResultsModel.hpp b/module-apps/application-messages/models/ThreadsSearchResultsModel.hpp index 91554c9a2dbd57c934cb386917875833ea429c92..fba720cdc40dd12e9e5334d79df3e6520072a7d0 100644 --- a/module-apps/application-messages/models/ThreadsSearchResultsModel.hpp +++ b/module-apps/application-messages/models/ThreadsSearchResultsModel.hpp @@ -9,7 +9,7 @@ namespace gui::model { - class ThreadsSearchResultsModel : public BaseThreadsRecordModel + class ThreadsSearchResultsModel : public BaseThreadsRecordModel, public app::AsyncCallbackReceiver { UTF8 textToSearch; diff --git a/module-apps/application-messages/windows/MessagesMainWindow.cpp b/module-apps/application-messages/windows/MessagesMainWindow.cpp index 27065e8c10ecf11ff6fd55d90758471b75b4c2ea..c0473a6fd87855b003bed9c35280f0f3962dbfe9 100644 --- a/module-apps/application-messages/windows/MessagesMainWindow.cpp +++ b/module-apps/application-messages/windows/MessagesMainWindow.cpp @@ -26,7 +26,8 @@ namespace gui { - MessagesMainWindow::MessagesMainWindow(app::Application *app) : AppWindow(app, gui::name::window::main_window) + MessagesMainWindow::MessagesMainWindow(app::Application *app) + : AppWindow(app, gui::name::window::main_window), app::AsyncCallbackReceiver{app} { buildInterface(); } @@ -112,7 +113,8 @@ namespace gui if (pdata != nullptr) { using db::query::ThreadGetByContactID; auto query = std::make_unique(pdata->result->ID); - query->setQueryListener(db::QueryCallback::fromFunction([app = application](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Contact); + task->setCallback([app = application](auto response) { using db::query::ThreadGetByContactIDResult; const auto result = dynamic_cast(response); if ((result != nullptr) && result->getRecord().has_value()) { @@ -123,8 +125,8 @@ namespace gui } LOG_FATAL("No thread and thread not created!"); return false; - })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Contact, std::move(query)); + }); + task->execute(application, this); } } diff --git a/module-apps/application-messages/windows/MessagesMainWindow.hpp b/module-apps/application-messages/windows/MessagesMainWindow.hpp index e17d5c33b0f4508fd7f42128e2bbe33c1085b1b3..cfc4323c3f66fd8d4f7a9f6fef53d7630b690e9d 100644 --- a/module-apps/application-messages/windows/MessagesMainWindow.hpp +++ b/module-apps/application-messages/windows/MessagesMainWindow.hpp @@ -17,7 +17,7 @@ namespace gui { - class MessagesMainWindow : public AppWindow + class MessagesMainWindow : public AppWindow, public app::AsyncCallbackReceiver { protected: Image *leftArrowImage = nullptr; diff --git a/module-apps/application-messages/windows/NewMessage.cpp b/module-apps/application-messages/windows/NewMessage.cpp index 2b4e341bf017c9e65a904ff2a4f867a3a370ef14..cf84e4ee1f3e19660d7cacab0aa80e3ab81ed9ed 100644 --- a/module-apps/application-messages/windows/NewMessage.cpp +++ b/module-apps/application-messages/windows/NewMessage.cpp @@ -49,7 +49,8 @@ namespace gui std::unique_ptr NewMessageWindow::memento = std::make_unique(); - NewMessageWindow::NewMessageWindow(app::Application *app) : AppWindow(app, name::window::new_sms) + NewMessageWindow::NewMessageWindow(app::Application *app) + : AppWindow(app, name::window::new_sms), app::AsyncCallbackReceiver{app} { buildInterface(); } @@ -311,7 +312,8 @@ namespace gui { auto number = contactRecord.numbers.front().number; auto query = std::make_unique(contactRecord.ID); - query->setQueryListener(db::QueryCallback::fromFunction([this, number](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMSThread); + task->setCallback([this, number](auto response) { const auto result = dynamic_cast(response); if (result == nullptr) { return false; @@ -323,15 +325,16 @@ namespace gui return true; } return addDraftToExistingThread(thread->ID, number, message->getText()); - })); - - return DBServiceAPI::GetQuery(application, db::Interface::Name::SMSThread, std::move(query)); + }); + task->execute(application, this); + return true; } auto NewMessageWindow::addDraft(const utils::PhoneNumber &number) -> bool { auto query = std::make_unique(number.getView()); - query->setQueryListener(db::QueryCallback::fromFunction([this, number](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMSThread); + task->setCallback([this, number](auto response) { const auto result = dynamic_cast(response); if (result == nullptr) { return false; @@ -343,9 +346,9 @@ namespace gui return true; } return addDraftToExistingThread(thread.ID, number.getView(), message->getText()); - })); - - return DBServiceAPI::GetQuery(application, db::Interface::Name::SMSThread, std::move(query)); + }); + task->execute(application, this); + return true; } auto NewMessageWindow::addDraftToExistingThread(unsigned int threadId, @@ -353,7 +356,8 @@ namespace gui const UTF8 &text) -> bool { auto query = std::make_unique(threadId); - query->setQueryListener(db::QueryCallback::fromFunction([this, number](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMS); + task->setCallback([this, number](auto response) { const auto result = dynamic_cast(response); if (result == nullptr) { return false; @@ -366,9 +370,9 @@ namespace gui } storeMessageDraft(number, message->getText()); return true; - })); - - return DBServiceAPI::GetQuery(application, db::Interface::Name::SMS, std::move(query)); + }); + task->execute(application, this); + return true; } void NewMessageWindow::storeMessageDraft(const utils::PhoneNumber::View &number, const UTF8 &text) diff --git a/module-apps/application-messages/windows/NewMessage.hpp b/module-apps/application-messages/windows/NewMessage.hpp index 2cb34e9ce14c9cd0c40dc2399dc20b434ba4d8bf..ef84f85996e459ca079396e9627f74a2af368b93 100644 --- a/module-apps/application-messages/windows/NewMessage.hpp +++ b/module-apps/application-messages/windows/NewMessage.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -14,7 +15,7 @@ namespace gui { - class NewMessageWindow : public AppWindow + class NewMessageWindow : public AppWindow, public app::AsyncCallbackReceiver { public: explicit NewMessageWindow(app::Application *app); diff --git a/module-apps/application-messages/windows/SMSThreadViewWindow.cpp b/module-apps/application-messages/windows/SMSThreadViewWindow.cpp index 080a08bf3359564e822c6855aaabdc38ad67b0e6..8a74e0154e345db350fb44e7a683ba4896c57ed9 100644 --- a/module-apps/application-messages/windows/SMSThreadViewWindow.cpp +++ b/module-apps/application-messages/windows/SMSThreadViewWindow.cpp @@ -24,7 +24,8 @@ namespace gui { SMSThreadViewWindow::SMSThreadViewWindow(app::Application *app) - : AppWindow(app, name::window::thread_view), smsModel{std::make_shared(this->application)} + : AppWindow(app, name::window::thread_view), app::AsyncCallbackReceiver{app}, + smsModel{std::make_shared(app)} { AppWindow::buildInterface(); setTitle(utils::localize.get("app_messages_title_main")); @@ -124,9 +125,9 @@ namespace gui auto SMSThreadViewWindow::requestContactName(unsigned int contactID) -> void { auto query = std::make_unique(contactID, true); - query->setQueryListener(db::QueryCallback::fromFunction( - [this](auto response) { return handleContactNameQueryResponse(response); })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Contact, std::move(query)); + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Contact); + task->setCallback([this](auto response) { return handleContactNameQueryResponse(response); }); + task->execute(application, this); } auto SMSThreadViewWindow::handleContactNameQueryResponse(db::QueryResult *queryResult) -> bool diff --git a/module-apps/application-messages/windows/SMSThreadViewWindow.hpp b/module-apps/application-messages/windows/SMSThreadViewWindow.hpp index 612631dfcc93803bc876a86bd2b741c59b2969c1..b02fc18a9f59ff8d303ed57da46b98331aa533fa 100644 --- a/module-apps/application-messages/windows/SMSThreadViewWindow.hpp +++ b/module-apps/application-messages/windows/SMSThreadViewWindow.hpp @@ -14,7 +14,7 @@ namespace gui { - class SMSThreadViewWindow : public AppWindow + class SMSThreadViewWindow : public AppWindow, public app::AsyncCallbackReceiver { private: std::shared_ptr smsModel; diff --git a/module-apps/application-notes/ApplicationNotes.cpp b/module-apps/application-notes/ApplicationNotes.cpp index 3f9082168ad34fd48e59e4c9ce84c432890729bb..a61f03733e1dcbb1c4f993a5a08c9f8909102085 100644 --- a/module-apps/application-notes/ApplicationNotes.cpp +++ b/module-apps/application-notes/ApplicationNotes.cpp @@ -56,18 +56,8 @@ namespace app } if (resp != nullptr) { - switch (resp->responseTo) { - case MessageType::DBQuery: - if (auto queryResponse = dynamic_cast(resp); queryResponse != nullptr) { - if (auto result = queryResponse->getResult(); result && result->hasListener()) { - if (result->handle()) { - refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); - } - } - } - break; - default: - break; + if (auto command = callbackStorage->getCallback(resp); command->execute()) { + refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); } return msgHandled(); } diff --git a/module-apps/application-notes/model/NotesRepository.cpp b/module-apps/application-notes/model/NotesRepository.cpp index dbe72ad205e9d33ab1f86b02b9ca763c5274cd63..77b44a09f76027395d9d2be8b9242e0037a214ed 100644 --- a/module-apps/application-notes/model/NotesRepository.cpp +++ b/module-apps/application-notes/model/NotesRepository.cpp @@ -12,13 +12,15 @@ namespace app::notes { - NotesDBRepository::NotesDBRepository(Application *application) : application{application} + NotesDBRepository::NotesDBRepository(Application *application) + : app::AsyncCallbackReceiver{application}, application{application} {} void NotesDBRepository::get(std::uint32_t offset, std::uint32_t limit, const OnGetCallback &callback) { auto query = std::make_unique(offset, limit); - query->setQueryListener(db::QueryCallback::fromFunction([callback](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Notes); + task->setCallback([callback](auto response) { auto result = dynamic_cast(response); if (result == nullptr) { return false; @@ -27,14 +29,15 @@ namespace app::notes callback(result->getRecords(), result->getCount()); } return true; - })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Notes, std::move(query)); + }); + task->execute(application, this); } void NotesDBRepository::getByText(const std::string &text, const OnFilteredCallback &callback) { auto query = std::make_unique(text); - query->setQueryListener(db::QueryCallback::fromFunction([callback](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Notes); + task->setCallback([callback](auto response) { auto result = dynamic_cast(response); if (result == nullptr) { return false; @@ -43,14 +46,15 @@ namespace app::notes callback(result->getRecords()); } return true; - })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Notes, std::move(query)); + }); + task->execute(application, this); } void NotesDBRepository::save(const NotesRecord ¬e, const OnResultCallback &callback) { auto query = std::make_unique(note); - query->setQueryListener(db::QueryCallback::fromFunction([callback](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Notes); + task->setCallback([callback](auto response) { auto result = dynamic_cast(response); if (result == nullptr) { return false; @@ -59,14 +63,15 @@ namespace app::notes callback(result->succeed()); } return true; - })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Notes, std::move(query)); + }); + task->execute(application, this); } void NotesDBRepository::remove(const NotesRecord ¬e, const OnResultCallback &callback) { auto query = std::make_unique(note.ID); - query->setQueryListener(db::QueryCallback::fromFunction([callback](auto response) { + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Notes); + task->setCallback([callback](auto response) { auto result = dynamic_cast(response); if (result == nullptr) { return false; @@ -75,7 +80,7 @@ namespace app::notes callback(result->succeed()); } return true; - })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Notes, std::move(query)); + }); + task->execute(application, this); } } // namespace app::notes diff --git a/module-apps/application-notes/model/NotesRepository.hpp b/module-apps/application-notes/model/NotesRepository.hpp index b773a1d1ef11bba5c40702e22d0df5931e68f9e7..c882054b10b2b22ab8d829064f88c2867180092f 100644 --- a/module-apps/application-notes/model/NotesRepository.hpp +++ b/module-apps/application-notes/model/NotesRepository.hpp @@ -26,7 +26,7 @@ namespace app::notes virtual void remove(const NotesRecord ¬e, const OnResultCallback &callback) = 0; }; - class NotesDBRepository : public AbstractNotesRepository + class NotesDBRepository : public AbstractNotesRepository, public app::AsyncCallbackReceiver { public: explicit NotesDBRepository(Application *application); diff --git a/module-apps/application-phonebook/ApplicationPhonebook.cpp b/module-apps/application-phonebook/ApplicationPhonebook.cpp index 48169c93027f7943394e3b2224c62a4badbbcbc5..a3dc7d4bf11d554523c7ce120ff74654f256dae9 100644 --- a/module-apps/application-phonebook/ApplicationPhonebook.cpp +++ b/module-apps/application-phonebook/ApplicationPhonebook.cpp @@ -80,22 +80,8 @@ namespace app // handle database response if (resp != nullptr) { handled = true; - switch (resp->responseTo) { - case MessageType::DBQuery: { - - if (auto queryResponse = dynamic_cast(resp)) { - auto result = queryResponse->getResult(); - - if (result->hasListener()) { - if (result->handle()) { - refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); - } - } - } - - } break; - default: - break; + if (auto command = callbackStorage->getCallback(resp); command->execute()) { + refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); } } diff --git a/module-apps/application-phonebook/models/PhonebookModel.cpp b/module-apps/application-phonebook/models/PhonebookModel.cpp index 6d48eb4996bcbd05c38e7808f7b107c807577129..31ae7692766a0c7a1d120d6a78effd01cd857bc2 100644 --- a/module-apps/application-phonebook/models/PhonebookModel.cpp +++ b/module-apps/application-phonebook/models/PhonebookModel.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include "ListView.hpp" #include "PhonebookModel.hpp" @@ -24,8 +26,8 @@ PhonebookModel::PhonebookModel(app::Application *app, std::string filter, std::uint32_t groupFilter, std::uint32_t displayMode) - : DatabaseModel(app), queryFilter(std::move(filter)), queryGroupFilter(std::move(groupFilter)), - queryDisplayMode(std::move(displayMode)) + : DatabaseModel(app), app::AsyncCallbackReceiver{app}, queryFilter(std::move(filter)), + queryGroupFilter(std::move(groupFilter)), queryDisplayMode(std::move(displayMode)) {} auto PhonebookModel::requestRecordsCount() -> unsigned int @@ -60,9 +62,9 @@ void PhonebookModel::requestRecords(const uint32_t offset, const uint32_t limit) { auto query = std::make_unique(offset, limit, queryFilter, queryGroupFilter, queryDisplayMode); - query->setQueryListener( - db::QueryCallback::fromFunction([this](auto response) { return handleQueryResponse(response); })); - DBServiceAPI::GetQuery(application, db::Interface::Name::Contact, std::move(query)); + auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Contact); + task->setCallback([this](auto response) { return handleQueryResponse(response); }); + task->execute(application, this); } auto PhonebookModel::requestLetterMap() -> ContactsMapData diff --git a/module-apps/application-phonebook/models/PhonebookModel.hpp b/module-apps/application-phonebook/models/PhonebookModel.hpp index 8c6ce62942c1371962a642de324f668bbf6b02a4..a04436e608607e4fa8dc7bcb150ad053096d408c 100644 --- a/module-apps/application-phonebook/models/PhonebookModel.hpp +++ b/module-apps/application-phonebook/models/PhonebookModel.hpp @@ -17,7 +17,9 @@ #include -class PhonebookModel : public app::DatabaseModel, public gui::ListItemProvider +class PhonebookModel : public app::DatabaseModel, + public gui::ListItemProvider, + public app::AsyncCallbackReceiver { private: std::string queryFilter; @@ -31,7 +33,6 @@ class PhonebookModel : public app::DatabaseModel, public gui::Lis std::string filter = "", std::uint32_t groupFilter = 0, std::uint32_t displayMode = 0); - ~PhonebookModel() override = default; // virtual methods from DatabaseModel auto updateRecords(std::vector records) -> bool override; diff --git a/module-apps/application-settings-new/ApplicationSettings.cpp b/module-apps/application-settings-new/ApplicationSettings.cpp index cd12605b2412cb001d064e5935f6fc4d4f423f1c..316fce80457077e3d40620eee31571dc26f468c8 100644 --- a/module-apps/application-settings-new/ApplicationSettings.cpp +++ b/module-apps/application-settings-new/ApplicationSettings.cpp @@ -96,7 +96,7 @@ namespace app currentWindow->rebuild(); } } - else if (auto responseStatusMsg = dynamic_cast(msgl); + else if (auto responseStatusMsg = dynamic_cast<::message::bluetooth::ResponseStatus *>(msgl); nullptr != responseStatusMsg) { if (gui::window::name::bluetooth == getCurrentWindow()->getName()) { auto btStatusData = std::make_unique(responseStatusMsg->getStatus()); diff --git a/module-apps/application-settings-new/windows/BluetoothWindow.cpp b/module-apps/application-settings-new/windows/BluetoothWindow.cpp index d3fbc8a258a35250724e2af491a47b28b8e5fac6..4d90e6bde0c28ad1165ef9ff4360baee6f21ecb3 100644 --- a/module-apps/application-settings-new/windows/BluetoothWindow.cpp +++ b/module-apps/application-settings-new/windows/BluetoothWindow.cpp @@ -18,7 +18,7 @@ namespace gui topBar->setActive(TopBar::Elements::BATTERY, false); topBar->setActive(TopBar::Elements::SIM, false); sys::Bus::SendUnicast( - std::make_shared(), service::name::bluetooth, application); + std::make_shared<::message::bluetooth::RequestStatus>(), service::name::bluetooth, application); } void BluetoothWindow::onBeforeShow(ShowMode mode, SwitchData *data) @@ -116,10 +116,10 @@ namespace gui btStatus.state = BluetoothStatus::BluetoothState::Off; } btStatus.visibility = isPhoneVisibilitySwitchOn; - message::bluetooth::SetStatus setStatus(btStatus); + ::message::bluetooth::SetStatus setStatus(btStatus); sys::Bus::SendUnicast( - std::make_shared(setStatus), service::name::bluetooth, application); + std::make_shared<::message::bluetooth::SetStatus>(setStatus), service::name::bluetooth, application); } void BluetoothWindow::rebuildOptionList() diff --git a/module-apps/tests/CMakeLists.txt b/module-apps/tests/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..bcfdcef47734657f06678bb60572a4718d8edff1 --- /dev/null +++ b/module-apps/tests/CMakeLists.txt @@ -0,0 +1,9 @@ +add_catch2_executable( + NAME + callback-storage-test + SRCS + tests-main.cpp + test-CallbackStorage.cpp + LIBS + ${PROJECT_NAME} +) diff --git a/module-apps/tests/test-CallbackStorage.cpp b/module-apps/tests/test-CallbackStorage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c974cafb3d16037c74715d44421423e2d0a1ed4 --- /dev/null +++ b/module-apps/tests/test-CallbackStorage.cpp @@ -0,0 +1,70 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include + +#include "CallbackStorage.hpp" + +#include + +using namespace app; + +class TestCallbacksDeleter : public AsyncCallbacksDeleter +{ + public: + explicit TestCallbacksDeleter(CallbackStorage &storage) : storage{storage} + {} + + void cancelCallbacks(AsyncCallbackReceiver *receiver) override + { + storage.removeAll(receiver); + } + + private: + CallbackStorage &storage; +}; + +class TestReceiver : public AsyncCallbackReceiver +{ + public: + TestReceiver(TestCallbacksDeleter *deleter = nullptr) : AsyncCallbackReceiver(deleter) + {} +}; + +TEST_CASE("CallbackStorageTests") +{ + CallbackStorage storage; + + SECTION("Get callback") + { + constexpr auto MessageId = 1; + sys::ResponseMessage response{}; + response.uniID = MessageId; + + TestReceiver receiver; + storage.registerCallback(MessageId, &receiver); + REQUIRE(storage.containsCallbackFor(&response)); + + [[maybe_unused]] auto callback = storage.getCallback(&response); + REQUIRE(!storage.containsCallbackFor(&response)); + } + + SECTION("Remove receiver") + { + constexpr auto MessageId = 2; + sys::ResponseMessage response{}; + response.uniID = MessageId; + + { + TestCallbacksDeleter deleter{storage}; + TestReceiver receiver{&deleter}; + + storage.registerCallback(MessageId, &receiver); + REQUIRE(storage.containsCallbackFor(&response)); + } + + REQUIRE(!storage.containsCallbackFor(&response)); + [[maybe_unused]] auto callback = storage.getCallback(&response); + REQUIRE(callback->execute() == false); + } +} diff --git a/module-apps/tests/tests-main.cpp b/module-apps/tests/tests-main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8a6ad34dd8ce49475f75635a46116fd419dafda9 --- /dev/null +++ b/module-apps/tests/tests-main.cpp @@ -0,0 +1,5 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file +#include diff --git a/module-services/service-cellular/ServiceCellular.cpp b/module-services/service-cellular/ServiceCellular.cpp index 4c91da86f91700c90bcf9ee5026925e26980d09f..66c8186f699a102e29829a0f8ee81c8bb12c44dd 100644 --- a/module-services/service-cellular/ServiceCellular.cpp +++ b/module-services/service-cellular/ServiceCellular.cpp @@ -1820,7 +1820,8 @@ bool ServiceCellular::dbAddSMSRecord(const SMSRecord &record) onSMSReceived(); return true; })); - return DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::move(query)); + const auto [succeed, _] = DBServiceAPI::GetQuery(this, db::Interface::Name::SMS, std::move(query)); + return succeed; } void ServiceCellular::onSMSReceived() diff --git a/module-services/service-db/DBServiceAPI.cpp b/module-services/service-db/DBServiceAPI.cpp index 32029366a82e1b4d1f0d6c32c31c65f4a4bce15e..dd6c7f9641b866009c5dfeb3f660e15a4bffc0b3 100644 --- a/module-services/service-db/DBServiceAPI.cpp +++ b/module-services/service-db/DBServiceAPI.cpp @@ -54,17 +54,6 @@ auto DBServiceAPI::ThreadGetByNumber(sys::Service *serv, return nullptr; } -auto DBServiceAPI::ThreadGetLimitOffset(sys::Service *serv, uint32_t offset, uint32_t limit) -> bool -{ - std::shared_ptr msg = std::make_shared(MessageType::DBThreadGetLimitOffset); - msg->offset = offset; - msg->limit = limit; - - sys::Bus::SendUnicast(msg, service::name::db, serv); - - return true; -} - auto DBServiceAPI::ThreadGetCount(sys::Service *serv, EntryState state) -> uint32_t { auto msg = std::make_shared(state); diff --git a/module-services/service-db/DBServiceAPI_GetByQuery.cpp b/module-services/service-db/DBServiceAPI_GetByQuery.cpp index 9a565943d7c3579700a0e59dd568c37c8547d36a..16bdea1c90310b0360a0eceba4d6cbf6769b0bf9 100644 --- a/module-services/service-db/DBServiceAPI_GetByQuery.cpp +++ b/module-services/service-db/DBServiceAPI_GetByQuery.cpp @@ -22,10 +22,13 @@ namespace sys class Service; } // namespace sys -bool DBServiceAPI::GetQuery(sys::Service *serv, db::Interface::Name database, std::unique_ptr query) +std::pair DBServiceAPI::GetQuery(sys::Service *serv, + db::Interface::Name database, + std::unique_ptr query) { auto msg = std::make_shared(database, std::move(query)); - return sys::Bus::SendUnicast(msg, service::name::db, serv); + const auto isSuccess = sys::Bus::SendUnicast(msg, service::name::db, serv); + return std::make_pair(isSuccess, msg->uniID); } sys::SendResult DBServiceAPI::GetQueryWithReply(sys::Service *serv, diff --git a/module-services/service-db/ServiceDB.cpp b/module-services/service-db/ServiceDB.cpp index 6752a1019e14ace1273eea44f84bb7f9a91da720..a455b997ee54b4938e760c83ac659cc2e6597737 100644 --- a/module-services/service-db/ServiceDB.cpp +++ b/module-services/service-db/ServiceDB.cpp @@ -209,15 +209,6 @@ sys::MessagePointer ServiceDB::DataReceivedHandler(sys::DataMessage *msgl, sys:: sendUpdateNotification(db::Interface::Name::SMSThread, db::Query::Type::Delete); } break; - case MessageType::DBThreadGetLimitOffset: { - auto time = utils::time::Scoped("DBThreadGetLimitOffset"); - DBThreadMessage *msg = reinterpret_cast(msgl); - auto ret = threadRecordInterface->GetLimitOffset(msg->offset, msg->limit); - LOG_INFO("Thread get limit offset"); - responseMsg = - std::make_shared(std::move(ret), true, msg->limit, msg->offset, ret->size()); - } break; - case MessageType::DBThreadGetCount: { auto *msg = static_cast(msgl); auto time = utils::time::Scoped("DBThreadGetCountMessage"); diff --git a/module-services/service-db/service-db/DBServiceAPI.hpp b/module-services/service-db/service-db/DBServiceAPI.hpp index 6f998895289761326d06e7ce04e286b1484e5a2a..ee25be38efc4266e74ad6cb92e680b43278ba34d 100644 --- a/module-services/service-db/service-db/DBServiceAPI.hpp +++ b/module-services/service-db/service-db/DBServiceAPI.hpp @@ -52,10 +52,18 @@ class DBServiceAPI static auto ThreadGetByNumber(sys::Service *serv, const utils::PhoneNumber::View &phoneNumber, std::uint32_t timeout = DefaultTimeoutInMs) -> std::unique_ptr; - static auto ThreadGetLimitOffset(sys::Service *serv, uint32_t offset, uint32_t limit) -> bool; static auto ThreadGetCount(sys::Service *serv, EntryState state = EntryState::ALL) -> uint32_t; - static auto GetQuery(sys::Service *serv, db::Interface::Name database, std::unique_ptr query) -> bool; + /** + * Queries the database. + * @param serv Sender service. + * @param database Target database name. + * @param query Query. + * @return A pair of: a flag that indicates whether query send was successful, and a message identifier that common + * for the query and its response. + */ + static auto GetQuery(sys::Service *serv, db::Interface::Name database, std::unique_ptr query) + -> std::pair; static auto GetQueryWithReply(sys::Service *serv, db::Interface::Name database, std::unique_ptr query, diff --git a/module-services/service-desktop/endpoints/calendarEvents/CalendarEventsHelper.cpp b/module-services/service-desktop/endpoints/calendarEvents/CalendarEventsHelper.cpp index 93cb7c1d6d288aa99c50d39e62573ee3941f772b..c8d0d282655d1d56d424152509e2e24eb72ef317 100644 --- a/module-services/service-desktop/endpoints/calendarEvents/CalendarEventsHelper.cpp +++ b/module-services/service-desktop/endpoints/calendarEvents/CalendarEventsHelper.cpp @@ -184,7 +184,7 @@ auto CalendarEventsHelper::requestDataFromDB(Context &context) -> sys::ReturnCod context); query->setQueryListener(std::move(listener)); - auto ret = DBServiceAPI::GetQuery(ownerServicePtr, db::Interface::Name::Events, std::move(query)); + auto [ret, _] = DBServiceAPI::GetQuery(ownerServicePtr, db::Interface::Name::Events, std::move(query)); if (ret) { return sys::ReturnCodes::Success; @@ -280,7 +280,9 @@ auto CalendarEventsHelper::createDBEntry(Context &context) -> sys::ReturnCodes context); query->setQueryListener(std::move(listener)); - ret = ret && DBServiceAPI::GetQuery(ownerServicePtr, db::Interface::Name::Events, std::move(query)); + const auto [succeed, _] = + DBServiceAPI::GetQuery(ownerServicePtr, db::Interface::Name::Events, std::move(query)); + ret = ret && succeed; } if (ret) { @@ -315,7 +317,9 @@ auto CalendarEventsHelper::updateDBEntry(Context &context) -> sys::ReturnCodes context); query->setQueryListener(std::move(listener)); - ret = ret && DBServiceAPI::GetQuery(ownerServicePtr, db::Interface::Name::Events, std::move(query)); + const auto [succeed, _] = + DBServiceAPI::GetQuery(ownerServicePtr, db::Interface::Name::Events, std::move(query)); + ret = ret && succeed; } if (ret) { return sys::ReturnCodes::Success; @@ -341,7 +345,7 @@ auto CalendarEventsHelper::deleteDBEntry(Context &context) -> sys::ReturnCodes context); query->setQueryListener(std::move(listener)); - auto ret = DBServiceAPI::GetQuery(ownerServicePtr, db::Interface::Name::Events, std::move(query)); + auto [ret, _] = DBServiceAPI::GetQuery(ownerServicePtr, db::Interface::Name::Events, std::move(query)); if (ret) { return sys::ReturnCodes::Success; diff --git a/module-services/service-time/timeEvents/CalendarTimeEvents.cpp b/module-services/service-time/timeEvents/CalendarTimeEvents.cpp index 44eab66f20ebbba1472600957268949e64874ebe..88292d363ae5889bfe38b49510682938cd4a5333 100644 --- a/module-services/service-time/timeEvents/CalendarTimeEvents.cpp +++ b/module-services/service-time/timeEvents/CalendarTimeEvents.cpp @@ -43,9 +43,11 @@ namespace stm filterTill = filterFrom; } - return DBServiceAPI::GetQuery(service(), - db::Interface::Name::Events, - std::make_unique(filterFrom, filterTill)); + const auto [succeed, _] = + DBServiceAPI::GetQuery(service(), + db::Interface::Name::Events, + std::make_unique(filterFrom, filterTill)); + return succeed; } uint32_t CalendarTimeEvents::calcToNextEventInterval(std::unique_ptr nextEventQueryResult) @@ -74,8 +76,9 @@ namespace stm bool CalendarTimeEvents::sendEventFiredQuery() { eventRecord.reminder_fired = TimePointNow(); - return DBServiceAPI::GetQuery( + const auto [succeed, _] = DBServiceAPI::GetQuery( service(), db::Interface::Name::Events, std::make_unique(eventRecord)); + return succeed; } void CalendarTimeEvents::invokeEvent()