// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md #include "CallbackStorage.hpp" #include "MessageType.hpp" #include namespace app { CallbackStorage::CallbackEntry::CallbackEntry(RequestId id, AsyncCallbackReceiver::Ptr receiver, std::optional callbackFunction, ReceiverBehavior receiverBehavior) noexcept : id{id}, receiver{receiver}, callbackFunction(callbackFunction), receiverBehavior(receiverBehavior) {} auto CallbackStorage::getCallback(sys::ResponseMessage *response) -> std::unique_ptr { if (auto cbEntry = getCallbackEntryFor(response); cbEntry) { remove(response); return toCallback(response, (*cbEntry).callbackFunction); } return std::make_unique(); } auto CallbackStorage::getCallbackEntryFor(sys::ResponseMessage *response) const noexcept -> std::optional { auto it = std::find_if( entries.begin(), entries.end(), [response](const auto &entry) { return entry->id == response->uniID; }); return it != entries.end() ? std::optional(**it) : std::nullopt; } 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::optional callbackFunction) -> std::unique_ptr { if (response->responseTo == MessageType::DBQuery) { if (auto queryResponse = dynamic_cast(response); queryResponse != nullptr) { return std::make_unique(queryResponse); } } if (callbackFunction) { return std::make_unique(response, *callbackFunction); } return std::make_unique(); } void CallbackStorage::registerCallback(RequestId id, AsyncCallbackReceiver::Ptr receiver, std::optional &&callback, ReceiverBehavior receiverBehavior) { entries.push_back(std::make_unique(id, receiver, std::move(callback), receiverBehavior)); } 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()); } bool CallbackStorage::checkBlockingCloseRequests() const noexcept { return std::any_of(entries.begin(), entries.end(), [](const auto &request) { return request->receiverBehavior == ReceiverBehavior::WaitForResponseToClose; }); } } // namespace app