diff options
Diffstat (limited to 'include/GFModuleEvent.h')
| -rw-r--r-- | include/GFModuleEvent.h | 236 |
1 files changed, 0 insertions, 236 deletions
diff --git a/include/GFModuleEvent.h b/include/GFModuleEvent.h deleted file mode 100644 index 1ac6614..0000000 --- a/include/GFModuleEvent.h +++ /dev/null @@ -1,236 +0,0 @@ -/** - * Copyright (C) 2021-2024 Saturneric <[email protected]> - * - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GpgFrontend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from - * the gpg4usb project, which is under GPL-3.0-or-later. - * - * All the source code of GpgFrontend was modified and released by - * Saturneric <[email protected]> starting on May 12, 2021. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <GFSDKBasic.h> -#include <GFSDKModule.h> - -#include <QMap> -#include <QString> -#include <functional> - -#include "GFModuleConvert.h" -#include "GFModuleMemory.h" - -/** - * @file GFModuleEvent.h - * @brief Subscribing to events, handling them, and answering them. - * - * A module says what it wants to hear with LISTEN(), declares a handler per - * event with REGISTER_EVENT_HANDLER(), and answers with CB_SUCC() or CB_ERR(). - * The dispatch table in between is generated by - * DEFINE_EXECUTE_API_USING_STANDARD_EVEN_HANDLE_MODEL, which the bootstrap - * macro expands for you -- a module does not normally write it out. - * - * Every one of these expands GFGetModuleID(), which is why that accessor is - * the one piece of generated identity that still exists. - */ - -/** - * @brief This module's identifier. - * - * Declared here because this header's macros are what call it. It is *defined* - * by GF_MODULE_BOOTSTRAP() in exactly one translation unit per module, from - * the identifier in module.json -- so a second copy cannot exist to disagree - * with the signed manifest the host checks it against. - */ -auto GFGetModuleID() -> const char*; - -/** - * @brief The lifecycle functions every module defines. - * - * Written out rather than produced by a macro. `GF_MODULE_API_DECLARE` used to - * expand to eleven of these, six of which described entry points the host - * stopped resolving when the bootstrap table replaced them -- so the - * declarations outlived the functions and nothing noticed, because a - * declaration nobody defines costs nothing until somebody calls it. - * - * GF_MODULE_BOOTSTRAP() adapts these onto the table the host actually uses. - */ -extern "C" { -auto GFRegisterModule() -> int; -auto GFActiveModule() -> int; -auto GFExecuteModule(GFModuleEvent*) -> int; -auto GFDeactivateModule() -> int; -auto GFUnregisterModule() -> int; -} - -/// Subscribe to an event by id. -/// -/// No DUP: SDK arguments are borrowed, so pre-allocating here would leak. -#define LISTEN(event) GFModuleListenEvent(GFGetModuleID(), (event)) - -// ------------------------------------------------------------- conversions - -inline auto ConvertEventParamsToMap(GFModuleEventParam* params) - -> QMap<QString, QString> { - QMap<QString, QString> param_map; - GFModuleEventParam* current = params; - GFModuleEventParam* last; - - while (current != nullptr) { - const auto name = UDUP(current->name); - const auto value = USECDUP(current->value); - - if (!name.isEmpty()) param_map[name] = value; - - last = current; - current = current->next; - GFFreeMemory(last); - } - - return param_map; -} - -inline auto ConvertMapToParams(const QMap<QString, QString>& param_map) - -> GFModuleEventParam* { - GFModuleEventParam* head = nullptr; - GFModuleEventParam* prev = nullptr; -#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) - for (const auto& [key, value] : param_map.asKeyValueRange()) { - auto* param = static_cast<GFModuleEventParam*>( - GFAllocateMemory(sizeof(GFModuleEventParam))); - - param->name = DUP(key.toUtf8()); - param->value = SECDUP(value.toUtf8()); - param->next = nullptr; - - if (prev == nullptr) { - head = param; - } else { - prev->next = param; - } - prev = param; - } -#else - for (auto it = param_map.keyValueBegin(); it != param_map.keyValueEnd(); - ++it) { - auto* param = static_cast<GFModuleEventParam*>( - GFAllocateMemory(sizeof(GFModuleEventParam))); - - param->name = DUP(it->first.toUtf8()); - param->value = SECDUP(it->second.toUtf8()); - param->next = nullptr; - - if (prev == nullptr) { - head = param; - } else { - prev->next = param; - } - prev = param; - } -#endif - - return head; -} - -inline auto ConvertEventToMap(GFModuleEvent* event) -> QMap<QString, QString> { - QMap<QString, QString> event_map; - - event_map["event_id"] = UDUP(event->id); - event_map["trigger_id"] = UDUP(event->trigger_id); - event_map.insert(ConvertEventParamsToMap(event->params)); - - GFFreeMemory(event); - - return event_map; -} - -inline auto ConvertMapToEvent(QMap<QString, QString> event_map) - -> GFModuleEvent* { - auto* event = - static_cast<GFModuleEvent*>(GFAllocateMemory(sizeof(GFModuleEvent))); - - event->id = DUP(event_map["event_id"].toUtf8()); - event->trigger_id = DUP(event_map["trigger_id"].toUtf8()); - event->params = nullptr; - - return event; -} - -// ---------------------------------------------------------------- answering - -inline void CB(const QMap<QString, QString>& event, const char* module, - const QMap<QString, QString>& params) { - GFModuleTriggerModuleEventCallback(ConvertMapToEvent(event), module, - ConvertMapToParams(params)); -} - -#undef CB_SUCC -/// Answer an event with success, and return from the handler. -#define CB_SUCC(event) \ - { \ - CB(event, GFGetModuleID(), {{"ret", "0"}}); \ - return 0; \ - } - -#undef CB_ERR -/// Answer an event with a failure, and return that code from the handler. -#define CB_ERR(event, ret, err) \ - { \ - CB(event, GFGetModuleID(), \ - {{"ret", QString::number(ret)}, {"err", QString(err)}}); \ - return ret; \ - } - -#undef CB_ERR_NO_RET -/// The same, without returning -- for a handler with cleanup still to do. -#define CB_ERR_NO_RET(event, ret, err) \ - { \ - CB(event, GFGetModuleID(), \ - {{"ret", QString::number(ret)}, {"err", QString(err)}}); \ - } - -// ----------------------------------------------------------------- dispatch - -#define EXECUTE_MODULE() \ - auto GFExecuteModule(GFModuleEvent* p_event) -> int { \ - auto event = ConvertEventToMap(p_event); - -#define END_EXECUTE_MODULE() } - -#define DEFINE_EXECUTE_API_USING_STANDARD_EVEN_HANDLE_MODEL \ - EXECUTE_MODULE() { \ - auto event_id = event["event_id"]; \ - auto it = _gr_module_event_handlers.find(event_id); \ - if (it != _gr_module_event_handlers.end()) { \ - return it.value()(event); \ - } \ - CB_ERR(event, -1, QString("unsupported event id: %1").arg(event_id)); \ - } \ - END_EXECUTE_MODULE() - -/// Register a handler for one event id, at static-initialisation time. -#define REGISTER_EVENT_HANDLER(event_id, handler) \ - namespace { \ - auto _gv_register_event_handler_by_id_##event_id = []() -> const bool { \ - _gr_module_event_handlers[#event_id] = handler; \ - return true; \ - }(); \ - } |
