From 3932371cd12ae7ec0812fbb2db3315448e18f1a8 Mon Sep 17 00:00:00 2001 From: Mikaƫl Capelle Date: Sun, 11 Oct 2020 21:17:34 +0200 Subject: Use proxy for ModList, PluginList and DownloadManager. Do not use registered callbacks when plugin is inactive. --- src/CMakeLists.txt | 9 ++++- src/downloadmanagerproxy.cpp | 44 ++++++++++++++++++++++++ src/downloadmanagerproxy.h | 31 +++++++++++++++++ src/modlistproxy.cpp | 53 +++++++++++++++++++++++++++++ src/modlistproxy.h | 32 +++++++++++++++++ src/organizerproxy.cpp | 81 ++++++++++++++++++++++++-------------------- src/organizerproxy.h | 18 ++++++++-- src/plugincontainer.cpp | 2 +- src/pluginlistproxy.cpp | 73 +++++++++++++++++++++++++++++++++++++++ src/pluginlistproxy.h | 36 ++++++++++++++++++++ src/proxyutils.h | 26 ++++++++++++++ 11 files changed, 365 insertions(+), 40 deletions(-) create mode 100644 src/downloadmanagerproxy.cpp create mode 100644 src/downloadmanagerproxy.h create mode 100644 src/modlistproxy.cpp create mode 100644 src/modlistproxy.h create mode 100644 src/pluginlistproxy.cpp create mode 100644 src/pluginlistproxy.h create mode 100644 src/proxyutils.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f1f54cbc..beb34ce4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,7 +33,6 @@ add_filter(NAME src/core GROUPS nexusinterface nxmaccessmanager organizercore - organizerproxy apiuseraccount processrunner qdirfiletree @@ -147,6 +146,14 @@ add_filter(NAME src/profiles GROUPS profilesdialog ) +add_filter(NAME src/proxies GROUPS + downloadmanagerproxy + modlistproxy + organizerproxy + pluginlistproxy + proxyutils +) + add_filter(NAME src/register GROUPS shared/directoryentry shared/fileentry diff --git a/src/downloadmanagerproxy.cpp b/src/downloadmanagerproxy.cpp new file mode 100644 index 00000000..4a5c9b6b --- /dev/null +++ b/src/downloadmanagerproxy.cpp @@ -0,0 +1,44 @@ +#include "downloadmanagerproxy.h" + +#include "proxyutils.h" +#include "organizerproxy.h" + +using namespace MOBase; + +DownloadManagerProxy::DownloadManagerProxy(OrganizerProxy* oproxy, IDownloadManager* downloadManager) : + m_OrganizerProxy(oproxy), m_Proxied(downloadManager) { } + +int DownloadManagerProxy::startDownloadURLs(const QStringList& urls) +{ + return m_Proxied->startDownloadURLs(urls); +} + +int DownloadManagerProxy::startDownloadNexusFile(int modID, int fileID) +{ + return m_Proxied->startDownloadNexusFile(modID, fileID); +} + +QString DownloadManagerProxy::downloadPath(int id) +{ + return m_Proxied->downloadPath(id); +} + +bool DownloadManagerProxy::onDownloadComplete(const std::function& callback) +{ + return m_Proxied->onDownloadComplete(MOShared::callIfPluginActive(m_OrganizerProxy, callback)); +} + +bool DownloadManagerProxy::onDownloadPaused(const std::function& callback) +{ + return m_Proxied->onDownloadPaused(MOShared::callIfPluginActive(m_OrganizerProxy, callback)); +} + +bool DownloadManagerProxy::onDownloadFailed(const std::function& callback) +{ + return m_Proxied->onDownloadFailed(MOShared::callIfPluginActive(m_OrganizerProxy, callback)); +} + +bool DownloadManagerProxy::onDownloadRemoved(const std::function& callback) +{ + return m_Proxied->onDownloadRemoved(MOShared::callIfPluginActive(m_OrganizerProxy, callback)); +} diff --git a/src/downloadmanagerproxy.h b/src/downloadmanagerproxy.h new file mode 100644 index 00000000..f41b60c6 --- /dev/null +++ b/src/downloadmanagerproxy.h @@ -0,0 +1,31 @@ +#ifndef DOWNLOADMANAGERPROXY_H +#define DOWNLOADMANAGERPROXY_H + +#include + +class OrganizerProxy; + +class DownloadManagerProxy : public MOBase::IDownloadManager +{ + +public: + + DownloadManagerProxy(OrganizerProxy* oproxy, IDownloadManager* downloadManager); + virtual ~DownloadManagerProxy() { } + + int startDownloadURLs(const QStringList& urls) override; + int startDownloadNexusFile(int modID, int fileID) override; + QString downloadPath(int id) override; + + bool onDownloadComplete(const std::function& callback) override; + bool onDownloadPaused(const std::function& callback) override; + bool onDownloadFailed(const std::function& callback) override; + bool onDownloadRemoved(const std::function& callback) override; + +private: + + OrganizerProxy* m_OrganizerProxy; + IDownloadManager* m_Proxied; +}; + +#endif // ORGANIZERPROXY_H diff --git a/src/modlistproxy.cpp b/src/modlistproxy.cpp new file mode 100644 index 00000000..7ec00c49 --- /dev/null +++ b/src/modlistproxy.cpp @@ -0,0 +1,53 @@ +#include "modlistproxy.h" +#include "organizerproxy.h" +#include "proxyutils.h" + +using namespace MOBase; + +ModListProxy::ModListProxy(OrganizerProxy* oproxy, IModList* modlist) : + m_OrganizerProxy(oproxy), m_Proxied(modlist) { } + +QString ModListProxy::displayName(const QString& internalName) const +{ + return m_Proxied->displayName(internalName); +} + +QStringList ModListProxy::allMods() const +{ + return m_Proxied->allMods(); +} + +IModList::ModStates ModListProxy::state(const QString& name) const +{ + return m_Proxied->state(name); +} + +bool ModListProxy::setActive(const QString& name, bool active) +{ + return m_Proxied->setActive(name, active); +} + +int ModListProxy::setActive(const QStringList& names, bool active) +{ + return m_Proxied->setActive(names, active); +} + +int ModListProxy::priority(const QString& name) const +{ + return m_Proxied->priority(name); +} + +bool ModListProxy::setPriority(const QString& name, int newPriority) +{ + return m_Proxied->setPriority(name, newPriority); +} + +bool ModListProxy::onModStateChanged(const std::function&)>& func) +{ + return m_Proxied->onModStateChanged(MOShared::callIfPluginActive(m_OrganizerProxy, func)); +} + +bool ModListProxy::onModMoved(const std::function& func) +{ + return m_Proxied->onModMoved(MOShared::callIfPluginActive(m_OrganizerProxy, func)); +} diff --git a/src/modlistproxy.h b/src/modlistproxy.h new file mode 100644 index 00000000..13399e0a --- /dev/null +++ b/src/modlistproxy.h @@ -0,0 +1,32 @@ +#ifndef MODLISTPROXY_H +#define MODLISTPROXY_H + +#include + +class OrganizerProxy; + +class ModListProxy : public MOBase::IModList +{ + +public: + + ModListProxy(OrganizerProxy* oproxy, IModList* modlist); + virtual ~ModListProxy() { } + + QString displayName(const QString& internalName) const override; + QStringList allMods() const override; + ModStates state(const QString& name) const override; + bool setActive(const QString& name, bool active) override; + int setActive(const QStringList& names, bool active) override; + int priority(const QString& name) const override; + bool setPriority(const QString& name, int newPriority) override; + bool onModStateChanged(const std::function&)>& func) override; + bool onModMoved(const std::function& func) override; + +private: + + OrganizerProxy* m_OrganizerProxy; + IModList* m_Proxied; +}; + +#endif // ORGANIZERPROXY_H diff --git a/src/organizerproxy.cpp b/src/organizerproxy.cpp index a5047b43..05011e80 100644 --- a/src/organizerproxy.cpp +++ b/src/organizerproxy.cpp @@ -5,6 +5,10 @@ #include "plugincontainer.h" #include "settings.h" #include "glob_matching.h" +#include "downloadmanagerproxy.h" +#include "modlistproxy.h" +#include "pluginlistproxy.h" +#include "proxyutils.h" #include #include @@ -13,16 +17,19 @@ using namespace MOBase; using namespace MOShared; -OrganizerProxy::OrganizerProxy(OrganizerCore *organizer, PluginContainer *pluginContainer, const QString &pluginName) +OrganizerProxy::OrganizerProxy(OrganizerCore* organizer, PluginContainer* pluginContainer, MOBase::IPlugin* plugin) : m_Proxied(organizer) , m_PluginContainer(pluginContainer) - , m_PluginName(pluginName) + , m_Plugin(plugin) + , m_DownloadManagerProxy(std::make_unique(this, organizer->downloadManager())) + , m_ModListProxy(std::make_unique(this, organizer->modList())) + , m_PluginListProxy(std::make_unique(this, organizer->pluginList())) { } IModRepositoryBridge *OrganizerProxy::createNexusBridge() const { - return new NexusBridge(m_PluginContainer, m_PluginName); + return new NexusBridge(m_PluginContainer, m_Plugin->name()); } QString OrganizerProxy::profileName() const @@ -171,36 +178,6 @@ bool OrganizerProxy::waitForApplication(HANDLE handle, LPDWORD exitCode) const } } -bool OrganizerProxy::onAboutToRun(const std::function &func) -{ - return m_Proxied->onAboutToRun(func); -} - -bool OrganizerProxy::onFinishedRun(const std::function &func) -{ - return m_Proxied->onFinishedRun(func); -} - -bool OrganizerProxy::onModInstalled(const std::function &func) -{ - return m_Proxied->onModInstalled(func); -} - -bool OrganizerProxy::onUserInterfaceInitialized(std::function const& func) -{ - return m_Proxied->onUserInterfaceInitialized(func); -} - -bool OrganizerProxy::onProfileChanged(std::function const& func) -{ - return m_Proxied->onProfileChanged(func); -} - -bool OrganizerProxy::onPluginSettingChanged(std::function const& func) -{ - return m_Proxied->onPluginSettingChanged(func); -} - void OrganizerProxy::refreshModList(bool saveChanges) { m_Proxied->refreshModList(saveChanges); @@ -254,17 +231,17 @@ QList OrganizerProxy::findFileInfos(const QString MOBase::IDownloadManager *OrganizerProxy::downloadManager() const { - return m_Proxied->downloadManager(); + return m_DownloadManagerProxy.get(); } MOBase::IPluginList *OrganizerProxy::pluginList() const { - return m_Proxied->pluginList(); + return m_PluginListProxy.get(); } MOBase::IModList *OrganizerProxy::modList() const { - return m_Proxied->modList(); + return m_ModListProxy.get(); } MOBase::IProfile *OrganizerProxy::profile() const @@ -281,3 +258,35 @@ QStringList OrganizerProxy::modsSortedByProfilePriority() const { return m_Proxied->modsSortedByProfilePriority(); } + +// CALLBACKS + +bool OrganizerProxy::onAboutToRun(const std::function& func) +{ + return m_Proxied->onAboutToRun(MOShared::callIfPluginActive(this, func, true)); +} + +bool OrganizerProxy::onFinishedRun(const std::function& func) +{ + return m_Proxied->onFinishedRun(MOShared::callIfPluginActive(this, func)); +} + +bool OrganizerProxy::onModInstalled(const std::function& func) +{ + return m_Proxied->onModInstalled(MOShared::callIfPluginActive(this, func)); +} + +bool OrganizerProxy::onUserInterfaceInitialized(std::function const& func) +{ + return m_Proxied->onUserInterfaceInitialized(MOShared::callIfPluginActive(this, func)); +} + +bool OrganizerProxy::onProfileChanged(std::function const& func) +{ + return m_Proxied->onProfileChanged(MOShared::callIfPluginActive(this, func)); +} + +bool OrganizerProxy::onPluginSettingChanged(std::function const& func) +{ + return m_Proxied->onPluginSettingChanged(MOShared::callIfPluginActive(this, func)); +} diff --git a/src/organizerproxy.h b/src/organizerproxy.h index 8950217d..cc059aa9 100644 --- a/src/organizerproxy.h +++ b/src/organizerproxy.h @@ -1,18 +1,28 @@ #ifndef ORGANIZERPROXY_H #define ORGANIZERPROXY_H +#include +#include #include class OrganizerCore; class PluginContainer; +class DownloadManagerProxy; +class ModListProxy; +class PluginListProxy; class OrganizerProxy : public MOBase::IOrganizer { public: - OrganizerProxy(OrganizerCore *organizer, PluginContainer *pluginContainer, const QString &pluginName); + OrganizerProxy(OrganizerCore *organizer, PluginContainer *pluginContainer, MOBase::IPlugin *plugin); + + /** + * @return the plugin corresponding to this proxy. + */ + MOBase::IPlugin* plugin() const { return m_Plugin; } virtual MOBase::IModRepositoryBridge *createNexusBridge() const; virtual QString profileName() const; @@ -65,7 +75,11 @@ private: OrganizerCore *m_Proxied; PluginContainer *m_PluginContainer; - QString m_PluginName; + MOBase::IPlugin *m_Plugin; + + std::unique_ptr m_DownloadManagerProxy; + std::unique_ptr m_ModListProxy; + std::unique_ptr m_PluginListProxy; }; diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index 60acc63c..4771359d 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -173,7 +173,7 @@ bool PluginContainer::verifyPlugin(IPlugin *plugin) { if (plugin == nullptr) { return false; - } else if (!plugin->init(new OrganizerProxy(m_Organizer, this, plugin->name()))) { + } else if (!plugin->init(new OrganizerProxy(m_Organizer, this, plugin))) { log::warn("plugin failed to initialize"); return false; } diff --git a/src/pluginlistproxy.cpp b/src/pluginlistproxy.cpp new file mode 100644 index 00000000..1f8dc2b4 --- /dev/null +++ b/src/pluginlistproxy.cpp @@ -0,0 +1,73 @@ +#include "pluginlistproxy.h" +#include "organizerproxy.h" +#include "proxyutils.h" + +using namespace MOBase; + +PluginListProxy::PluginListProxy(OrganizerProxy* oproxy, IPluginList* pluginlist) : + m_OrganizerProxy(oproxy), m_Proxied(pluginlist) { } + +QStringList PluginListProxy::pluginNames() const +{ + return m_Proxied->pluginNames(); +} + +IPluginList::PluginStates PluginListProxy::state(const QString& name) const +{ + return m_Proxied->state(name); +} + +void PluginListProxy::setState(const QString& name, PluginStates state) +{ + return m_Proxied->setState(name, state); +} + +int PluginListProxy::priority(const QString& name) const +{ + return m_Proxied->priority(name); +} + +bool PluginListProxy::setPriority(const QString& name, int newPriority) +{ + return m_Proxied->setPriority(name, newPriority); +} + +int PluginListProxy::loadOrder(const QString& name) const +{ + return m_Proxied->loadOrder(name); +} + +void PluginListProxy::setLoadOrder(const QStringList& pluginList) +{ + return m_Proxied->setLoadOrder(pluginList); +} + +bool PluginListProxy::isMaster(const QString& name) const +{ + return m_Proxied->isMaster(name); +} + +QStringList PluginListProxy::masters(const QString& name) const +{ + return m_Proxied->masters(name); +} + +QString PluginListProxy::origin(const QString& name) const +{ + return m_Proxied->origin(name); +} + +bool PluginListProxy::onRefreshed(const std::function& callback) +{ + return m_Proxied->onRefreshed(MOShared::callIfPluginActive(m_OrganizerProxy, callback)); +} + +bool PluginListProxy::onPluginMoved(const std::function& func) +{ + return m_Proxied->onPluginMoved(MOShared::callIfPluginActive(m_OrganizerProxy, func)); +} + +bool PluginListProxy::onPluginStateChanged(const std::function&)> &func) +{ + return m_Proxied->onPluginStateChanged(MOShared::callIfPluginActive(m_OrganizerProxy, func)); +} diff --git a/src/pluginlistproxy.h b/src/pluginlistproxy.h new file mode 100644 index 00000000..e08406e3 --- /dev/null +++ b/src/pluginlistproxy.h @@ -0,0 +1,36 @@ +#ifndef PLUGINLISTPROXY_H +#define PLUGINLISTPROXY_H + +#include + +class OrganizerProxy; + +class PluginListProxy : public MOBase::IPluginList +{ + +public: + + PluginListProxy(OrganizerProxy* oproxy, IPluginList* pluginlist); + virtual ~PluginListProxy() { } + + QStringList pluginNames() const override; + PluginStates state(const QString& name) const override; + void setState(const QString& name, PluginStates state) override; + int priority(const QString& name) const override; + bool setPriority(const QString& name, int newPriority) override; + int loadOrder(const QString& name) const override; + void setLoadOrder(const QStringList& pluginList) override; + bool isMaster(const QString& name) const override; + QStringList masters(const QString& name) const override; + QString origin(const QString& name) const override; + bool onRefreshed(const std::function& callback) override; + bool onPluginMoved(const std::function& func) override; + bool onPluginStateChanged(const std::function&)>& func) override; + +private: + + OrganizerProxy* m_OrganizerProxy; + IPluginList* m_Proxied; +}; + +#endif // ORGANIZERPROXY_H diff --git a/src/proxyutils.h b/src/proxyutils.h new file mode 100644 index 00000000..4c1717d8 --- /dev/null +++ b/src/proxyutils.h @@ -0,0 +1,26 @@ +#ifndef PROXYUTILS_H +#define PROXYUTILS_H + +#include + +#include "organizerproxy.h" + +namespace MOShared { + + template + auto callIfPluginActive(OrganizerProxy* proxy, Fn&& callback, T defaultReturn = T{}) { + return [fn = std::forward(callback), proxy, defaultReturn](auto&& ...args) { + if (proxy->plugin()->isActive()) { + return fn(std::forward(args)...); + } + else { + if constexpr (!std::is_same_v, decltype(args)... >, void>) { + return defaultReturn; + } + } + }; + } + +} + +#endif -- cgit v1.3.1