From 2810efded7429ba8c039ed1fb3ba670cf03294f6 Mon Sep 17 00:00:00 2001 From: hasslesstech Date: Wed, 15 Jul 2026 17:51:48 +0300 Subject: [PATCH] Introduce MBFT::Module and MBFT::ModuleAPI --- modules/Module.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++ modules/Module.h | 31 +++++++++++++ modules/ModuleAPI.cpp | 28 ++++++++++++ modules/ModuleAPI.h | 17 +++++++ 4 files changed, 180 insertions(+) create mode 100644 modules/Module.cpp create mode 100644 modules/Module.h create mode 100644 modules/ModuleAPI.cpp create mode 100644 modules/ModuleAPI.h diff --git a/modules/Module.cpp b/modules/Module.cpp new file mode 100644 index 0000000..fe1f103 --- /dev/null +++ b/modules/Module.cpp @@ -0,0 +1,104 @@ +#include + +#include + +#include "modules/Module.h" + +MBFT::Module::Module(const std::string& module_path) + : module_path(module_path) +{ + load(); +} + +MBFT::Module::~Module(void) +{ + unload(); +} + +void MBFT::Module::load(void) { + if (module_shared_object != nullptr) + { + return; + } + + module_shared_object = dlopen(module_path.c_str(), RTLD_NOW); + + if (module_shared_object == NULL) + { + std::cout << __FILE__ << ": Failed to open library " << module_path << "\n"; + std::cout << __FILE__ << ": " << dlerror() << "\n"; + module_shared_object = nullptr; + return; + } + + loaded_init = reinterpret_cast(dlsym(module_shared_object, "init")); + if (loaded_init == NULL) + { + std::cout << __FILE__ << ": No function init() in " << module_path << "\n"; + loaded_init = nullptr; + } + + loaded_process = reinterpret_cast(dlsym(module_shared_object, "process")); + if (loaded_process == NULL) + { + std::cout << __FILE__ << ": No function process() in " << module_path << "\n"; + loaded_process = nullptr; + } + + init(); +} + +void MBFT::Module::unload(void) +{ + if (module_shared_object == nullptr) + { + return; + } + + dlclose(module_shared_object); + module_shared_object = nullptr; + + loaded_init = nullptr; + loaded_process = nullptr; +} + +void MBFT::Module::reload(void) +{ + unload(); + load(); +} + +void MBFT::Module::disable(void) +{ + enabled = false; +} + +void MBFT::Module::enable(void) +{ + enabled = true; +} + +void MBFT::Module::init(void) +{ + if (loaded_init == nullptr) + { + return; + } + + loaded_init(); +} + +void MBFT::Module::process(MBFT::ModuleAPI& api, const MBFT::InboundMessage& message) +{ + if (!enabled) + { + return; + } + + if (loaded_process == nullptr) + { + return; + } + + loaded_process(api, message); +} diff --git a/modules/Module.h b/modules/Module.h new file mode 100644 index 0000000..3a1e4dc --- /dev/null +++ b/modules/Module.h @@ -0,0 +1,31 @@ +#pragma once + +#include "core/inc/Types.h" +#include "modules/ModuleAPI.h" + +namespace MBFT +{ + class Module + { + private: + void *module_shared_object{nullptr}; + std::string module_path; + + void (*loaded_init)(void){nullptr}; + void (*loaded_process)(MBFT::ModuleAPI& api, const MBFT::InboundMessage& message){nullptr}; + + bool enabled{true}; + public: + Module(const std::string& module_path); + ~Module(void); + void load(void); + void unload(void); + void reload(void); + + void disable(void); + void enable(void); + + void init(void); + void process(MBFT::ModuleAPI& api, const MBFT::InboundMessage& message); + }; +} diff --git a/modules/ModuleAPI.cpp b/modules/ModuleAPI.cpp new file mode 100644 index 0000000..efbad10 --- /dev/null +++ b/modules/ModuleAPI.cpp @@ -0,0 +1,28 @@ +#include "modules/ModuleAPI.h" + +MBFT::ModuleAPI::ModuleAPI(MBFT::IConnector& c) + : connector(c) +{ + +} + +void MBFT::ModuleAPI::set_context(const MBFT::InboundMessage * const ctx) +{ + this->ctx = const_cast(ctx); +} + +void MBFT::ModuleAPI::v1_respond(const std::string& text) +{ + if (ctx == nullptr) + { + return; + } + + std::shared_ptr new_message = std::make_shared(); + MBFT::OutboundMessage& m = *new_message; + + m.target_chat_id = ctx->chat->id; + m.text = text; + + connector.send(new_message); +} diff --git a/modules/ModuleAPI.h b/modules/ModuleAPI.h new file mode 100644 index 0000000..89f4bfd --- /dev/null +++ b/modules/ModuleAPI.h @@ -0,0 +1,17 @@ +#include "core/inc/Types.h" +#include "connectors/IConnector.h" + +namespace MBFT +{ + class ModuleAPI + { + public: + MBFT::IConnector& connector; + MBFT::InboundMessage *ctx{nullptr}; + public: + ModuleAPI(MBFT::IConnector& c); + void set_context(const MBFT::InboundMessage * const ctx); + + void v1_respond(const std::string& text); + }; +}