summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikaël Capelle <capelle.mikael@gmail.com>2020-12-02 21:08:22 +0100
committerMikaël Capelle <capelle.mikael@gmail.com>2020-12-02 21:08:22 +0100
commitcb453a9ba70106832eec2cb0feecbd91d2e8b7d7 (patch)
treec23efc7f1ad1679fe906c43f6886e1c78c0308c5
parent4f7f378d8d6f9ec93d7e024ce73cda6b177fc490 (diff)
Fix callbacks for IOrganizer when plugin are unloaded/loaded.
-rw-r--r--src/organizercore.cpp42
-rw-r--r--src/organizercore.h24
-rw-r--r--src/organizerproxy.cpp57
-rw-r--r--src/organizerproxy.h23
-rw-r--r--src/proxyutils.h15
5 files changed, 109 insertions, 52 deletions
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index f14d3234..7016f9a1 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -1184,58 +1184,56 @@ bool OrganizerCore::previewFile(
return true;
}
-bool OrganizerCore::onAboutToRun(
+boost::signals2::connection OrganizerCore::onAboutToRun(
const std::function<bool(const QString &)> &func)
{
- auto conn = m_AboutToRun.connect(func);
- return conn.connected();
+ return m_AboutToRun.connect(func);
}
-bool OrganizerCore::onFinishedRun(
+boost::signals2::connection OrganizerCore::onFinishedRun(
const std::function<void(const QString &, unsigned int)> &func)
{
- auto conn = m_FinishedRun.connect(func);
- return conn.connected();
+ return m_FinishedRun.connect(func);
}
-bool OrganizerCore::onUserInterfaceInitialized(std::function<void(QMainWindow*)> const& func)
+boost::signals2::connection OrganizerCore::onUserInterfaceInitialized(std::function<void(QMainWindow*)> const& func)
{
- return m_UserInterfaceInitialized.connect(func).connected();
+ return m_UserInterfaceInitialized.connect(func);
}
-bool OrganizerCore::onProfileCreated(std::function<void(MOBase::IProfile*)> const& func)
+boost::signals2::connection OrganizerCore::onProfileCreated(std::function<void(MOBase::IProfile*)> const& func)
{
- return m_ProfileCreated.connect(func).connected();
+ return m_ProfileCreated.connect(func);
}
-bool OrganizerCore::onProfileRenamed(std::function<void(MOBase::IProfile*, QString const&, QString const&)> const& func)
+boost::signals2::connection OrganizerCore::onProfileRenamed(std::function<void(MOBase::IProfile*, QString const&, QString const&)> const& func)
{
- return m_ProfileRenamed.connect(func).connected();
+ return m_ProfileRenamed.connect(func);
}
-bool OrganizerCore::onProfileRemoved(std::function<void(QString const&)> const& func)
+boost::signals2::connection OrganizerCore::onProfileRemoved(std::function<void(QString const&)> const& func)
{
- return m_ProfileRemoved.connect(func).connected();
+ return m_ProfileRemoved.connect(func);
}
-bool OrganizerCore::onProfileChanged(std::function<void(IProfile*, IProfile*)> const& func)
+boost::signals2::connection OrganizerCore::onProfileChanged(std::function<void(IProfile*, IProfile*)> const& func)
{
- return m_ProfileChanged.connect(func).connected();
+ return m_ProfileChanged.connect(func);
}
-bool OrganizerCore::onPluginSettingChanged(std::function<void(QString const&, const QString& key, const QVariant&, const QVariant&)> const& func)
+boost::signals2::connection OrganizerCore::onPluginSettingChanged(std::function<void(QString const&, const QString& key, const QVariant&, const QVariant&)> const& func)
{
- return m_PluginSettingChanged.connect(func).connected();
+ return m_PluginSettingChanged.connect(func);
}
-bool OrganizerCore::onPluginEnabled(std::function<void(const IPlugin*)> const& func)
+boost::signals2::connection OrganizerCore::onPluginEnabled(std::function<void(const IPlugin*)> const& func)
{
- return m_PluginEnabled.connect(func).connected();
+ return m_PluginEnabled.connect(func);
}
-bool OrganizerCore::onPluginDisabled(std::function<void(const IPlugin*)> const& func)
+boost::signals2::connection OrganizerCore::onPluginDisabled(std::function<void(const IPlugin*)> const& func)
{
- return m_PluginDisabled.connect(func).connected();
+ return m_PluginDisabled.connect(func);
}
void OrganizerCore::refresh(bool saveChanges)
diff --git a/src/organizercore.h b/src/organizercore.h
index 23b624e8..1b77b7f5 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -61,6 +61,8 @@ class OrganizerCore : public QObject, public MOBase::IPluginDiagnose
private:
+ friend class OrganizerProxy;
+
struct SignalCombinerAnd
{
typedef bool result_type;
@@ -87,7 +89,7 @@ private:
using SignalProfileRemoved = boost::signals2::signal<void(QString const&)>;
using SignalProfileChanged = boost::signals2::signal<void (MOBase::IProfile *, MOBase::IProfile *)>;
using SignalPluginSettingChanged = boost::signals2::signal<void (QString const&, const QString& key, const QVariant&, const QVariant&)>;
- using SignalPluginEnabled = boost::signals2::signal<void(MOBase::IPlugin*)>;
+ using SignalPluginEnabled = boost::signals2::signal<void(const MOBase::IPlugin*)>;
public:
@@ -328,16 +330,16 @@ public:
ModList *modList();
void refresh(bool saveChanges = true);
- bool onAboutToRun(const std::function<bool(const QString&)>& func);
- bool onFinishedRun(const std::function<void(const QString&, unsigned int)>& func);
- bool onUserInterfaceInitialized(std::function<void(QMainWindow*)> const& func);
- bool onProfileCreated(std::function<void(MOBase::IProfile*)> const& func);
- bool onProfileRenamed(std::function<void(MOBase::IProfile*, QString const&, QString const&)> const& func);
- bool onProfileRemoved(std::function<void(QString const&)> const& func);
- bool onProfileChanged(std::function<void(MOBase::IProfile*, MOBase::IProfile*)> const& func);
- bool onPluginSettingChanged(std::function<void(QString const&, const QString& key, const QVariant&, const QVariant&)> const& func);
- bool onPluginEnabled(std::function<void(const MOBase::IPlugin*)> const& func);
- bool onPluginDisabled(std::function<void(const MOBase::IPlugin*)> const& func);
+ boost::signals2::connection onAboutToRun(const std::function<bool(const QString&)>& func);
+ boost::signals2::connection onFinishedRun(const std::function<void(const QString&, unsigned int)>& func);
+ boost::signals2::connection onUserInterfaceInitialized(std::function<void(QMainWindow*)> const& func);
+ boost::signals2::connection onProfileCreated(std::function<void(MOBase::IProfile*)> const& func);
+ boost::signals2::connection onProfileRenamed(std::function<void(MOBase::IProfile*, QString const&, QString const&)> const& func);
+ boost::signals2::connection onProfileRemoved(std::function<void(QString const&)> const& func);
+ boost::signals2::connection onProfileChanged(std::function<void(MOBase::IProfile*, MOBase::IProfile*)> const& func);
+ boost::signals2::connection onPluginSettingChanged(std::function<void(QString const&, const QString& key, const QVariant&, const QVariant&)> const& func);
+ boost::signals2::connection onPluginEnabled(std::function<void(const MOBase::IPlugin*)> const& func);
+ boost::signals2::connection onPluginDisabled(std::function<void(const MOBase::IPlugin*)> const& func);
bool getArchiveParsing() const
{
diff --git a/src/organizerproxy.cpp b/src/organizerproxy.cpp
index 92f250ea..13b91ff4 100644
--- a/src/organizerproxy.cpp
+++ b/src/organizerproxy.cpp
@@ -22,10 +22,31 @@ OrganizerProxy::OrganizerProxy(OrganizerCore* organizer, PluginContainer* plugin
: m_Proxied(organizer)
, m_PluginContainer(pluginContainer)
, m_Plugin(plugin)
+ , m_PluginName(plugin->name())
, m_DownloadManagerProxy(std::make_unique<DownloadManagerProxy>(this, organizer->downloadManager()))
, m_ModListProxy(std::make_unique<ModListProxy>(this, organizer->modList()))
, m_PluginListProxy(std::make_unique<PluginListProxy>(this, organizer->pluginList()))
{
+ m_Connections.push_back(m_Proxied->onAboutToRun(callSignalIfPluginActive(this, m_AboutToRun, true)));
+ m_Connections.push_back(m_Proxied->onFinishedRun(callSignalIfPluginActive(this, m_FinishedRun)));
+ m_Connections.push_back(m_Proxied->onProfileCreated(callSignalIfPluginActive(this, m_ProfileCreated)));
+ m_Connections.push_back(m_Proxied->onProfileRenamed(callSignalIfPluginActive(this, m_ProfileRenamed)));
+ m_Connections.push_back(m_Proxied->onProfileRemoved(callSignalIfPluginActive(this, m_ProfileRemoved)));
+ m_Connections.push_back(m_Proxied->onProfileChanged(callSignalIfPluginActive(this, m_ProfileChanged)));
+
+ m_Connections.push_back(m_Proxied->onUserInterfaceInitialized(callSignalAlways(m_UserInterfaceInitialized)));
+ m_Connections.push_back(m_Proxied->onPluginSettingChanged(callSignalAlways(m_PluginSettingChanged)));
+ m_Connections.push_back(m_Proxied->onPluginEnabled(callSignalAlways(m_PluginEnabled)));
+ m_Connections.push_back(m_Proxied->onPluginDisabled(callSignalAlways(m_PluginDisabled)));
+
+}
+
+OrganizerProxy::~OrganizerProxy()
+{
+ log::debug("~OrganizerProxy() for {}.", m_PluginName);
+ for (auto& conn : m_Connections) {
+ conn.disconnect();
+ }
}
IModRepositoryBridge *OrganizerProxy::createNexusBridge() const
@@ -265,68 +286,68 @@ MOBase::IPluginGame const *OrganizerProxy::managedGame() const
bool OrganizerProxy::onAboutToRun(const std::function<bool(const QString&)>& func)
{
- return m_Proxied->onAboutToRun(MOShared::callIfPluginActive(this, func, true));
+ return m_Proxied->onAboutToRun(MOShared::callIfPluginActive(this, func, true)).connected();
}
bool OrganizerProxy::onFinishedRun(const std::function<void(const QString&, unsigned int)>& func)
{
- return m_Proxied->onFinishedRun(MOShared::callIfPluginActive(this, func));
-}
-
-bool OrganizerProxy::onUserInterfaceInitialized(std::function<void(QMainWindow*)> const& func)
-{
- // Always call this one to allow plugin to initialize themselves even when not active:
- return m_Proxied->onUserInterfaceInitialized(func);
+ return m_Proxied->onFinishedRun(MOShared::callIfPluginActive(this, func)).connected();
}
bool OrganizerProxy::onProfileCreated(std::function<void(IProfile*)> const& func)
{
- return m_Proxied->onProfileCreated(MOShared::callIfPluginActive(this, func));
+ return m_ProfileCreated.connect(func).connected();
}
bool OrganizerProxy::onProfileRenamed(std::function<void(IProfile*, QString const&, QString const&)> const& func)
{
- return m_Proxied->onProfileRenamed(MOShared::callIfPluginActive(this, func));
+ return m_ProfileRenamed.connect(func).connected();
}
bool OrganizerProxy::onProfileRemoved(std::function<void(QString const&)> const& func)
{
- return m_Proxied->onProfileRemoved(MOShared::callIfPluginActive(this, func));
+ return m_ProfileRemoved.connect(func).connected();
}
bool OrganizerProxy::onProfileChanged(std::function<void(MOBase::IProfile*, MOBase::IProfile*)> const& func)
{
- return m_Proxied->onProfileChanged(MOShared::callIfPluginActive(this, func));
+ return m_ProfileChanged.connect(func).connected();
+}
+
+bool OrganizerProxy::onUserInterfaceInitialized(std::function<void(QMainWindow*)> const& func)
+{
+ // Always call this one to allow plugin to initialize themselves even when not active:
+ return m_UserInterfaceInitialized.connect(func).connected();
}
// Always call these one, otherwise plugin cannot detect they are being enabled / disabled:
bool OrganizerProxy::onPluginSettingChanged(std::function<void(QString const&, const QString& key, const QVariant&, const QVariant&)> const& func)
{
- return m_Proxied->onPluginSettingChanged(func);
+ return m_PluginSettingChanged.connect(func).connected();
}
bool OrganizerProxy::onPluginEnabled(std::function<void(const IPlugin*)> const& func)
{
- return m_Proxied->onPluginEnabled(func);
+ return m_PluginEnabled.connect(func).connected();
}
bool OrganizerProxy::onPluginEnabled(const QString& pluginName, std::function<void()> const& func)
{
- return m_Proxied->onPluginEnabled([=](const IPlugin* plugin) {
+ return onPluginEnabled([=](const IPlugin* plugin) {
if (plugin->name().compare(pluginName, Qt::CaseInsensitive) == 0) {
func();
}
- });
+ });
}
bool OrganizerProxy::onPluginDisabled(std::function<void(const IPlugin*)> const& func)
{
- return m_Proxied->onPluginDisabled(func);
+ return m_PluginDisabled.connect(func).connected();
}
bool OrganizerProxy::onPluginDisabled(const QString& pluginName, std::function<void()> const& func)
{
- return m_Proxied->onPluginDisabled([=](const IPlugin* plugin) {
+ return onPluginDisabled([=](const IPlugin* plugin) {
if (plugin->name().compare(pluginName, Qt::CaseInsensitive) == 0) {
func();
}
diff --git a/src/organizerproxy.h b/src/organizerproxy.h
index 3097adf0..fb463822 100644
--- a/src/organizerproxy.h
+++ b/src/organizerproxy.h
@@ -6,7 +6,8 @@
#include <iplugin.h>
#include <imoinfo.h>
-class OrganizerCore;
+#include "organizercore.h"
+
class PluginContainer;
class DownloadManagerProxy;
class ModListProxy;
@@ -18,6 +19,7 @@ class OrganizerProxy : public MOBase::IOrganizer
public:
OrganizerProxy(OrganizerCore *organizer, PluginContainer *pluginContainer, MOBase::IPlugin *plugin);
+ ~OrganizerProxy();
/**
* @return the plugin corresponding to this proxy.
@@ -76,12 +78,31 @@ public:
virtual MOBase::IPluginGame const *managedGame() const;
+protected:
+
+ // The container needs access to some callbacks to simulate startup.
+ friend class PluginContainer;
+
private:
OrganizerCore *m_Proxied;
PluginContainer *m_PluginContainer;
MOBase::IPlugin *m_Plugin;
+ QString m_PluginName;
+
+ OrganizerCore::SignalAboutToRunApplication m_AboutToRun;
+ OrganizerCore::SignalFinishedRunApplication m_FinishedRun;
+ OrganizerCore::SignalUserInterfaceInitialized m_UserInterfaceInitialized;
+ OrganizerCore::SignalProfileCreated m_ProfileCreated;
+ OrganizerCore::SignalProfileRenamed m_ProfileRenamed;
+ OrganizerCore::SignalProfileRemoved m_ProfileRemoved;
+ OrganizerCore::SignalProfileChanged m_ProfileChanged;
+ OrganizerCore::SignalPluginSettingChanged m_PluginSettingChanged;
+ OrganizerCore::SignalPluginEnabled m_PluginEnabled;
+ OrganizerCore::SignalPluginEnabled m_PluginDisabled;
+
+ std::vector<boost::signals2::connection> m_Connections;
std::unique_ptr<DownloadManagerProxy> m_DownloadManagerProxy;
std::unique_ptr<ModListProxy> m_ModListProxy;
diff --git a/src/proxyutils.h b/src/proxyutils.h
index 4f26c070..6c85ba14 100644
--- a/src/proxyutils.h
+++ b/src/proxyutils.h
@@ -21,6 +21,21 @@ namespace MOShared {
};
}
+ // We need to connect to the organizer.
+ template <class Signal, class T = int>
+ auto callSignalIfPluginActive(OrganizerProxy* proxy, const Signal& signal, T defaultReturn = T{}) {
+ return callIfPluginActive(proxy, [&signal](auto&&... args) {
+ return signal(std::forward<decltype(args)>(args)...);
+ }, defaultReturn);
+ }
+
+ template <class Signal, class T = int>
+ auto callSignalAlways(const Signal& signal) {
+ return [&signal](auto&&... args) {
+ return signal(std::forward<decltype(args)>(args)...);
+ };
+ }
+
}
#endif