diff --git a/libnymea-core/experiences/experiencemanager.cpp b/libnymea-core/experiences/experiencemanager.cpp index 90e9e5e4..78559ef5 100644 --- a/libnymea-core/experiences/experiencemanager.cpp +++ b/libnymea-core/experiences/experiencemanager.cpp @@ -1,11 +1,74 @@ #include "experiencemanager.h" +#include "experiences/experienceplugin.h" #include "jsonrpc/jsonrpcserver.h" +#include "loggingcategories.h" + +#include +#include +#include +#include + namespace nymeaserver { + ExperienceManager::ExperienceManager(JsonRPCServer *jsonRpcServer, QObject *parent) : QObject(parent) { // jsonRpcServer->registerHandler(); + foreach (const QString &path, pluginSearchDirs()) { + QDir dir(path); + qCDebug(dcExperiences) << "Loading platform plugins from:" << dir.absolutePath(); + foreach (const QString &entry, dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot)) { + QFileInfo fi(path + "/" + entry); + if (fi.isFile()) { + if (entry.startsWith("libnymea_experienceplugin") && entry.endsWith(".so")) { + loadExperiencePlugin(path + "/" + entry); + } + } else if (fi.isDir()) { + if (QFileInfo::exists(path + "/" + entry + "/libnymea_experienceplugin" + entry + ".so")) { + loadExperiencePlugin(path + "/" + entry + "/libnymea_experienceplugin" + entry + ".so"); + } + } + } + } +} + +QStringList ExperienceManager::pluginSearchDirs() const +{ + QStringList searchDirs; + QByteArray envPath = qgetenv("NYMEA_EXPERIENCE_PLUGINS_PATH"); + if (!envPath.isEmpty()) { + searchDirs << QString(envPath).split(':'); + } + + foreach (QString libraryPath, QCoreApplication::libraryPaths()) { + searchDirs << libraryPath.replace("qt5", "nymea").replace("plugins", "experiences"); + } + searchDirs << QCoreApplication::applicationDirPath() + "/../lib/nymea/experiences"; + searchDirs << QCoreApplication::applicationDirPath() + "/../experiences/"; + searchDirs << QCoreApplication::applicationDirPath() + "/../../../experiences/"; + return searchDirs; +} + +void ExperienceManager::loadExperiencePlugin(const QString &file) +{ + QPluginLoader loader; + loader.setFileName(file); + loader.setLoadHints(QLibrary::ResolveAllSymbolsHint); + if (!loader.load()) { + qCWarning(dcExperiences()) << loader.errorString(); + return; + } + ExperiencePlugin *plugin = qobject_cast(loader.instance()); + if (!plugin) { + qCWarning(dcExperiences()) << "Could not get plugin instance of" << loader.fileName(); + loader.unload(); + return; + } + qCDebug(dcExperiences()) << "Loaded experience plugin:" << loader.fileName(); + plugin->setParent(this); + + m_plugins.append(plugin); } } diff --git a/libnymea-core/experiences/experiencemanager.h b/libnymea-core/experiences/experiencemanager.h index 2b0b25bc..62218095 100644 --- a/libnymea-core/experiences/experiencemanager.h +++ b/libnymea-core/experiences/experiencemanager.h @@ -3,6 +3,8 @@ #include +class ExperiencePlugin; + namespace nymeaserver { class JsonRPCServer; @@ -16,6 +18,14 @@ public: signals: public slots: + +private: + QStringList pluginSearchDirs() const; + + void loadExperiencePlugin(const QString &file); + +private: + QList m_plugins; }; } diff --git a/libnymea-core/nymeacore.cpp b/libnymea-core/nymeacore.cpp index f4089ea9..3562b891 100644 --- a/libnymea-core/nymeacore.cpp +++ b/libnymea-core/nymeacore.cpp @@ -97,6 +97,7 @@ #include "nymeasettings.h" #include "tagging/tagsstorage.h" #include "platform/platform.h" +#include "experiences/experiencemanager.h" #include "devices/devicemanagerimplementation.h" #include "devices/device.h" @@ -172,6 +173,7 @@ void NymeaCore::init() { m_cloudManager = new CloudManager(m_configuration, m_networkManager, this); qCDebug(dcApplication()) << "Loading experiences"; + new ExperienceManager(m_serverManager->jsonServer(), this); CloudNotifications *cloudNotifications = m_cloudManager->createNotificationsPlugin(); diff --git a/libnymea/loggingcategories.cpp b/libnymea/loggingcategories.cpp index e879bd6d..4b8cc66e 100644 --- a/libnymea/loggingcategories.cpp +++ b/libnymea/loggingcategories.cpp @@ -30,6 +30,7 @@ Q_LOGGING_CATEGORY(dcSystem, "System") Q_LOGGING_CATEGORY(dcPlatform, "Platform") Q_LOGGING_CATEGORY(dcPlatformUpdate, "PlatformUpdate") Q_LOGGING_CATEGORY(dcPlatformZeroConf, "PlatformZeroConf") +Q_LOGGING_CATEGORY(dcExperiences, "Experiences") Q_LOGGING_CATEGORY(dcTimeManager, "TimeManager") Q_LOGGING_CATEGORY(dcRuleEngine, "RuleEngine") Q_LOGGING_CATEGORY(dcRuleEngineDebug, "RuleEngineDebug") diff --git a/libnymea/loggingcategories.h b/libnymea/loggingcategories.h index 1da7b91c..fec359bc 100644 --- a/libnymea/loggingcategories.h +++ b/libnymea/loggingcategories.h @@ -35,6 +35,7 @@ Q_DECLARE_LOGGING_CATEGORY(dcSystem) Q_DECLARE_LOGGING_CATEGORY(dcPlatform) Q_DECLARE_LOGGING_CATEGORY(dcPlatformUpdate) Q_DECLARE_LOGGING_CATEGORY(dcPlatformZeroConf) +Q_DECLARE_LOGGING_CATEGORY(dcExperiences) Q_DECLARE_LOGGING_CATEGORY(dcTimeManager) Q_DECLARE_LOGGING_CATEGORY(dcRuleEngine) Q_DECLARE_LOGGING_CATEGORY(dcRuleEngineDebug)