mirror of
https://github.com/logos-co/logos-cpp-sdk.git
synced 2026-08-31 01:31:10 +00:00
Merge pull request #1 from logos-co/support_local
Add support for a 'local' mode that does not use separate processes. required for some platforms such as mobile
This commit is contained in:
@@ -23,6 +23,8 @@ set(SDK_SOURCES
|
||||
module_proxy.h
|
||||
token_manager.cpp
|
||||
token_manager.h
|
||||
logos_mode.h
|
||||
plugin_registry.h
|
||||
)
|
||||
|
||||
# Create the SDK library as STATIC instead of SHARED
|
||||
@@ -56,5 +58,7 @@ install(FILES
|
||||
logos_api_provider.h
|
||||
module_proxy.h
|
||||
token_manager.h
|
||||
logos_mode.h
|
||||
plugin_registry.h
|
||||
DESTINATION include
|
||||
)
|
||||
+86
-35
@@ -2,6 +2,8 @@
|
||||
#include "module_proxy.h"
|
||||
#include "logos_api_client.h"
|
||||
#include "token_manager.h"
|
||||
#include "logos_mode.h"
|
||||
#include "plugin_registry.h"
|
||||
#include <QRemoteObjectNode>
|
||||
#include <QRemoteObjectReplica>
|
||||
#include <QRemoteObjectPendingCall>
|
||||
@@ -18,8 +20,13 @@ LogosAPIConsumer::LogosAPIConsumer(const QString& module_to_talk_to, const QStri
|
||||
, m_connected(false)
|
||||
, m_token_manager(token_manager)
|
||||
{
|
||||
m_node = new QRemoteObjectNode(this);
|
||||
connectToRegistry();
|
||||
if (LogosModeConfig::isLocal()) {
|
||||
qDebug() << "LogosAPIConsumer: Using Local mode - skipping QRemoteObjectNode";
|
||||
m_connected = true;
|
||||
} else {
|
||||
m_node = new QRemoteObjectNode(this);
|
||||
connectToRegistry();
|
||||
}
|
||||
}
|
||||
|
||||
LogosAPIConsumer::~LogosAPIConsumer()
|
||||
@@ -37,16 +44,27 @@ LogosAPIConsumer::~LogosAPIConsumer()
|
||||
QObject* LogosAPIConsumer::requestObject(const QString& objectName, int timeoutMs)
|
||||
{
|
||||
qDebug() << "LogosAPIConsumer: Requesting object:" << objectName << "at" << QTime::currentTime().toString("hh:mm:ss.zzz");
|
||||
if (!m_connected) {
|
||||
qWarning() << "LogosAPIConsumer: Not connected to registry. Cannot request object:" << objectName;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (objectName.isEmpty()) {
|
||||
qWarning() << "LogosAPIConsumer: Object name cannot be empty";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (LogosModeConfig::isLocal()) {
|
||||
QObject* plugin = PluginRegistry::getPlugin<QObject>(objectName);
|
||||
if (!plugin) {
|
||||
qWarning() << "LogosAPIConsumer: Plugin not found in registry:" << objectName;
|
||||
return nullptr;
|
||||
}
|
||||
qDebug() << "LogosAPIConsumer: Successfully found plugin:" << objectName;
|
||||
return plugin;
|
||||
}
|
||||
|
||||
if (!m_connected) {
|
||||
qWarning() << "LogosAPIConsumer: Not connected to registry. Cannot request object:" << objectName;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
qDebug() << "LogosAPIConsumer: Requesting object:" << objectName;
|
||||
|
||||
// Acquire the dynamic replica
|
||||
@@ -80,6 +98,11 @@ QString LogosAPIConsumer::registryUrl() const
|
||||
|
||||
bool LogosAPIConsumer::reconnect()
|
||||
{
|
||||
if (LogosModeConfig::isLocal()) {
|
||||
m_connected = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
qDebug() << "LogosAPIConsumer: Attempting to reconnect to registry:" << m_registryUrl;
|
||||
|
||||
// Disconnect first if already connected
|
||||
@@ -134,25 +157,30 @@ QVariant LogosAPIConsumer::invokeRemoteMethod(const QString& authToken, const QS
|
||||
|
||||
// This method handles both ModuleProxy-wrapped modules (template_module, package_manager)
|
||||
// and direct remote object calls for other modules
|
||||
QObject* replica = requestObject(objectName, timeoutMs);
|
||||
if (!replica) {
|
||||
qWarning() << "LogosAPIConsumer: Failed to acquire replica for object:" << objectName;
|
||||
QObject* plugin = requestObject(objectName, timeoutMs);
|
||||
if (!plugin) {
|
||||
qWarning() << "LogosAPIConsumer: Failed to acquire plugin/replica for object:" << objectName;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// Try to cast to ModuleProxy first (in case the replica is a wrapped module)
|
||||
ModuleProxy* moduleProxy = qobject_cast<ModuleProxy*>(replica);
|
||||
ModuleProxy* moduleProxy = qobject_cast<ModuleProxy*>(plugin);
|
||||
if (moduleProxy) {
|
||||
QVariant result = moduleProxy->callRemoteMethod(authToken, methodName, args);
|
||||
delete replica;
|
||||
if (!LogosModeConfig::isLocal()) {
|
||||
delete plugin;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Fallback: use QMetaObject::invokeMethod directly
|
||||
// Note: Remote objects' callRemoteMethod returns QRemoteObjectPendingCall, not QVariant
|
||||
if (LogosModeConfig::isLocal()) {
|
||||
qWarning() << "LogosAPIConsumer: Local mode requires ModuleProxy-wrapped objects";
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// Remote mode: callRemoteMethod returns QRemoteObjectPendingCall, not QVariant
|
||||
QRemoteObjectPendingCall pendingCall;
|
||||
bool success = QMetaObject::invokeMethod(
|
||||
replica,
|
||||
plugin,
|
||||
"callRemoteMethod",
|
||||
Qt::DirectConnection,
|
||||
Q_RETURN_ARG(QRemoteObjectPendingCall, pendingCall),
|
||||
@@ -163,13 +191,13 @@ QVariant LogosAPIConsumer::invokeRemoteMethod(const QString& authToken, const QS
|
||||
|
||||
if (!success) {
|
||||
qWarning() << "LogosAPIConsumer: Failed to invoke callRemoteMethod on replica for object:" << objectName;
|
||||
delete replica;
|
||||
delete plugin;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// Wait for the result
|
||||
pendingCall.waitForFinished(timeoutMs);
|
||||
delete replica;
|
||||
delete plugin;
|
||||
|
||||
if (!pendingCall.isFinished() || pendingCall.error() != QRemoteObjectPendingCall::NoError) {
|
||||
qWarning() << "LogosAPIConsumer: Remote callRemoteMethod failed or timed out:" << pendingCall.error();
|
||||
@@ -236,17 +264,30 @@ bool LogosAPIConsumer::informModuleToken(const QString& authToken, const QString
|
||||
{
|
||||
qDebug() << "LogosAPIConsumer: Informing module token for module:" << moduleName << "with token:" << token;
|
||||
|
||||
// Request the ModuleProxy object
|
||||
QObject* replica = requestObject("capability_module", 20000);
|
||||
if (!replica) {
|
||||
qWarning() << "LogosAPIConsumer: Failed to acquire replica for object:" << "capability_module";
|
||||
QObject* plugin = requestObject("capability_module", 20000);
|
||||
if (!plugin) {
|
||||
qWarning() << "LogosAPIConsumer: Failed to acquire plugin/replica for object: capability_module";
|
||||
return false;
|
||||
}
|
||||
|
||||
ModuleProxy* moduleProxy = qobject_cast<ModuleProxy*>(plugin);
|
||||
if (moduleProxy) {
|
||||
bool result = moduleProxy->informModuleToken(authToken, moduleName, token);
|
||||
qDebug() << "LogosAPIConsumer: informModuleToken completed with result:" << result;
|
||||
if (!LogosModeConfig::isLocal()) {
|
||||
delete plugin;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (LogosModeConfig::isLocal()) {
|
||||
qWarning() << "LogosAPIConsumer: Local mode requires ModuleProxy-wrapped objects";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use QRemoteObjectPendingCall similar to invokeRemoteMethod
|
||||
QRemoteObjectPendingCall pendingCall;
|
||||
bool success = QMetaObject::invokeMethod(
|
||||
replica,
|
||||
plugin,
|
||||
"informModuleToken",
|
||||
Qt::DirectConnection,
|
||||
Q_RETURN_ARG(QRemoteObjectPendingCall, pendingCall),
|
||||
@@ -257,13 +298,12 @@ bool LogosAPIConsumer::informModuleToken(const QString& authToken, const QString
|
||||
|
||||
if (!success) {
|
||||
qWarning() << "LogosAPIConsumer: Failed to invoke informModuleToken on replica";
|
||||
delete replica;
|
||||
delete plugin;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait for the result
|
||||
pendingCall.waitForFinished(20000);
|
||||
delete replica;
|
||||
delete plugin;
|
||||
|
||||
if (!pendingCall.isFinished() || pendingCall.error() != QRemoteObjectPendingCall::NoError) {
|
||||
qWarning() << "LogosAPIConsumer: Remote informModuleToken failed or timed out:" << pendingCall.error();
|
||||
@@ -280,17 +320,29 @@ bool LogosAPIConsumer::informModuleToken_module(const QString& authToken, const
|
||||
{
|
||||
qDebug() << "LogosAPIConsumer: Informing module token for module:" << moduleName << "with token:" << token;
|
||||
|
||||
// Request the ModuleProxy object
|
||||
QObject* replica = requestObject(originModule, 20000);
|
||||
if (!replica) {
|
||||
qWarning() << "LogosAPIConsumer: Failed to acquire replica for object:" << "capability_module";
|
||||
QObject* plugin = requestObject(originModule, 20000);
|
||||
if (!plugin) {
|
||||
qWarning() << "LogosAPIConsumer: Failed to acquire plugin/replica for object:" << originModule;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use QRemoteObjectPendingCall similar to invokeRemoteMethod
|
||||
ModuleProxy* moduleProxy = qobject_cast<ModuleProxy*>(plugin);
|
||||
if (moduleProxy) {
|
||||
bool result = moduleProxy->informModuleToken(authToken, moduleName, token);
|
||||
qDebug() << "LogosAPIConsumer: informModuleToken completed with result:" << result;
|
||||
if (!LogosModeConfig::isLocal()) {
|
||||
delete plugin;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (LogosModeConfig::isLocal()) {
|
||||
qWarning() << "LogosAPIConsumer: Local mode requires ModuleProxy-wrapped objects";
|
||||
return false;
|
||||
}
|
||||
QRemoteObjectPendingCall pendingCall;
|
||||
bool success = QMetaObject::invokeMethod(
|
||||
replica,
|
||||
plugin,
|
||||
"informModuleToken",
|
||||
Qt::DirectConnection,
|
||||
Q_RETURN_ARG(QRemoteObjectPendingCall, pendingCall),
|
||||
@@ -301,13 +353,12 @@ bool LogosAPIConsumer::informModuleToken_module(const QString& authToken, const
|
||||
|
||||
if (!success) {
|
||||
qWarning() << "LogosAPIConsumer: Failed to invoke informModuleToken on replica";
|
||||
delete replica;
|
||||
delete plugin;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait for the result
|
||||
pendingCall.waitForFinished(20000);
|
||||
delete replica;
|
||||
delete plugin;
|
||||
|
||||
if (!pendingCall.isFinished() || pendingCall.error() != QRemoteObjectPendingCall::NoError) {
|
||||
qWarning() << "LogosAPIConsumer: Remote informModuleToken failed or timed out:" << pendingCall.error();
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <QMap>
|
||||
#include <functional>
|
||||
|
||||
#include "logos_mode.h"
|
||||
|
||||
class QRemoteObjectNode;
|
||||
class TokenManager;
|
||||
|
||||
|
||||
+25
-11
@@ -1,6 +1,8 @@
|
||||
#include "logos_api_provider.h"
|
||||
#include "module_proxy.h"
|
||||
#include "logos_api.h"
|
||||
#include "logos_mode.h"
|
||||
#include "plugin_registry.h"
|
||||
#include <QRemoteObjectRegistryHost>
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
@@ -16,6 +18,9 @@ LogosAPIProvider::LogosAPIProvider(const QString& module_name, QObject *parent)
|
||||
|
||||
LogosAPIProvider::~LogosAPIProvider()
|
||||
{
|
||||
if (LogosModeConfig::isLocal() && !m_registeredObjectName.isEmpty()) {
|
||||
PluginRegistry::unregisterPlugin(m_registeredObjectName);
|
||||
}
|
||||
// QRemoteObjectRegistryHost will be deleted automatically as it's a child object
|
||||
// ModuleProxy will be deleted automatically as it's a child object
|
||||
}
|
||||
@@ -60,20 +65,29 @@ bool LogosAPIProvider::registerObject(const QString& name, QObject* object)
|
||||
m_moduleProxy = new ModuleProxy(object, this);
|
||||
object = m_moduleProxy;
|
||||
|
||||
if (!m_registryHost) {
|
||||
m_registryHost = new QRemoteObjectRegistryHost(QUrl(m_registryUrl));
|
||||
if (!m_registryHost) {
|
||||
qCritical() << "LogosAPIProvider: Failed to create registry host";
|
||||
return false;
|
||||
}
|
||||
qDebug() << "LogosAPIProvider: Created registry host with URL:" << m_registryUrl;
|
||||
}
|
||||
bool success = false;
|
||||
|
||||
bool success = m_registryHost->enableRemoting(object, name);
|
||||
if (success) {
|
||||
if (LogosModeConfig::isLocal()) {
|
||||
PluginRegistry::registerPlugin(object, name);
|
||||
m_registeredObjectName = name;
|
||||
success = true;
|
||||
qDebug() << "LogosAPIProvider: Successfully registered object with name:" << name;
|
||||
} else {
|
||||
qCritical() << "LogosAPIProvider: Failed to register object with name:" << name;
|
||||
if (!m_registryHost) {
|
||||
m_registryHost = new QRemoteObjectRegistryHost(QUrl(m_registryUrl));
|
||||
if (!m_registryHost) {
|
||||
qCritical() << "LogosAPIProvider: Failed to create registry host";
|
||||
return false;
|
||||
}
|
||||
qDebug() << "LogosAPIProvider: Created registry host with URL:" << m_registryUrl;
|
||||
}
|
||||
|
||||
success = m_registryHost->enableRemoting(object, name);
|
||||
if (success) {
|
||||
qDebug() << "LogosAPIProvider: Successfully registered object with name:" << name;
|
||||
} else {
|
||||
qCritical() << "LogosAPIProvider: Failed to register object with name:" << name;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
class QRemoteObjectRegistryHost;
|
||||
class ModuleProxy;
|
||||
|
||||
#include "logos_mode.h"
|
||||
|
||||
/**
|
||||
* @brief LogosAPIProvider handles registering objects for remote access
|
||||
*
|
||||
@@ -72,6 +74,7 @@ private:
|
||||
QString m_registryUrl;
|
||||
QMap<QString, QString> m_tokens;
|
||||
ModuleProxy* m_moduleProxy;
|
||||
QString m_registeredObjectName;
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef LOGOS_MODE_H
|
||||
#define LOGOS_MODE_H
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
/**
|
||||
* @brief LogosMode defines the communication mode for the SDK
|
||||
*
|
||||
* - Remote: Uses QRemoteObjects for inter-process communication (desktop apps)
|
||||
* - Local: Uses in-process PluginRegistry (mobile apps, single process)
|
||||
*/
|
||||
enum class LogosMode {
|
||||
Remote, // Default: Use QRemoteObjects (IPC)
|
||||
Local // Use in-process PluginRegistry
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief LogosModeConfig provides global mode configuration
|
||||
*
|
||||
* Set the mode once at application startup before creating any LogosAPI instances.
|
||||
*
|
||||
* Example usage:
|
||||
* LogosModeConfig::setMode(LogosMode::Local); // For mobile apps
|
||||
* LogosAPI api("my_module"); // Will use local mode
|
||||
*/
|
||||
namespace LogosModeConfig {
|
||||
|
||||
/**
|
||||
* @brief Get the current mode (internal storage)
|
||||
* @return Reference to the static mode variable
|
||||
*/
|
||||
inline LogosMode& modeStorage() {
|
||||
static LogosMode mode = LogosMode::Remote; // Default to Remote
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the SDK communication mode
|
||||
* @param mode The mode to use (Remote or Local)
|
||||
*
|
||||
* Call this before creating any LogosAPI instances.
|
||||
*/
|
||||
inline void setMode(LogosMode mode) {
|
||||
modeStorage() = mode;
|
||||
qDebug() << "LogosModeConfig: Mode set to" << (mode == LogosMode::Local ? "Local" : "Remote");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current SDK communication mode
|
||||
* @return The current mode
|
||||
*/
|
||||
inline LogosMode getMode() {
|
||||
return modeStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the SDK is in Local mode
|
||||
* @return true if Local mode, false if Remote mode
|
||||
*/
|
||||
inline bool isLocal() {
|
||||
return modeStorage() == LogosMode::Local;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the SDK is in Remote mode
|
||||
* @return true if Remote mode, false if Local mode
|
||||
*/
|
||||
inline bool isRemote() {
|
||||
return modeStorage() == LogosMode::Remote;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // LOGOS_MODE_H
|
||||
@@ -186,6 +186,12 @@ QVariant ModuleProxy::callRemoteMethod(const QString& authToken, const QString&
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// TODO: review this. note this method is part of ModuleProxy
|
||||
if (methodName == "getPluginMethods" && args.isEmpty()) {
|
||||
qDebug() << "ModuleProxy: Handling getPluginMethods() directly";
|
||||
return QVariant(getPluginMethods());
|
||||
}
|
||||
|
||||
qDebug() << "ModuleProxy: Auth token received:" << authToken;
|
||||
qDebug() << "ModuleProxy: Calling method" << methodName << "on module" << m_module << "with args:" << args;
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
#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
|
||||
+5
-1
@@ -27,12 +27,16 @@ pkgs.stdenv.mkDerivation {
|
||||
# Install cpp headers and sources
|
||||
for file in logos_api.cpp logos_api.h logos_api_client.cpp logos_api_client.h \
|
||||
logos_api_consumer.cpp logos_api_consumer.h logos_api_provider.cpp logos_api_provider.h \
|
||||
token_manager.cpp token_manager.h module_proxy.cpp module_proxy.h; do
|
||||
token_manager.cpp token_manager.h module_proxy.cpp module_proxy.h logos_mode.h; do
|
||||
if [ -f cpp/$file ]; then
|
||||
cp cpp/$file $out/include/cpp/
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -f cpp/logos_mode.h ]; then
|
||||
cp cpp/logos_mode.h $out/include/
|
||||
fi
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user