From 90beed8c7b356ef58431721ffe8eb4abff3da032 Mon Sep 17 00:00:00 2001 From: Mikaƫl Capelle Date: Wed, 11 Nov 2020 22:45:33 +0100 Subject: Handle proxy dependencies differently. --- src/plugincontainer.cpp | 37 ++++++++++++++++++++++++------------- src/plugincontainer.h | 10 ++++++++++ src/settingsdialogplugins.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index bcd0db44..05c6790d 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -58,14 +58,11 @@ PluginRequirements::PluginRequirements(PluginContainer* pluginContainer, MOBase: , m_Plugin(plugin) , m_PluginProxy(pluginProxy) , m_Organizer(proxy) -{ - for (auto* requirement : plugin->requirements()) { - m_Requirements.emplace_back(requirement); - } +{ } - // TODO: - if (pluginProxy) { - m_Requirements.emplace_back(PluginRequirementFactory::pluginDependency(pluginProxy->name())); +void PluginRequirements::fetchRequirements() { + for (auto* requirement : m_Plugin->requirements()) { + m_Requirements.emplace_back(requirement); } } @@ -74,6 +71,20 @@ IPluginProxy* PluginRequirements::proxy() const return m_PluginProxy; } +std::vector PluginRequirements::proxied() const +{ + std::vector children; + if (dynamic_cast(m_Plugin)) { + for (auto* obj : m_PluginContainer->plugins()) { + auto* plugin = qobject_cast(obj); + if (plugin && m_PluginContainer->requirements(plugin).proxy() == m_Plugin) { + children.push_back(plugin); + } + } + } + return children; +} + IPlugin* PluginRequirements::master() const { if (m_Plugin->master().isEmpty()) { @@ -322,12 +333,15 @@ bool PluginContainer::initPlugin(IPlugin *plugin, IPluginProxy *pluginProxy) return true; } + auto [it, bl] = m_Requirements.emplace(plugin, PluginRequirements(this, plugin, proxy, pluginProxy)); + if (!plugin->init(proxy)) { log::warn("plugin failed to initialize"); return false; } - m_Requirements.emplace(plugin, PluginRequirements(this, plugin, proxy, pluginProxy)); + // Update requirements: + it->second.fetchRequirements(); return true; } @@ -519,11 +533,8 @@ bool PluginContainer::isEnabled(IPlugin* plugin) const return false; } - // Check the requirements (if a plugin checks in init(), the requirements have - // not been computed yet): - auto it = m_Requirements.find(plugin); - - return it == std::end(m_Requirements) ? true : it->second.canEnable(); + // Check the requirements: + return m_Requirements.at(plugin).canEnable(); } void PluginContainer::setEnabled(MOBase::IPlugin* plugin, bool enable, bool dependencies) diff --git a/src/plugincontainer.h b/src/plugincontainer.h index e9761cb1..b37b48cd 100644 --- a/src/plugincontainer.h +++ b/src/plugincontainer.h @@ -49,6 +49,11 @@ public: */ MOBase::IPluginProxy* proxy() const; + /** + * @return the list of plugins this plugin proxies (if it's a proxy plugin). + */ + std::vector proxied() const; + /** * @return the master of this plugin, if any. */ @@ -81,6 +86,11 @@ private: // Accumulator version for requiredFor() to avoid infinite recursion. void requiredFor(std::vector& required, std::set& visited) const; + // Retrieve the requirements from the underlying plugin, take ownership on them + // and store them. We cannot do this in the constructor because we want to have a + // constructed object before calling init(). + void fetchRequirements(); + friend class PluginContainer; PluginContainer* m_PluginContainer; diff --git a/src/settingsdialogplugins.cpp b/src/settingsdialogplugins.cpp index 15c0b424..e9d36c57 100644 --- a/src/settingsdialogplugins.cpp +++ b/src/settingsdialogplugins.cpp @@ -225,6 +225,8 @@ void PluginsSettingsTab::on_checkboxEnabled_clicked(bool checked) else { // Custom check for proxy + current game: if (m_pluginContainer->implementInterface(plugin)) { + + // Current game: auto* game = m_pluginContainer->managedGame(); if (m_pluginContainer->requirements(game).proxy() == plugin) { QMessageBox::warning( @@ -233,6 +235,25 @@ void PluginsSettingsTab::on_checkboxEnabled_clicked(bool checked) ui->enabledCheckbox->setChecked(true); return; } + + // Check the proxied plugins: + auto proxied = requirements.proxied(); + QStringList pluginNames; + for (auto& p : proxied) { + pluginNames.append(p->localizedName()); + } + pluginNames.sort(); + QString message = QObject::tr( + "

Disabling this plugin will prevent the following plugins from working correctly:

    %1
" + "

Do you want to continue? You will need to restart ModOrganizer2 for the change to take effect.

") + .arg("
  • " + pluginNames.join("
  • ") + "
  • "); + if (QMessageBox::warning( + parentWidget(), QObject::tr("Really disable plugin?"), message, + QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { + ui->enabledCheckbox->setChecked(true); + return; + } + } // Check if the plugins is required for other plugins: @@ -256,6 +277,11 @@ void PluginsSettingsTab::on_checkboxEnabled_clicked(bool checked) m_pluginContainer->setEnabled(plugin, false, true); } + // Proxy was disabled / enabled, need restart: + if (m_pluginContainer->implementInterface(plugin)) { + dialog().setExitNeeded(Exit::Restart); + } + updateListItems(); } -- cgit v1.3.1