From b9df3fb0f5555d4e93afee9103cdbcc5d80f401f Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 28 Feb 2011 21:01:35 +0200 Subject: [PATCH] Changed: #1206 Update plugin system. Now plugin manager takes into account dependencies between plug-ins. Update core, object viewer and example plugin. --- .../src/extension_system/iplugin.h | 82 +++++-- .../src/extension_system/iplugin_manager.h | 44 ++-- .../src/extension_system/iplugin_spec.h | 36 ++-- .../src/extension_system/plugin_manager.cpp | 194 ++++++++++++----- .../src/extension_system/plugin_manager.h | 49 ++--- .../src/extension_system/plugin_spec.cpp | 204 +++++++++++------- .../src/extension_system/plugin_spec.h | 64 +++--- .../src/plugins/core/core_constants.h | 1 + .../src/plugins/core/core_plugin.cpp | 19 +- .../src/plugins/core/core_plugin.h | 2 +- .../src/plugins/example/plugin1.cpp | 7 +- .../src/plugins/example/plugin1.h | 2 +- .../object_viewer/object_viewer_plugin.cpp | 6 +- .../object_viewer/object_viewer_plugin.h | 2 +- .../object_viewer/particle_control_dialog.cpp | 6 +- .../plugins/object_viewer/settings_dialog.cpp | 2 +- 16 files changed, 457 insertions(+), 263 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin.h index 1f878cc32..b5b07a0ab 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin.h @@ -1,27 +1,27 @@ -/* - Object Viewer Qt - Copyright (C) 2010 Dzmitry Kamiahin - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . #ifndef IPLUGIN_H #define IPLUGIN_H #include #include +#include #include "iplugin_manager.h" @@ -46,17 +46,61 @@ class IPlugin public: virtual ~IPlugin() {} + /** + @brief Called after the plugin has been loaded and the IPlugin instance has been created. + + @details The initialize methods of plugins that depend + on this plugin are called after the initialize method of this plugin + has been called. Plugins should initialize their internal state in this + method. Returns if initialization of successful. If it wasn't successful, + the \a errorString should be set to a user-readable message + describing the reason. + */ virtual bool initialize(IPluginManager *pluginManager, QString *errorString) = 0; + + /** + @brief Called after the IPlugin::initialize() method has been called, + and after both the IPlugin::initialize() and IPlugin::extensionsInitialized() + methods of plugins that depend on this plugin have been called. + + @details In this method, the plugin can assume that plugins that depend on + this plugin are fully 'up and running'. It is a good place to + look in the plugin manager's object pool for objects that have + been provided by dependent plugins. + */ virtual void extensionsInitialized() = 0; + + /** + @\brief Called during a shutdown sequence in the same order as initialization + before the plugins get deleted in reverse order. + + @details This method should be used to disconnect from other plugins, + hide all UI, and optimize shutdown in general. + */ virtual void shutdown() { } + /** + @\brief This method should be implemented to work properly NeL singletons. + Called immediately after loading the plugin. + @code + void Plugin::setNelContext(NLMISC::INelContext *nelContext) + { + #ifdef NL_OS_WINDOWS + // Ensure that a context doesn't exist yet. + // This only applies to platforms without PIC, e.g. Windows. + nlassert(!NLMISC::INelContext::isContextInitialised()); + #endif // NL_OS_WINDOWS + _LibContext = new NLMISC::CLibraryContext(*nelContext); + } + @endcode + */ virtual void setNelContext(NLMISC::INelContext *nelContext) = 0; virtual QString name() const = 0; virtual QString version() const = 0; virtual QString vendor() const = 0; virtual QString description() const = 0; - virtual QList dependencies() const = 0; + virtual QStringList dependencies() const = 0; }; }; //namespace ExtensionSystem diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h index 0d568cd2b..e67c9e588 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h @@ -1,26 +1,25 @@ -/* - Object Viewer Qt - Copyright (C) 2010 Dzmitry Kamiahin - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . #ifndef IPLUGINMANAGER_H #define IPLUGINMANAGER_H -#include "plugin_spec.h" +#include "iplugin_spec.h" #include #include @@ -62,6 +61,8 @@ public: virtual QSettings *settings() const = 0; // Auxiliary operations + + /// Retrieve all objects of a given type from the object pool. template QList getObjects() const { @@ -76,6 +77,7 @@ public: return objects; } + /// Retrieve the object of a given type from the object pool. template T *getObject() const { @@ -124,9 +126,13 @@ public: } Q_SIGNALS: + /// Signal that \a obj has been added to the object pool. void objectAdded(QObject *obj); + + /// Signal that \a obj will be removed from the object pool. void aboutToRemoveObject(QObject *obj); + /// Signal that the list of available plugins has changed. void pluginsChanged(); }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_spec.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_spec.h index 020183cc1..f0c62fec7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_spec.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_spec.h @@ -1,21 +1,20 @@ -/* - Object Viewer Qt - Copyright (C) 2010 Dzmitry Kamiahin - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . #ifndef IPLUGINSPEC_H #define IPLUGINSPEC_H @@ -39,6 +38,7 @@ struct State Invalid = 1, Read, Loaded, + Resolved, Initialized, Running, Stopped, diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp index 22ffe8aec..701f2e9ea 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp @@ -1,23 +1,23 @@ -/* - Object Viewer Qt - Copyright (C) 2010 Dzmitry Kamiahin - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . #include "plugin_manager.h" +#include "plugin_spec.h" #include @@ -28,7 +28,7 @@ namespace ExtensionSystem CPluginManager::CPluginManager(QObject *parent) :IPluginManager(parent), - _settings(0) + m_settings(0) { } @@ -36,25 +36,25 @@ CPluginManager::~CPluginManager() { stopAll(); deleteAll(); - qDeleteAll(_pluginSpecs); + qDeleteAll(m_pluginSpecs); } void CPluginManager::addObject(QObject *obj) { - QWriteLocker lock(&_lock); + QWriteLocker lock(&m_lock); if (obj == 0) { nlwarning("trying to add null object"); return; } - if (_allObjects.contains(obj)) + if (m_allObjects.contains(obj)) { nlwarning("trying to add duplicate object"); return; } nlinfo(QString("addObject: " + obj->objectName()).toStdString().c_str()); - _allObjects.append(obj); + m_allObjects.append(obj); Q_EMIT objectAdded(obj); } @@ -67,7 +67,7 @@ void CPluginManager::removeObject(QObject *obj) return; } - if (!_allObjects.contains(obj)) + if (!m_allObjects.contains(obj)) { nlinfo(QString("object not in list: " + obj->objectName()).toStdString().c_str()); return; @@ -75,24 +75,29 @@ void CPluginManager::removeObject(QObject *obj) nlinfo(QString("removeObject: " + obj->objectName()).toStdString().c_str()); Q_EMIT aboutToRemoveObject(obj); - QWriteLocker lock(&_lock); - _allObjects.removeAll(obj); + QWriteLocker lock(&m_lock); + m_allObjects.removeAll(obj); } QList CPluginManager::allObjects() const { - return _allObjects; + return m_allObjects; } void CPluginManager::loadPlugins() { - Q_FOREACH (CPluginSpec *spec, _pluginSpecs) + Q_FOREACH (CPluginSpec *spec, m_pluginSpecs) setPluginState(spec, State::Loaded); - Q_FOREACH (CPluginSpec *spec, _pluginSpecs) + Q_FOREACH (CPluginSpec *spec, m_pluginSpecs) + setPluginState(spec, State::Resolved); + + QList queue = loadQueue(); + + Q_FOREACH (CPluginSpec *spec, queue) setPluginState(spec, State::Initialized); - QListIterator it(_pluginSpecs); + QListIterator it(queue); it.toBack(); while (it.hasPrevious()) setPluginState(it.previous(), State::Running); @@ -102,28 +107,28 @@ void CPluginManager::loadPlugins() QStringList CPluginManager::getPluginPaths() const { - return _pluginPaths; + return m_pluginPaths; } void CPluginManager::setPluginPaths(const QStringList &paths) { - _pluginPaths = paths; + m_pluginPaths = paths; readPluginPaths(); } QList CPluginManager::plugins() const { - return _ipluginSpecs; + return m_ipluginSpecs; } void CPluginManager::setSettings(QSettings *settings) { - _settings = settings; + m_settings = settings; } QSettings *CPluginManager::settings() const { - return _settings; + return m_settings; } void CPluginManager::readSettings() @@ -136,12 +141,12 @@ void CPluginManager::writeSettings() void CPluginManager::readPluginPaths() { - qDeleteAll(_pluginSpecs); - _pluginSpecs.clear(); - _ipluginSpecs.clear(); + qDeleteAll(m_pluginSpecs); + m_pluginSpecs.clear(); + m_ipluginSpecs.clear(); QStringList pluginsList; - QStringList searchPaths = _pluginPaths; + QStringList searchPaths = m_pluginPaths; while (!searchPaths.isEmpty()) { const QDir dir(searchPaths.takeFirst()); @@ -161,9 +166,9 @@ void CPluginManager::readPluginPaths() { CPluginSpec *spec = new CPluginSpec; spec->setFileName(pluginFile); - spec->_pluginManager = this; - _pluginSpecs.append(spec); - _ipluginSpecs.append(spec); + spec->m_pluginManager = this; + m_pluginSpecs.append(spec); + m_ipluginSpecs.append(spec); } Q_EMIT pluginsChanged(); @@ -171,36 +176,115 @@ void CPluginManager::readPluginPaths() void CPluginManager::setPluginState(CPluginSpec *spec, int destState) { - if (spec->hasError()) + if (spec->hasError() || spec->getState() != destState-1) return; - if (destState == State::Running) + + switch (destState) { + case State::Loaded: + spec->loadLibrary(); + return; + case State::Resolved: + spec->resolveDependencies(m_pluginSpecs); + return; + case State::Running: spec->initializeExtensions(); return; - } - else if (destState == State::Deleted) - { + case State::Deleted: spec->kill(); return; + default: + break; + } + Q_FOREACH (const CPluginSpec *depSpec, spec->dependencySpecs()) + { + if (depSpec->getState() != destState) + { + spec->m_hasError = true; + spec->m_errorString = tr("Cannot initializing plugin because dependency failed to load: %1\nReason: %2") + .arg(depSpec->name()).arg(depSpec->errorString()); + return; + } + } + switch (destState) + { + case State::Initialized: + spec->initializePlugin(); + break; + case State::Stopped: + spec->stop(); + break; + default: + break; + } +} + +QList CPluginManager::loadQueue() +{ + QList queue; + Q_FOREACH(CPluginSpec *spec, m_pluginSpecs) + { + QList circularityCheckQueue; + loadQueue(spec, queue, circularityCheckQueue); + } + return queue; +} + +bool CPluginManager::loadQueue(CPluginSpec *spec, QList &queue, + QList &circularityCheckQueue) +{ + if (queue.contains(spec)) + return true; + // check for circular dependencies + if (circularityCheckQueue.contains(spec)) + { + spec->m_hasError = true; + spec->m_errorString = tr("Circular dependency detected:\n"); + int index = circularityCheckQueue.indexOf(spec); + for (int i = index; i < circularityCheckQueue.size(); ++i) + { + spec->m_errorString.append(tr("%1(%2) depends on\n") + .arg(circularityCheckQueue.at(i)->name()).arg(circularityCheckQueue.at(i)->version())); + } + spec->m_errorString.append(tr("%1(%2)").arg(spec->name()).arg(spec->version())); + return false; + } + circularityCheckQueue.append(spec); + // check if we have the dependencies + if (spec->getState() == State::Invalid || spec->getState() == State::Read) + { + queue.append(spec); + return false; } - if (destState == State::Loaded) - spec->loadLibrary(); - else if (destState == State::Initialized) - spec->initializePlugin(); - else if (destState == State::Stopped) - spec->stop(); + // add dependencies + Q_FOREACH (CPluginSpec *depSpec, spec->dependencySpecs()) + { + if (!loadQueue(depSpec, queue, circularityCheckQueue)) + { + spec->m_hasError = true; + spec->m_errorString = + tr("Cannot load plugin because dependency failed to load: %1(%2)\nReason: %3") + .arg(depSpec->name()).arg(depSpec->version()).arg(depSpec->errorString()); + return false; + } + } + // add self + queue.append(spec); + return true; } void CPluginManager::stopAll() { - Q_FOREACH (CPluginSpec *spec, _pluginSpecs) + QList queue = loadQueue(); + Q_FOREACH (CPluginSpec *spec, queue) setPluginState(spec, State::Stopped); } void CPluginManager::deleteAll() { - QListIterator it(_pluginSpecs); + QList queue = loadQueue(); + QListIterator it(queue); it.toBack(); while (it.hasPrevious()) { diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h index 97698b14e..d1a18485b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h @@ -1,21 +1,20 @@ -/* - Object Viewer Qt - Copyright (C) 2010 Dzmitry Kamiahin - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . #ifndef PLUGINMANAGER_H #define PLUGINMANAGER_H @@ -50,6 +49,7 @@ public: virtual QStringList getPluginPaths() const; virtual void setPluginPaths(const QStringList &paths); virtual QList plugins() const; + QList loadQueue(); // Settings virtual void setSettings(QSettings *settings); @@ -60,16 +60,17 @@ public: private: void setPluginState(CPluginSpec *spec, int destState); void readPluginPaths(); + bool loadQueue(CPluginSpec *spec, QList &queue, QList &circularityCheckQueue); void stopAll(); void deleteAll(); - mutable QReadWriteLock _lock; + mutable QReadWriteLock m_lock; - QSettings *_settings; - QList _pluginSpecs; - QList _ipluginSpecs; - QStringList _pluginPaths; - QList _allObjects; + QSettings *m_settings; + QList m_pluginSpecs; + QList m_ipluginSpecs; + QStringList m_pluginPaths; + QList m_allObjects; }; // class CPluginManager diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp index 3906aafc5..f1e19dc45 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp @@ -1,22 +1,20 @@ -/* - Object Viewer Qt - Copyright (C) 2010 Dzmitry Kamiahin - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ - +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . #include "plugin_spec.h" #include @@ -34,74 +32,79 @@ namespace ExtensionSystem { CPluginSpec::CPluginSpec() - : _location(""), - _filePath(""), - _fileName(""), - _name(""), - _version(""), - _vendor(""), - _description(""), - _state(State::Invalid), - _hasError(false), - _errorString(""), - _plugin(0), - _pluginManager(0) + : m_location(""), + m_filePath(""), + m_fileName(""), + m_name(""), + m_version(""), + m_vendor(""), + m_description(""), + m_state(State::Invalid), + m_hasError(false), + m_errorString(""), + m_plugin(0), + m_pluginManager(0) { } QString CPluginSpec::name() const { - return _name; + return m_name; } QString CPluginSpec::version() const { - return _version; + return m_version; } QString CPluginSpec::vendor() const { - return _vendor; + return m_vendor; } QString CPluginSpec::description() const { - return _description; + return m_description; } QString CPluginSpec::location() const { - return _location; + return m_location; } QString CPluginSpec::filePath() const { - return _filePath; + return m_filePath; } QString CPluginSpec::fileName() const { - return _fileName; + return m_fileName; } IPlugin* CPluginSpec::plugin() const { - return _plugin; + return m_plugin; } int CPluginSpec::getState() const { - return _state; + return m_state; } bool CPluginSpec::hasError() const { - return _hasError; + return m_hasError; } QString CPluginSpec::errorString() const { - return _errorString; + return m_errorString; +} + +QList CPluginSpec::dependencySpecs() const +{ + return m_dependencySpecs; } bool CPluginSpec::setFileName(const QString &fileName) @@ -113,26 +116,26 @@ bool CPluginSpec::setFileName(const QString &fileName) return reportError(QCoreApplication::translate("CPluginSpec", "Could not open file for read: %1").arg(file.fileName())); QFileInfo fileInfo(file); - _location = fileInfo.absolutePath(); - _filePath = fileInfo.absoluteFilePath(); - _fileName = fileInfo.fileName(); + m_location = fileInfo.absolutePath(); + m_filePath = fileInfo.absoluteFilePath(); + m_fileName = fileInfo.fileName(); - _state = State::Read; + m_state = State::Read; return true; } bool CPluginSpec::loadLibrary() { - if (_hasError) + if (m_hasError) return false; - if (_state != State::Read) + if (m_state != State::Read) { - if (_state == State::Loaded) + if (m_state == State::Loaded) return true; return reportError(QCoreApplication::translate("CPluginSpec", "Loading the library failed because state != Resolved")); } - QPluginLoader loader(_filePath); + QPluginLoader loader(m_filePath); if (!loader.load()) return reportError(loader.errorString()); @@ -145,76 +148,121 @@ bool CPluginSpec::loadLibrary() pluginObject->setNelContext(&NLMISC::INelContext::getInstance()); - _name = pluginObject->name(); - _version = pluginObject->version(); - _vendor = pluginObject->vendor(); - _description = pluginObject->description(); + m_name = pluginObject->name(); + m_version = pluginObject->version(); + m_vendor = pluginObject->vendor(); + m_description = pluginObject->description(); + + m_state = State::Loaded; + m_plugin = pluginObject; + return true; +} + +bool CPluginSpec::resolveDependencies(const QList &specs) +{ + if (m_hasError) + return false; + if (m_state != State::Loaded) + { + m_errorString = QCoreApplication::translate("CPluginSpec", "Resolving dependencies failed because state != Read"); + m_hasError = true; + return false; + } + QList resolvedDependencies; + QStringList dependencies = m_plugin->dependencies(); + Q_FOREACH(const QString &dependency, dependencies) + { + CPluginSpec *found = 0; + + Q_FOREACH(CPluginSpec *spec, specs) + { + if (QString::compare(dependency, spec->name(), Qt::CaseInsensitive) == 0) + { + found = spec; + break; + } + } + if (!found) + { + m_hasError = true; + if (!m_errorString.isEmpty()) + m_errorString.append(QLatin1Char('\n')); + m_errorString.append(QCoreApplication::translate("CPluginSpec", "Could not resolve dependency '%1'") + .arg(dependency)); + continue; + } + resolvedDependencies.append(found); + } + if (m_hasError) + return false; + + m_dependencySpecs = resolvedDependencies; + + m_state = State::Resolved; - _state = State::Loaded; - _plugin = pluginObject; return true; } bool CPluginSpec::initializePlugin() { - if (_hasError) + if (m_hasError) return false; - if (_state != State::Loaded) + if (m_state != State::Resolved) { - if (_state == State::Initialized) + if (m_state == State::Initialized) return true; - return reportError(QCoreApplication::translate("CPluginSpec", "Initializing the plugin failed because state != Loaded)")); + return reportError(QCoreApplication::translate("CPluginSpec", "Initializing the plugin failed because state != Resolved)")); } - if (!_plugin) + if (!m_plugin) return reportError(QCoreApplication::translate("CPluginSpec", "Internal error: have no plugin instance to initialize")); QString err; - if (!_plugin->initialize(_pluginManager, &err)) + if (!m_plugin->initialize(m_pluginManager, &err)) return reportError(QCoreApplication::translate("CPluginSpec", "Plugin initialization failed: %1").arg(err)); - _state = State::Initialized; + m_state = State::Initialized; return true; } bool CPluginSpec::initializeExtensions() { - if (_hasError) + if (m_hasError) return false; - if (_state != State::Initialized) + if (m_state != State::Initialized) { - if (_state == State::Running) + if (m_state == State::Running) return true; return reportError(QCoreApplication::translate("CPluginSpec", "Cannot perform extensionsInitialized because state != Initialized")); } - if (!_plugin) + if (!m_plugin) return reportError(QCoreApplication::translate("CPluginSpec", "Internal error: have no plugin instance to perform extensionsInitialized")); - _plugin->extensionsInitialized(); - _state = State::Running; + m_plugin->extensionsInitialized(); + m_state = State::Running; return true; } void CPluginSpec::stop() { - if (!_plugin) + if (!m_plugin) return; - _plugin->shutdown(); - _state = State::Stopped; + m_plugin->shutdown(); + m_state = State::Stopped; } void CPluginSpec::kill() { - if (!_plugin) + if (!m_plugin) return; - delete _plugin; - _plugin = 0; - _state = State::Deleted; + delete m_plugin; + m_plugin = 0; + m_state = State::Deleted; } bool CPluginSpec::reportError(const QString &err) { - _errorString = err; - _hasError = true; + m_errorString = err; + m_hasError = true; return false; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h index aadf6be1e..e73f3ed93 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h @@ -1,27 +1,28 @@ -/* - Object Viewer Qt - Copyright (C) 2010 Dzmitry Kamiahin - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . #ifndef PLUGINSPEC_H #define PLUGINSPEC_H #include "iplugin_spec.h" +#include "QtCore/QList" + namespace ExtensionSystem { @@ -43,12 +44,14 @@ public: virtual int getState() const; virtual bool hasError() const; virtual QString errorString() const; + QList dependencySpecs() const; private: CPluginSpec(); bool setFileName(const QString &fileName); bool loadLibrary(); + bool resolveDependencies(const QList &specs); bool initializePlugin(); bool initializeExtensions(); void stop(); @@ -56,21 +59,22 @@ private: bool reportError(const QString &err); - QString _location; - QString _filePath; - QString _fileName; + QString m_location; + QString m_filePath; + QString m_fileName; - QString _name; - QString _version; - QString _vendor; - QString _description; + QString m_name; + QString m_version; + QString m_vendor; + QString m_description; - int _state; - bool _hasError; - QString _errorString; + int m_state; + bool m_hasError; + QString m_errorString; - IPlugin *_plugin; - IPluginManager *_pluginManager; + IPlugin *m_plugin; + IPluginManager *m_pluginManager; + QList m_dependencySpecs; friend class CPluginManager; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h index 6f1c0f06d..af0e2aa5b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h @@ -26,6 +26,7 @@ namespace Constants const char * const OVQT_VERSION_LONG = "0.0.1"; const char * const OVQT_VENDOR = "Dzmitry Kamiahin"; const char * const OVQT_YEAR = "2010, 2011"; +const char * const OVQT_CORE_PLUGIN = "Core"; //mainwindow const char * const MAIN_WINDOW = "ObjectViewerQt.MainWindow"; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp index 4ecddb826..ccc30614a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp @@ -58,12 +58,13 @@ bool CorePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QStr _plugMan = pluginManager; _mainWindow = new MainWindow(pluginManager); -/* if (QtWin::isCompositionEnabled()) - { - QtWin::extendFrameIntoClientArea(_mainWindow); - _mainWindow->setContentsMargins(0, 0, 0, 0); - } -*/ bool success = _mainWindow->initialize(errorString); + /* if (QtWin::isCompositionEnabled()) + { + QtWin::extendFrameIntoClientArea(_mainWindow); + _mainWindow->setContentsMargins(0, 0, 0, 0); + } + */ + bool success = _mainWindow->initialize(errorString); CSearchPathsSettingsPage *serchPathPage = new CSearchPathsSettingsPage(this); serchPathPage->applySearchPaths(); addAutoReleasedObject(serchPathPage); @@ -91,7 +92,7 @@ void CorePlugin::setNelContext(NLMISC::INelContext *nelContext) QString CorePlugin::name() const { - return QLatin1String("Core"); + return QLatin1String(Constants::OVQT_CORE_PLUGIN); } QString CorePlugin::version() const @@ -109,9 +110,9 @@ QString CorePlugin::description() const return "Core plugin."; } -QList CorePlugin::dependencies() const +QStringList CorePlugin::dependencies() const { - return QList(); + return QStringList(); } void CorePlugin::addAutoReleasedObject(QObject *obj) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h index 45f95fd77..ef590e1fc 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h @@ -57,7 +57,7 @@ public: QString version() const; QString vendor() const; QString description() const; - QList dependencies() const; + QStringList dependencies() const; void addAutoReleasedObject(QObject *obj); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp index 776f982c7..6cf3f09a8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp @@ -86,9 +86,12 @@ QString MyPlugin::description() const return "Example ovqt plugin."; } -QList MyPlugin::dependencies() const +QStringList MyPlugin::dependencies() const { - return QList(); + QStringList list; + list.append(Core::Constants::OVQT_CORE_PLUGIN); + list.append("ObjectViewer"); + return list; } void MyPlugin::addAutoReleasedObject(QObject *obj) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h index 081dfda89..f09ec8fa2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h @@ -43,7 +43,7 @@ public: QString version() const; QString vendor() const; QString description() const; - QList dependencies() const; + QStringList dependencies() const; void addAutoReleasedObject(QObject *obj); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp index 20f60c1a6..e300c8fa7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp @@ -65,9 +65,11 @@ QString ObjectViewerPlugin::description() const return "Object Viewer plugin."; } -QList ObjectViewerPlugin::dependencies() const +QStringList ObjectViewerPlugin::dependencies() const { - return QList(); + QStringList list; + list.append(Core::Constants::OVQT_CORE_PLUGIN); + return list; } void ObjectViewerPlugin::addAutoReleasedObject(QObject *obj) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h index 6ecb7668d..5c4b76afb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h @@ -42,7 +42,7 @@ public: QString version() const; QString vendor() const; QString description() const; - QList dependencies() const; + QStringList dependencies() const; void addAutoReleasedObject(QObject *obj); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_control_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_control_dialog.cpp index a6abdc5e3..c0fee6b05 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_control_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_control_dialog.cpp @@ -161,15 +161,15 @@ void CParticleControlDialog::updateCount() // display number of particles for the currently active node _ui.numParticlesSpinBox->setValue(currNumParticles); - + // display max number of wanted faces NLMISC::CMatrix camMat = ps->getScene()->getCam()->getMatrix(); sint numWantedFaces = (uint) ps->getWantedNumTris((ps->getSysMat().getPos() - camMat.getPos()).norm()); _ui.numWantedFacesSpinBox->setValue(numWantedFaces); - + // display system date _ui.timeDoubleSpinBox->setValue(ps->getSystemDate()); - + Q_EMIT changeCount(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/settings_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/settings_dialog.cpp index 1d712eac5..17a63387c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/settings_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/settings_dialog.cpp @@ -46,7 +46,7 @@ CSettingsDialog::CSettingsDialog(QWidget *parent) loadGraphicsSettings(); loadSoundSettings(); -loadVegetableSettings(); + loadVegetableSettings(); connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(applyPressed()));