diff options
| author | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-12-02 21:08:22 +0100 |
|---|---|---|
| committer | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-12-02 21:08:22 +0100 |
| commit | cb453a9ba70106832eec2cb0feecbd91d2e8b7d7 (patch) | |
| tree | c23efc7f1ad1679fe906c43f6886e1c78c0308c5 | |
| parent | 4f7f378d8d6f9ec93d7e024ce73cda6b177fc490 (diff) | |
Fix callbacks for IOrganizer when plugin are unloaded/loaded.
| -rw-r--r-- | src/organizercore.cpp | 42 | ||||
| -rw-r--r-- | src/organizercore.h | 24 | ||||
| -rw-r--r-- | src/organizerproxy.cpp | 57 | ||||
| -rw-r--r-- | src/organizerproxy.h | 23 | ||||
| -rw-r--r-- | src/proxyutils.h | 15 |
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 |
