From 5d035677e046db25a91eeceaea4bc328395d10f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 6 Nov 2025 21:15:26 +0100 Subject: [PATCH] Add WebServerResource support for experience plugins --- libnymea-core/experiences/experiencemanager.cpp | 17 ++++++++++++++--- libnymea-core/experiences/experiencemanager.h | 6 +++++- libnymea-core/nymeacore.cpp | 2 +- libnymea-core/servermanager.cpp | 6 ++++-- libnymea/experiences/experienceplugin.cpp | 7 +++++++ libnymea/experiences/experienceplugin.h | 9 +++++++-- 6 files changed, 38 insertions(+), 9 deletions(-) diff --git a/libnymea-core/experiences/experiencemanager.cpp b/libnymea-core/experiences/experiencemanager.cpp index 479ada50..8b0fb746 100644 --- a/libnymea-core/experiences/experiencemanager.cpp +++ b/libnymea-core/experiences/experiencemanager.cpp @@ -24,6 +24,7 @@ #include "experiencemanager.h" #include "experiences/experienceplugin.h" +#include "servermanager.h" #include "jsonrpc/jsonrpcserverimplementation.h" #include "loggingcategories.h" @@ -35,9 +36,12 @@ namespace nymeaserver { -ExperienceManager::ExperienceManager(ThingManager *thingManager, JsonRPCServer *jsonRpcServer, QObject *parent) : QObject(parent), - m_thingManager(thingManager), - m_jsonRpcServer(jsonRpcServer) +ExperienceManager::ExperienceManager(ThingManager *thingManager, JsonRPCServer *jsonRpcServer, ServerManager *serverManager, QObject *parent) : + QObject{parent}, + m_thingManager{thingManager}, + m_jsonRpcServer{jsonRpcServer}, + m_serverManager{serverManager} + { staticMetaObject.invokeMethod(this, "loadPlugins", Qt::QueuedConnection); } @@ -122,6 +126,9 @@ void ExperienceManager::loadExperiencePlugin(const QString &file) plugin->setParent(this); plugin->initPlugin(m_thingManager, m_jsonRpcServer); + if (plugin->webServerResource()) { + m_serverManager->registerWebServerResource(plugin->webServerResource()); + } } void ExperienceManager::loadExperiencePlugin(ExperiencePlugin *experiencePlugin) @@ -130,6 +137,10 @@ void ExperienceManager::loadExperiencePlugin(ExperiencePlugin *experiencePlugin) m_plugins.append(experiencePlugin); experiencePlugin->setParent(this); experiencePlugin->initPlugin(m_thingManager, m_jsonRpcServer); + + if (experiencePlugin->webServerResource()) { + m_serverManager->registerWebServerResource(experiencePlugin->webServerResource()); + } } } diff --git a/libnymea-core/experiences/experiencemanager.h b/libnymea-core/experiences/experiencemanager.h index f3a0ad86..47eb3439 100644 --- a/libnymea-core/experiences/experiencemanager.h +++ b/libnymea-core/experiences/experiencemanager.h @@ -33,11 +33,13 @@ class ThingManager; namespace nymeaserver { +class ServerManager; + class ExperienceManager : public QObject { Q_OBJECT public: - explicit ExperienceManager(ThingManager *thingManager, JsonRPCServer *jsonRpcServer, QObject *parent = nullptr); + explicit ExperienceManager(ThingManager *thingManager, JsonRPCServer *jsonRpcServer, ServerManager *serverManager, QObject *parent = nullptr); QList plugins() const; @@ -50,6 +52,8 @@ private slots: private: ThingManager *m_thingManager = nullptr; JsonRPCServer *m_jsonRpcServer = nullptr; + ServerManager *m_serverManager = nullptr; + QList m_plugins; QStringList pluginSearchDirs() const; diff --git a/libnymea-core/nymeacore.cpp b/libnymea-core/nymeacore.cpp index 85600fca..30d1191d 100644 --- a/libnymea-core/nymeacore.cpp +++ b/libnymea-core/nymeacore.cpp @@ -159,7 +159,7 @@ void NymeaCore::init(const QStringList &additionalInterfaces, bool disableLogEng m_serverManager->jsonServer()->registerHandler(new DebugHandler(m_serverManager->jsonServer())); qCDebug(dcCore()) << "Loading experiences"; - m_experienceManager = new ExperienceManager(m_thingManager, m_serverManager->jsonServer(), this); + m_experienceManager = new ExperienceManager(m_thingManager, m_serverManager->jsonServer(), m_serverManager, this); connect(m_configuration, &NymeaConfiguration::serverNameChanged, m_serverManager, &ServerManager::setServerName); connect(m_thingManager, &ThingManagerImplementation::loaded, this, &NymeaCore::thingManagerLoaded); diff --git a/libnymea-core/servermanager.cpp b/libnymea-core/servermanager.cpp index d316b880..4b21671b 100644 --- a/libnymea-core/servermanager.cpp +++ b/libnymea-core/servermanager.cpp @@ -284,7 +284,6 @@ bool ServerManager::registerWebServerResource(WebServerResource *resource) } m_webServerResources.insert(resource->basePath(), resource); - foreach (WebServer *webserver, m_webServers) webserver->registerResource(resource); @@ -379,7 +378,6 @@ void ServerManager::webServerConfigurationChanged(const QString &id) qCDebug(dcServerManager()) << "Received a Web Server config change event but don't have a Web Server instance for it. Creating new WebServer instance on" << config.address << config.port << "(SSL:" << config.sslEnabled << ")"; server = new WebServer(config, m_sslConfiguration, this); m_webServers.insert(config.id, server); - foreach (WebServerResource *resource, m_webServerResources) { if (!server->registerResource(resource)) { qCWarning(dcServerManager()) << "Unable to register resource" << resource->basePath() << "on webserver" << server->serverUrl().toString(); @@ -399,6 +397,10 @@ void ServerManager::webServerConfigurationRemoved(const QString &id) } WebServer *server = m_webServers.take(id); + + foreach (WebServerResource *resource, m_webServerResources) + server->unregisterResource(resource); + unregisterZeroConfService(id, "http"); server->stopServer(); server->deleteLater(); diff --git a/libnymea/experiences/experienceplugin.cpp b/libnymea/experiences/experienceplugin.cpp index f32df07a..504fb166 100644 --- a/libnymea/experiences/experienceplugin.cpp +++ b/libnymea/experiences/experienceplugin.cpp @@ -36,6 +36,13 @@ void ExperiencePlugin::init() } +/*! This method will can be used to provide a web server resource to the core. + Override this method and provide an object. The resource will be added to the webserver after the init() method has been called. */ +WebServerResource *ExperiencePlugin::webServerResource() const +{ + return nullptr; +} + /*! Returns a pointer to the DeviceManager. The pointer won't be valid unless init() has been called. */ ThingManager *ExperiencePlugin::thingManager() { diff --git a/libnymea/experiences/experienceplugin.h b/libnymea/experiences/experienceplugin.h index c814723d..a4b4ee79 100644 --- a/libnymea/experiences/experienceplugin.h +++ b/libnymea/experiences/experienceplugin.h @@ -29,8 +29,10 @@ class ThingManager; class JsonRPCServer; +class WebServerResource; namespace nymeaserver { + class ExperienceManager; } class ExperiencePlugin : public QObject @@ -38,12 +40,15 @@ class ExperiencePlugin : public QObject Q_OBJECT public: explicit ExperiencePlugin(QObject *parent = nullptr); + virtual ~ExperiencePlugin() = default; virtual void init() = 0; + virtual WebServerResource *webServerResource() const; + protected: - ThingManager* thingManager(); - JsonRPCServer* jsonRpcServer(); + ThingManager *thingManager(); + JsonRPCServer *jsonRpcServer(); private: friend class nymeaserver::ExperienceManager;