mirror of
https://github.com/logos-co/logos-protocol.git
synced 2026-08-27 20:11:07 +00:00
* Extract the Logos protocol layer from logos-cpp-sdk
Transports (plain TCP/TLS, qt_local, qt_remote/QRO, mock), token manager,
consumer core (LogosAPIClient/LogosAPIConsumer incl. the capability
auto-requestModule flow), ModuleProxy, the abstract LogosProviderObject
interface, and the canonical QVariant<->JSON conversion — now behind the
language-neutral lp_* C ABI (logos_protocol.h) carrying the protocol
semver (LOGOS_PROTOCOL_VERSION_*, lp_protocol_version()).
Bytes crossing the ABI use the lossless {"_bytes": base64url} tagging
(NUL-safe), matching the plain wire encoding.
Provider lp_* surface is compiled groundwork; serving lands with module
authoring.
* consumer: typed requestModule for the capability flow
Port of logos-cpp-sdk master f5a127dd ('use updated capability module',
cpp-sdk#85, Iuri Matias) — the touched files (logos_api_client.cpp,
logos_api_consumer.{h,cpp}) moved into this repo in the P1 extraction.
The capability auto-requestModule path now calls a typed std::string
helper on the consumer (which acquires the capability object directly)
instead of a stringly invokeRemoteMethod round-trip. 111/111 tests.
131 lines
4.3 KiB
C++
131 lines
4.3 KiB
C++
#ifndef PLUGIN_REGISTRY_H
|
|
#define PLUGIN_REGISTRY_H
|
|
|
|
#include <QMap>
|
|
#include <QString>
|
|
#include <QObject>
|
|
#include <QCoreApplication>
|
|
#include <QVariant>
|
|
#include <QDebug>
|
|
#include <QMutex>
|
|
#include <QMutexLocker>
|
|
|
|
/**
|
|
* @brief PluginRegistry provides in-process plugin registration for Local mode
|
|
*
|
|
* This namespace provides functions to register, unregister, and retrieve plugins
|
|
* using QCoreApplication properties. This is used as an alternative to QRemoteObjects
|
|
* for mobile apps that run in a single process.
|
|
*/
|
|
namespace PluginRegistry {
|
|
|
|
// Mutex for thread-safe access to the registry
|
|
inline QMutex& registryMutex() {
|
|
static QMutex mutex;
|
|
return mutex;
|
|
}
|
|
|
|
// Prefix for plugin keys to avoid conflicts with other properties
|
|
inline QString pluginKeyPrefix() {
|
|
return QStringLiteral("logos_plugin_");
|
|
}
|
|
|
|
/**
|
|
* @brief Convert a plugin name to a standardized key
|
|
* @param name The plugin name
|
|
* @return QString The standardized key
|
|
*/
|
|
inline QString toPluginKey(const QString& name) {
|
|
return pluginKeyPrefix() + name.toLower().replace(" ", "_");
|
|
}
|
|
|
|
/**
|
|
* @brief Register a plugin in the application properties
|
|
* @param plugin The plugin object to register
|
|
* @param name The name to register the plugin under
|
|
*/
|
|
inline void registerPlugin(QObject* plugin, const QString& name) {
|
|
if (!plugin) {
|
|
qWarning() << "PluginRegistry: Cannot register null plugin";
|
|
return;
|
|
}
|
|
if (name.isEmpty()) {
|
|
qWarning() << "PluginRegistry: Cannot register plugin with empty name";
|
|
return;
|
|
}
|
|
|
|
QMutexLocker locker(®istryMutex());
|
|
QString pluginKey = toPluginKey(name);
|
|
QCoreApplication::instance()->setProperty(pluginKey.toUtf8().constData(), QVariant::fromValue(plugin));
|
|
qDebug() << "PluginRegistry: Registered plugin with key:" << pluginKey;
|
|
}
|
|
|
|
/**
|
|
* @brief Unregister a plugin from the application properties
|
|
* @param name The name of the plugin to unregister
|
|
* @return bool true if successful
|
|
*/
|
|
inline bool unregisterPlugin(const QString& name) {
|
|
if (name.isEmpty()) {
|
|
qWarning() << "PluginRegistry: Cannot unregister plugin with empty name";
|
|
return false;
|
|
}
|
|
|
|
QMutexLocker locker(®istryMutex());
|
|
QString pluginKey = toPluginKey(name);
|
|
QCoreApplication::instance()->setProperty(pluginKey.toUtf8().constData(), QVariant());
|
|
qDebug() << "PluginRegistry: Unregistered plugin with key:" << pluginKey;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @brief Get a plugin by name with automatic casting to the requested type
|
|
* @param name The name of the plugin to retrieve
|
|
* @return T* Pointer to the plugin, or nullptr if not found
|
|
*/
|
|
template<typename T>
|
|
inline T* getPlugin(const QString& name) {
|
|
if (name.isEmpty()) {
|
|
qWarning() << "PluginRegistry: Cannot get plugin with empty name";
|
|
return nullptr;
|
|
}
|
|
|
|
QMutexLocker locker(®istryMutex());
|
|
QString pluginKey = toPluginKey(name);
|
|
QVariant pluginVariant = QCoreApplication::instance()->property(pluginKey.toUtf8().constData());
|
|
|
|
if (pluginVariant.isValid()) {
|
|
QObject* obj = pluginVariant.value<QObject*>();
|
|
if (obj) {
|
|
T* result = qobject_cast<T*>(obj);
|
|
if (result) {
|
|
qDebug() << "PluginRegistry: Found plugin:" << name;
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
qDebug() << "PluginRegistry: Plugin not found:" << name;
|
|
return nullptr;
|
|
}
|
|
|
|
/**
|
|
* @brief Check if a plugin is registered
|
|
* @param name The name of the plugin to check
|
|
* @return bool true if the plugin is registered
|
|
*/
|
|
inline bool hasPlugin(const QString& name) {
|
|
if (name.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
QMutexLocker locker(®istryMutex());
|
|
QString pluginKey = toPluginKey(name);
|
|
QVariant pluginVariant = QCoreApplication::instance()->property(pluginKey.toUtf8().constData());
|
|
return pluginVariant.isValid() && pluginVariant.value<QObject*>() != nullptr;
|
|
}
|
|
|
|
}
|
|
|
|
#endif // PLUGIN_REGISTRY_H
|