Changed: #1193 Now plugin system reads plugin information from plugin-spec file(ovqt_plugin_*.xml) for each plugin.
This commit is contained in:
parent
ab4468c48f
commit
2eac5ab064
7 changed files with 222 additions and 125 deletions
|
@ -95,12 +95,6 @@ public:
|
||||||
@endcode
|
@endcode
|
||||||
*/
|
*/
|
||||||
virtual void setNelContext(NLMISC::INelContext *nelContext) = 0;
|
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 QStringList dependencies() const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}; //namespace ExtensionSystem
|
}; //namespace ExtensionSystem
|
||||||
|
|
|
@ -37,8 +37,8 @@ struct State
|
||||||
{
|
{
|
||||||
Invalid = 1,
|
Invalid = 1,
|
||||||
Read,
|
Read,
|
||||||
Loaded,
|
|
||||||
Resolved,
|
Resolved,
|
||||||
|
Loaded,
|
||||||
Initialized,
|
Initialized,
|
||||||
Running,
|
Running,
|
||||||
Stopped,
|
Stopped,
|
||||||
|
|
|
@ -26,13 +26,14 @@
|
||||||
namespace ExtensionSystem
|
namespace ExtensionSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
CPluginManager::CPluginManager(QObject *parent)
|
PluginManager::PluginManager(QObject *parent)
|
||||||
:IPluginManager(parent),
|
:IPluginManager(parent),
|
||||||
m_settings(0)
|
m_settings(0),
|
||||||
|
m_extension("xml")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CPluginManager::~CPluginManager()
|
PluginManager::~PluginManager()
|
||||||
{
|
{
|
||||||
writeSettings();
|
writeSettings();
|
||||||
stopAll();
|
stopAll();
|
||||||
|
@ -40,7 +41,7 @@ CPluginManager::~CPluginManager()
|
||||||
qDeleteAll(m_pluginSpecs);
|
qDeleteAll(m_pluginSpecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::addObject(QObject *obj)
|
void PluginManager::addObject(QObject *obj)
|
||||||
{
|
{
|
||||||
QWriteLocker lock(&m_lock);
|
QWriteLocker lock(&m_lock);
|
||||||
if (obj == 0)
|
if (obj == 0)
|
||||||
|
@ -60,7 +61,7 @@ void CPluginManager::addObject(QObject *obj)
|
||||||
Q_EMIT objectAdded(obj);
|
Q_EMIT objectAdded(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::removeObject(QObject *obj)
|
void PluginManager::removeObject(QObject *obj)
|
||||||
{
|
{
|
||||||
if (obj == 0)
|
if (obj == 0)
|
||||||
{
|
{
|
||||||
|
@ -80,25 +81,25 @@ void CPluginManager::removeObject(QObject *obj)
|
||||||
m_allObjects.removeAll(obj);
|
m_allObjects.removeAll(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QObject *> CPluginManager::allObjects() const
|
QList<QObject *> PluginManager::allObjects() const
|
||||||
{
|
{
|
||||||
return m_allObjects;
|
return m_allObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::loadPlugins()
|
void PluginManager::loadPlugins()
|
||||||
{
|
{
|
||||||
Q_FOREACH (CPluginSpec *spec, m_pluginSpecs)
|
Q_FOREACH (PluginSpec *spec, m_pluginSpecs)
|
||||||
setPluginState(spec, State::Loaded);
|
|
||||||
|
|
||||||
Q_FOREACH (CPluginSpec *spec, m_pluginSpecs)
|
|
||||||
setPluginState(spec, State::Resolved);
|
setPluginState(spec, State::Resolved);
|
||||||
|
|
||||||
QList<CPluginSpec *> queue = loadQueue();
|
QList<PluginSpec *> queue = loadQueue();
|
||||||
|
|
||||||
Q_FOREACH (CPluginSpec *spec, queue)
|
Q_FOREACH (PluginSpec *spec, queue)
|
||||||
|
setPluginState(spec, State::Loaded);
|
||||||
|
|
||||||
|
Q_FOREACH (PluginSpec *spec, queue)
|
||||||
setPluginState(spec, State::Initialized);
|
setPluginState(spec, State::Initialized);
|
||||||
|
|
||||||
QListIterator<CPluginSpec *> it(queue);
|
QListIterator<PluginSpec *> it(queue);
|
||||||
it.toBack();
|
it.toBack();
|
||||||
while (it.hasPrevious())
|
while (it.hasPrevious())
|
||||||
setPluginState(it.previous(), State::Running);
|
setPluginState(it.previous(), State::Running);
|
||||||
|
@ -106,34 +107,34 @@ void CPluginManager::loadPlugins()
|
||||||
Q_EMIT pluginsChanged();
|
Q_EMIT pluginsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList CPluginManager::getPluginPaths() const
|
QStringList PluginManager::getPluginPaths() const
|
||||||
{
|
{
|
||||||
return m_pluginPaths;
|
return m_pluginPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::setPluginPaths(const QStringList &paths)
|
void PluginManager::setPluginPaths(const QStringList &paths)
|
||||||
{
|
{
|
||||||
m_pluginPaths = paths;
|
m_pluginPaths = paths;
|
||||||
readPluginPaths();
|
readPluginPaths();
|
||||||
readSettings();
|
readSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<IPluginSpec *> CPluginManager::plugins() const
|
QList<IPluginSpec *> PluginManager::plugins() const
|
||||||
{
|
{
|
||||||
return m_ipluginSpecs;
|
return m_ipluginSpecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::setSettings(QSettings *settings)
|
void PluginManager::setSettings(QSettings *settings)
|
||||||
{
|
{
|
||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSettings *CPluginManager::settings() const
|
QSettings *PluginManager::settings() const
|
||||||
{
|
{
|
||||||
return m_settings;
|
return m_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::readSettings()
|
void PluginManager::readSettings()
|
||||||
{
|
{
|
||||||
if (m_settings)
|
if (m_settings)
|
||||||
{
|
{
|
||||||
|
@ -141,7 +142,7 @@ void CPluginManager::readSettings()
|
||||||
m_settings->beginGroup("PluginManager");
|
m_settings->beginGroup("PluginManager");
|
||||||
blackList = m_settings->value("BlackList").toStringList();
|
blackList = m_settings->value("BlackList").toStringList();
|
||||||
m_settings->endGroup();
|
m_settings->endGroup();
|
||||||
Q_FOREACH (CPluginSpec *spec, m_pluginSpecs)
|
Q_FOREACH (PluginSpec *spec, m_pluginSpecs)
|
||||||
{
|
{
|
||||||
QString pluginName = spec->fileName();
|
QString pluginName = spec->fileName();
|
||||||
|
|
||||||
|
@ -154,14 +155,13 @@ void CPluginManager::readSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::writeSettings()
|
void PluginManager::writeSettings()
|
||||||
{
|
{
|
||||||
if (m_settings)
|
if (m_settings)
|
||||||
{
|
{
|
||||||
QStringList blackList;
|
QStringList blackList;
|
||||||
Q_FOREACH(CPluginSpec *spec, m_pluginSpecs)
|
Q_FOREACH(PluginSpec *spec, m_pluginSpecs)
|
||||||
{
|
{
|
||||||
nlinfo(spec->fileName().toStdString().c_str());
|
|
||||||
if (!spec->isEnabled())
|
if (!spec->isEnabled())
|
||||||
blackList.push_back(spec->fileName());
|
blackList.push_back(spec->fileName());
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ void CPluginManager::writeSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::readPluginPaths()
|
void PluginManager::readPluginPaths()
|
||||||
{
|
{
|
||||||
qDeleteAll(m_pluginSpecs);
|
qDeleteAll(m_pluginSpecs);
|
||||||
m_pluginSpecs.clear();
|
m_pluginSpecs.clear();
|
||||||
|
@ -183,11 +183,7 @@ void CPluginManager::readPluginPaths()
|
||||||
while (!searchPaths.isEmpty())
|
while (!searchPaths.isEmpty())
|
||||||
{
|
{
|
||||||
const QDir dir(searchPaths.takeFirst());
|
const QDir dir(searchPaths.takeFirst());
|
||||||
#ifdef Q_OS_WIN
|
const QFileInfoList files = dir.entryInfoList(QStringList() << QString("ovqt_plugin_*.%1").arg(m_extension), QDir::Files);
|
||||||
const QFileInfoList files = dir.entryInfoList(QStringList() << QString("ovqt_plugin_*.dll"), QDir::Files);
|
|
||||||
#else
|
|
||||||
const QFileInfoList files = dir.entryInfoList(QStringList() << QString("libovqt_plugin_*.so"), QDir::Files);
|
|
||||||
#endif
|
|
||||||
Q_FOREACH (const QFileInfo &file, files)
|
Q_FOREACH (const QFileInfo &file, files)
|
||||||
pluginsList << file.absoluteFilePath();
|
pluginsList << file.absoluteFilePath();
|
||||||
const QFileInfoList dirs = dir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot);
|
const QFileInfoList dirs = dir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot);
|
||||||
|
@ -197,9 +193,9 @@ void CPluginManager::readPluginPaths()
|
||||||
|
|
||||||
Q_FOREACH (const QString &pluginFile, pluginsList)
|
Q_FOREACH (const QString &pluginFile, pluginsList)
|
||||||
{
|
{
|
||||||
CPluginSpec *spec = new CPluginSpec;
|
PluginSpec *spec = new PluginSpec;
|
||||||
spec->setFileName(pluginFile);
|
|
||||||
spec->m_pluginManager = this;
|
spec->m_pluginManager = this;
|
||||||
|
spec->setSpecFileName(pluginFile);
|
||||||
m_pluginSpecs.append(spec);
|
m_pluginSpecs.append(spec);
|
||||||
m_ipluginSpecs.append(spec);
|
m_ipluginSpecs.append(spec);
|
||||||
}
|
}
|
||||||
|
@ -207,7 +203,7 @@ void CPluginManager::readPluginPaths()
|
||||||
Q_EMIT pluginsChanged();
|
Q_EMIT pluginsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::setPluginState(CPluginSpec *spec, int destState)
|
void PluginManager::setPluginState(PluginSpec *spec, int destState)
|
||||||
{
|
{
|
||||||
if (spec->hasError() || spec->state() != destState-1)
|
if (spec->hasError() || spec->state() != destState-1)
|
||||||
return;
|
return;
|
||||||
|
@ -233,7 +229,7 @@ void CPluginManager::setPluginState(CPluginSpec *spec, int destState)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Q_FOREACH (const CPluginSpec *depSpec, spec->dependencySpecs())
|
Q_FOREACH (const PluginSpec *depSpec, spec->dependencySpecs())
|
||||||
{
|
{
|
||||||
if (depSpec->state() != destState)
|
if (depSpec->state() != destState)
|
||||||
{
|
{
|
||||||
|
@ -256,19 +252,19 @@ void CPluginManager::setPluginState(CPluginSpec *spec, int destState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<CPluginSpec *> CPluginManager::loadQueue()
|
QList<PluginSpec *> PluginManager::loadQueue()
|
||||||
{
|
{
|
||||||
QList<CPluginSpec *> queue;
|
QList<PluginSpec *> queue;
|
||||||
Q_FOREACH(CPluginSpec *spec, m_pluginSpecs)
|
Q_FOREACH(PluginSpec *spec, m_pluginSpecs)
|
||||||
{
|
{
|
||||||
QList<CPluginSpec *> circularityCheckQueue;
|
QList<PluginSpec *> circularityCheckQueue;
|
||||||
loadQueue(spec, queue, circularityCheckQueue);
|
loadQueue(spec, queue, circularityCheckQueue);
|
||||||
}
|
}
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginManager::loadQueue(CPluginSpec *spec, QList<CPluginSpec *> &queue,
|
bool PluginManager::loadQueue(PluginSpec *spec, QList<PluginSpec *> &queue,
|
||||||
QList<CPluginSpec *> &circularityCheckQueue)
|
QList<PluginSpec *> &circularityCheckQueue)
|
||||||
{
|
{
|
||||||
if (queue.contains(spec))
|
if (queue.contains(spec))
|
||||||
return true;
|
return true;
|
||||||
|
@ -295,7 +291,7 @@ bool CPluginManager::loadQueue(CPluginSpec *spec, QList<CPluginSpec *> &queue,
|
||||||
}
|
}
|
||||||
|
|
||||||
// add dependencies
|
// add dependencies
|
||||||
Q_FOREACH (CPluginSpec *depSpec, spec->dependencySpecs())
|
Q_FOREACH (PluginSpec *depSpec, spec->dependencySpecs())
|
||||||
{
|
{
|
||||||
if (!loadQueue(depSpec, queue, circularityCheckQueue))
|
if (!loadQueue(depSpec, queue, circularityCheckQueue))
|
||||||
{
|
{
|
||||||
|
@ -311,17 +307,17 @@ bool CPluginManager::loadQueue(CPluginSpec *spec, QList<CPluginSpec *> &queue,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::stopAll()
|
void PluginManager::stopAll()
|
||||||
{
|
{
|
||||||
QList<CPluginSpec *> queue = loadQueue();
|
QList<PluginSpec *> queue = loadQueue();
|
||||||
Q_FOREACH (CPluginSpec *spec, queue)
|
Q_FOREACH (PluginSpec *spec, queue)
|
||||||
setPluginState(spec, State::Stopped);
|
setPluginState(spec, State::Stopped);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::deleteAll()
|
void PluginManager::deleteAll()
|
||||||
{
|
{
|
||||||
QList<CPluginSpec *> queue = loadQueue();
|
QList<PluginSpec *> queue = loadQueue();
|
||||||
QListIterator<CPluginSpec *> it(queue);
|
QListIterator<PluginSpec *> it(queue);
|
||||||
it.toBack();
|
it.toBack();
|
||||||
while (it.hasPrevious())
|
while (it.hasPrevious())
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,15 +29,15 @@ namespace ExtensionSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
class IPlugin;
|
class IPlugin;
|
||||||
class CPluginSpec;
|
class PluginSpec;
|
||||||
|
|
||||||
class CPluginManager : public IPluginManager
|
class PluginManager : public IPluginManager
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CPluginManager(QObject *parent = 0);
|
PluginManager(QObject *parent = 0);
|
||||||
~CPluginManager();
|
~PluginManager();
|
||||||
|
|
||||||
// Object pool operations
|
// Object pool operations
|
||||||
virtual void addObject(QObject *obj);
|
virtual void addObject(QObject *obj);
|
||||||
|
@ -49,7 +49,7 @@ public:
|
||||||
virtual QStringList getPluginPaths() const;
|
virtual QStringList getPluginPaths() const;
|
||||||
virtual void setPluginPaths(const QStringList &paths);
|
virtual void setPluginPaths(const QStringList &paths);
|
||||||
virtual QList<IPluginSpec *> plugins() const;
|
virtual QList<IPluginSpec *> plugins() const;
|
||||||
QList<CPluginSpec *> loadQueue();
|
QList<PluginSpec *> loadQueue();
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
virtual void setSettings(QSettings *settings);
|
virtual void setSettings(QSettings *settings);
|
||||||
|
@ -58,21 +58,22 @@ public:
|
||||||
void writeSettings();
|
void writeSettings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setPluginState(CPluginSpec *spec, int destState);
|
void setPluginState(PluginSpec *spec, int destState);
|
||||||
void readPluginPaths();
|
void readPluginPaths();
|
||||||
bool loadQueue(CPluginSpec *spec, QList<CPluginSpec *> &queue, QList<CPluginSpec *> &circularityCheckQueue);
|
bool loadQueue(PluginSpec *spec, QList<PluginSpec *> &queue, QList<PluginSpec *> &circularityCheckQueue);
|
||||||
void stopAll();
|
void stopAll();
|
||||||
void deleteAll();
|
void deleteAll();
|
||||||
|
|
||||||
mutable QReadWriteLock m_lock;
|
mutable QReadWriteLock m_lock;
|
||||||
|
|
||||||
QSettings *m_settings;
|
QSettings *m_settings;
|
||||||
QList<CPluginSpec *> m_pluginSpecs;
|
QString m_extension;
|
||||||
|
QList<PluginSpec *> m_pluginSpecs;
|
||||||
QList<IPluginSpec *> m_ipluginSpecs;
|
QList<IPluginSpec *> m_ipluginSpecs;
|
||||||
QStringList m_pluginPaths;
|
QStringList m_pluginPaths;
|
||||||
QList<QObject *> m_allObjects;
|
QList<QObject *> m_allObjects;
|
||||||
|
|
||||||
}; // class CPluginManager
|
}; // class PluginManager
|
||||||
|
|
||||||
} // namespace ExtensionSystem
|
} // namespace ExtensionSystem
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,15 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
#include "plugin_spec.h"
|
#include "plugin_spec.h"
|
||||||
#include "iplugin.h"
|
#include "iplugin.h"
|
||||||
#include "iplugin_manager.h"
|
#include "iplugin_manager.h"
|
||||||
|
|
||||||
#include "nel/misc/app_context.h"
|
#include "nel/misc/app_context.h"
|
||||||
|
#include "nel/misc/debug.h"
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
|
@ -30,8 +33,17 @@
|
||||||
|
|
||||||
namespace ExtensionSystem
|
namespace ExtensionSystem
|
||||||
{
|
{
|
||||||
|
const char *const PLUGIN_SPEC_NAME = "name";
|
||||||
|
const char *const PLUGIN_SPEC_VENDOR = "vendor";
|
||||||
|
const char *const PLUGIN_SPEC_VERSION = "version";
|
||||||
|
const char *const PLUGIN_SPEC_LIBRARY_NAME = "library-name";
|
||||||
|
const char *const PLUGIN_SPEC_DESCRIPTION = "description";
|
||||||
|
const char *const PLUGIN_SPEC_DEPENDENCIES = "dependencies";
|
||||||
|
const char *const PLUGIN_SPEC_DEPENDENCY = "dependency";
|
||||||
|
const char *const PLUGIN_SPEC_DEPENDENCY_NAME = "plugin-name";
|
||||||
|
const char *const PLUGIN_SPEC_DEPENDENCY_VERSION = "version";
|
||||||
|
|
||||||
CPluginSpec::CPluginSpec()
|
PluginSpec::PluginSpec()
|
||||||
: m_location(""),
|
: m_location(""),
|
||||||
m_filePath(""),
|
m_filePath(""),
|
||||||
m_fileName(""),
|
m_fileName(""),
|
||||||
|
@ -39,6 +51,8 @@ CPluginSpec::CPluginSpec()
|
||||||
m_version(""),
|
m_version(""),
|
||||||
m_vendor(""),
|
m_vendor(""),
|
||||||
m_description(""),
|
m_description(""),
|
||||||
|
m_nameSpecFile(""),
|
||||||
|
m_suffix(""),
|
||||||
m_state(State::Invalid),
|
m_state(State::Invalid),
|
||||||
m_enabled(true),
|
m_enabled(true),
|
||||||
m_enabledStartup(true),
|
m_enabledStartup(true),
|
||||||
|
@ -47,104 +61,195 @@ CPluginSpec::CPluginSpec()
|
||||||
m_plugin(0),
|
m_plugin(0),
|
||||||
m_pluginManager(0)
|
m_pluginManager(0)
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
# ifdef DEBUG
|
||||||
|
m_suffix = "_d.dll";
|
||||||
|
# else
|
||||||
|
m_suffix = "_r.dll";
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
m_suffix = ".so";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CPluginSpec::name() const
|
QString PluginSpec::name() const
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CPluginSpec::version() const
|
QString PluginSpec::version() const
|
||||||
{
|
{
|
||||||
return m_version;
|
return m_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CPluginSpec::vendor() const
|
QString PluginSpec::vendor() const
|
||||||
{
|
{
|
||||||
return m_vendor;
|
return m_vendor;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CPluginSpec::description() const
|
QString PluginSpec::description() const
|
||||||
{
|
{
|
||||||
return m_description;
|
return m_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CPluginSpec::location() const
|
QString PluginSpec::location() const
|
||||||
{
|
{
|
||||||
return m_location;
|
return m_location;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CPluginSpec::filePath() const
|
QString PluginSpec::filePath() const
|
||||||
{
|
{
|
||||||
return m_filePath;
|
return m_filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CPluginSpec::fileName() const
|
QString PluginSpec::fileName() const
|
||||||
{
|
{
|
||||||
return m_fileName;
|
return m_fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPlugin *CPluginSpec::plugin() const
|
IPlugin *PluginSpec::plugin() const
|
||||||
{
|
{
|
||||||
return m_plugin;
|
return m_plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CPluginSpec::state() const
|
int PluginSpec::state() const
|
||||||
{
|
{
|
||||||
return m_state;
|
return m_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginSpec::hasError() const
|
bool PluginSpec::hasError() const
|
||||||
{
|
{
|
||||||
return m_hasError;
|
return m_hasError;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CPluginSpec::errorString() const
|
QString PluginSpec::errorString() const
|
||||||
{
|
{
|
||||||
return m_errorString;
|
return m_errorString;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<CPluginSpec *> CPluginSpec::dependencySpecs() const
|
QList<PluginSpec *> PluginSpec::dependencySpecs() const
|
||||||
{
|
{
|
||||||
return m_dependencySpecs;
|
return m_dependencySpecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginSpec::setFileName(const QString &fileName)
|
bool PluginSpec::setFileName(const QString &fileName)
|
||||||
{
|
{
|
||||||
QFile file(fileName);
|
m_fileName = fileName + m_suffix;
|
||||||
|
m_filePath = m_location + "/" + m_fileName;
|
||||||
|
|
||||||
|
nlinfo(m_filePath.toStdString().c_str());
|
||||||
|
QFile file(m_filePath);
|
||||||
if (!file.exists())
|
if (!file.exists())
|
||||||
return reportError(QCoreApplication::translate("CPluginSpec", "File does not exist: %1").arg(file.fileName()));
|
return reportError(QCoreApplication::translate("PluginSpec", "File does not exist: %1").arg(file.fileName()));
|
||||||
if (!file.open(QIODevice::ReadOnly))
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
return reportError(QCoreApplication::translate("CPluginSpec", "Could not open file for read: %1").arg(file.fileName()));
|
return reportError(QCoreApplication::translate("PluginSpec", "Could not open file for read: %1").arg(file.fileName()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PluginSpec::setSpecFileName(const QString &specFileName)
|
||||||
|
{
|
||||||
|
m_nameSpecFile = specFileName;
|
||||||
|
|
||||||
|
QFile file(specFileName);
|
||||||
|
if (!file.exists())
|
||||||
|
return reportError(QCoreApplication::translate("PluginSpec", "Spec file does not exist: %1").arg(file.fileName()));
|
||||||
|
|
||||||
QFileInfo fileInfo(file);
|
QFileInfo fileInfo(file);
|
||||||
m_location = fileInfo.absolutePath();
|
m_location = fileInfo.absolutePath();
|
||||||
m_filePath = fileInfo.absoluteFilePath();
|
readSpec();
|
||||||
m_fileName = fileInfo.fileName();
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PluginSpec::readSpec()
|
||||||
|
{
|
||||||
|
QFile file(m_nameSpecFile);
|
||||||
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
|
return reportError(QCoreApplication::translate("PluginSpec", "Could not open spec file for read: %1").arg(file.fileName()));
|
||||||
|
|
||||||
|
QXmlStreamReader reader(&file);
|
||||||
|
while (!reader.atEnd())
|
||||||
|
{
|
||||||
|
if (reader.isStartElement())
|
||||||
|
parseSpec(reader);
|
||||||
|
reader.readNext();
|
||||||
|
}
|
||||||
|
if (reader.hasError())
|
||||||
|
return reportError(QCoreApplication::translate("PluginSpec", "Error parsing file %1: %2, at line %3, column %4")
|
||||||
|
.arg(file.fileName())
|
||||||
|
.arg(reader.errorString())
|
||||||
|
.arg(reader.lineNumber())
|
||||||
|
.arg(reader.columnNumber()));
|
||||||
m_state = State::Read;
|
m_state = State::Read;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginSpec::setEnabled(bool enabled)
|
void PluginSpec::parseSpec(QXmlStreamReader &reader)
|
||||||
|
{
|
||||||
|
QString elemName = reader.name().toString();
|
||||||
|
reader.readNext();
|
||||||
|
if (reader.isCharacters())
|
||||||
|
{
|
||||||
|
QString elemText = reader.text().toString();
|
||||||
|
if (elemName == PLUGIN_SPEC_LIBRARY_NAME)
|
||||||
|
setFileName(elemText);
|
||||||
|
if (elemName == PLUGIN_SPEC_NAME)
|
||||||
|
m_name = elemText;
|
||||||
|
if (elemName == PLUGIN_SPEC_VERSION)
|
||||||
|
m_version = elemText;
|
||||||
|
if (elemName == PLUGIN_SPEC_VENDOR)
|
||||||
|
m_vendor = elemText;
|
||||||
|
if (elemName == PLUGIN_SPEC_DESCRIPTION)
|
||||||
|
m_description = elemText;
|
||||||
|
if (elemName == PLUGIN_SPEC_DEPENDENCIES)
|
||||||
|
parseDependency(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginSpec::parseDependency(QXmlStreamReader &reader)
|
||||||
|
{
|
||||||
|
QString elemName;
|
||||||
|
while (!reader.atEnd() && (elemName != PLUGIN_SPEC_DEPENDENCIES))
|
||||||
|
{
|
||||||
|
reader.readNext();
|
||||||
|
elemName = reader.name().toString();
|
||||||
|
if (reader.isStartElement() && (elemName == PLUGIN_SPEC_DEPENDENCY))
|
||||||
|
{
|
||||||
|
// Read name dependency plugin
|
||||||
|
QString dependencyName = reader.attributes().value(PLUGIN_SPEC_DEPENDENCY_NAME).toString();
|
||||||
|
if (dependencyName.isEmpty())
|
||||||
|
{
|
||||||
|
reader.raiseError(QCoreApplication::translate("CPluginSpec", "'%1' misses attribute '%2'")
|
||||||
|
.arg(PLUGIN_SPEC_DEPENDENCY)
|
||||||
|
.arg(PLUGIN_SPEC_DEPENDENCY_NAME));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Read version dependency plugin
|
||||||
|
QString dependencyVersion = reader.attributes().value(PLUGIN_SPEC_DEPENDENCY_VERSION).toString();
|
||||||
|
|
||||||
|
m_dependencies.push_back(dependencyName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginSpec::setEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
m_enabled = enabled;
|
m_enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginSpec::isEnabled() const
|
bool PluginSpec::isEnabled() const
|
||||||
{
|
{
|
||||||
return m_enabled;
|
return m_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginSpec::loadLibrary()
|
bool PluginSpec::loadLibrary()
|
||||||
{
|
{
|
||||||
if (m_hasError)
|
if (m_hasError)
|
||||||
return false;
|
return false;
|
||||||
if (m_state != State::Read)
|
if (m_state != State::Resolved)
|
||||||
{
|
{
|
||||||
if (m_state == State::Loaded)
|
if (m_state == State::Loaded)
|
||||||
return true;
|
return true;
|
||||||
return reportError(QCoreApplication::translate("CPluginSpec", "Loading the library failed because state != Resolved"));
|
return reportError(QCoreApplication::translate("PluginSpec", "Loading the library failed because state != Resolved"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QPluginLoader loader(m_filePath);
|
QPluginLoader loader(m_filePath);
|
||||||
|
@ -155,38 +260,32 @@ bool CPluginSpec::loadLibrary()
|
||||||
if (!pluginObject)
|
if (!pluginObject)
|
||||||
{
|
{
|
||||||
loader.unload();
|
loader.unload();
|
||||||
return reportError(QCoreApplication::translate("CPluginSpec", "Plugin is not valid (does not derive from IPlugin)"));
|
return reportError(QCoreApplication::translate("PluginSpec", "Plugin is not valid (does not derive from IPlugin)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginObject->setNelContext(&NLMISC::INelContext::getInstance());
|
pluginObject->setNelContext(&NLMISC::INelContext::getInstance());
|
||||||
|
|
||||||
m_name = pluginObject->name();
|
|
||||||
m_version = pluginObject->version();
|
|
||||||
m_vendor = pluginObject->vendor();
|
|
||||||
m_description = pluginObject->description();
|
|
||||||
|
|
||||||
m_state = State::Loaded;
|
m_state = State::Loaded;
|
||||||
m_plugin = pluginObject;
|
m_plugin = pluginObject;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginSpec::resolveDependencies(const QList<CPluginSpec *> &specs)
|
bool PluginSpec::resolveDependencies(const QList<PluginSpec *> &specs)
|
||||||
{
|
{
|
||||||
if (m_hasError)
|
if (m_hasError)
|
||||||
return false;
|
return false;
|
||||||
if (m_state != State::Loaded)
|
if (m_state != State::Read)
|
||||||
{
|
{
|
||||||
m_errorString = QCoreApplication::translate("CPluginSpec", "Resolving dependencies failed because state != Read");
|
m_errorString = QCoreApplication::translate("PluginSpec", "Resolving dependencies failed because state != Read");
|
||||||
m_hasError = true;
|
m_hasError = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QList<CPluginSpec *> resolvedDependencies;
|
QList<PluginSpec *> resolvedDependencies;
|
||||||
QStringList dependencies = m_plugin->dependencies();
|
Q_FOREACH(const QString &dependency, m_dependencies)
|
||||||
Q_FOREACH(const QString &dependency, dependencies)
|
|
||||||
{
|
{
|
||||||
CPluginSpec *found = 0;
|
PluginSpec *found = 0;
|
||||||
|
|
||||||
Q_FOREACH(CPluginSpec *spec, specs)
|
Q_FOREACH(PluginSpec *spec, specs)
|
||||||
{
|
{
|
||||||
if (QString::compare(dependency, spec->name(), Qt::CaseInsensitive) == 0)
|
if (QString::compare(dependency, spec->name(), Qt::CaseInsensitive) == 0)
|
||||||
{
|
{
|
||||||
|
@ -199,7 +298,7 @@ bool CPluginSpec::resolveDependencies(const QList<CPluginSpec *> &specs)
|
||||||
m_hasError = true;
|
m_hasError = true;
|
||||||
if (!m_errorString.isEmpty())
|
if (!m_errorString.isEmpty())
|
||||||
m_errorString.append(QLatin1Char('\n'));
|
m_errorString.append(QLatin1Char('\n'));
|
||||||
m_errorString.append(QCoreApplication::translate("CPluginSpec", "Could not resolve dependency '%1'")
|
m_errorString.append(QCoreApplication::translate("PluginSpec", "Could not resolve dependency '%1'")
|
||||||
.arg(dependency));
|
.arg(dependency));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -209,34 +308,32 @@ bool CPluginSpec::resolveDependencies(const QList<CPluginSpec *> &specs)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_dependencySpecs = resolvedDependencies;
|
m_dependencySpecs = resolvedDependencies;
|
||||||
|
|
||||||
m_state = State::Resolved;
|
m_state = State::Resolved;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginSpec::initializePlugin()
|
bool PluginSpec::initializePlugin()
|
||||||
{
|
{
|
||||||
if (m_hasError)
|
if (m_hasError)
|
||||||
return false;
|
return false;
|
||||||
if (m_state != State::Resolved)
|
if (m_state != State::Loaded)
|
||||||
{
|
{
|
||||||
if (m_state == State::Initialized)
|
if (m_state == State::Initialized)
|
||||||
return true;
|
return true;
|
||||||
return reportError(QCoreApplication::translate("CPluginSpec", "Initializing the plugin failed because state != Resolved)"));
|
return reportError(QCoreApplication::translate("PluginSpec", "Initializing the plugin failed because state != Loaded)"));
|
||||||
}
|
}
|
||||||
if (!m_plugin)
|
if (!m_plugin)
|
||||||
return reportError(QCoreApplication::translate("CPluginSpec", "Internal error: have no plugin instance to initialize"));
|
return reportError(QCoreApplication::translate("PluginSpec", "Internal error: have no plugin instance to initialize"));
|
||||||
|
|
||||||
QString err;
|
QString err;
|
||||||
if (!m_plugin->initialize(m_pluginManager, &err))
|
if (!m_plugin->initialize(m_pluginManager, &err))
|
||||||
return reportError(QCoreApplication::translate("CPluginSpec", "Plugin initialization failed: %1").arg(err));
|
return reportError(QCoreApplication::translate("PluginSpec", "Plugin initialization failed: %1").arg(err));
|
||||||
|
|
||||||
m_state = State::Initialized;
|
m_state = State::Initialized;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginSpec::initializeExtensions()
|
bool PluginSpec::initializeExtensions()
|
||||||
{
|
{
|
||||||
if (m_hasError)
|
if (m_hasError)
|
||||||
return false;
|
return false;
|
||||||
|
@ -244,17 +341,17 @@ bool CPluginSpec::initializeExtensions()
|
||||||
{
|
{
|
||||||
if (m_state == State::Running)
|
if (m_state == State::Running)
|
||||||
return true;
|
return true;
|
||||||
return reportError(QCoreApplication::translate("CPluginSpec", "Cannot perform extensionsInitialized because state != Initialized"));
|
return reportError(QCoreApplication::translate("PluginSpec", "Cannot perform extensionsInitialized because state != Initialized"));
|
||||||
}
|
}
|
||||||
if (!m_plugin)
|
if (!m_plugin)
|
||||||
return reportError(QCoreApplication::translate("CPluginSpec", "Internal error: have no plugin instance to perform extensionsInitialized"));
|
return reportError(QCoreApplication::translate("PluginSpec", "Internal error: have no plugin instance to perform extensionsInitialized"));
|
||||||
|
|
||||||
m_plugin->extensionsInitialized();
|
m_plugin->extensionsInitialized();
|
||||||
m_state = State::Running;
|
m_state = State::Running;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginSpec::stop()
|
void PluginSpec::stop()
|
||||||
{
|
{
|
||||||
if (!m_plugin)
|
if (!m_plugin)
|
||||||
return;
|
return;
|
||||||
|
@ -262,7 +359,7 @@ void CPluginSpec::stop()
|
||||||
m_state = State::Stopped;
|
m_state = State::Stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginSpec::kill()
|
void PluginSpec::kill()
|
||||||
{
|
{
|
||||||
if (!m_plugin)
|
if (!m_plugin)
|
||||||
return;
|
return;
|
||||||
|
@ -271,17 +368,17 @@ void CPluginSpec::kill()
|
||||||
m_state = State::Deleted;
|
m_state = State::Deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginSpec::setEnabledStartup(bool enabled)
|
void PluginSpec::setEnabledStartup(bool enabled)
|
||||||
{
|
{
|
||||||
m_enabledStartup = enabled;
|
m_enabledStartup = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginSpec::isEnabledStartup() const
|
bool PluginSpec::isEnabledStartup() const
|
||||||
{
|
{
|
||||||
return m_enabledStartup;
|
return m_enabledStartup;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginSpec::reportError(const QString &err)
|
bool PluginSpec::reportError(const QString &err)
|
||||||
{
|
{
|
||||||
m_errorString = err;
|
m_errorString = err;
|
||||||
m_hasError = true;
|
m_hasError = true;
|
||||||
|
|
|
@ -21,12 +21,14 @@
|
||||||
|
|
||||||
#include "iplugin_spec.h"
|
#include "iplugin_spec.h"
|
||||||
|
|
||||||
#include "QtCore/QList"
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtCore/QXmlStreamReader>
|
||||||
|
|
||||||
namespace ExtensionSystem
|
namespace ExtensionSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
class CPluginSpec: public IPluginSpec
|
class PluginSpec: public IPluginSpec
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual QString name() const;
|
virtual QString name() const;
|
||||||
|
@ -44,18 +46,22 @@ public:
|
||||||
virtual int state() const;
|
virtual int state() const;
|
||||||
virtual bool hasError() const;
|
virtual bool hasError() const;
|
||||||
virtual QString errorString() const;
|
virtual QString errorString() const;
|
||||||
QList<CPluginSpec *> dependencySpecs() const;
|
QList<PluginSpec *> dependencySpecs() const;
|
||||||
|
|
||||||
/// Enables/disables load this plugin after restart the program
|
/// Enables/disables load this plugin after restart the program
|
||||||
virtual void setEnabled(bool enabled);
|
virtual void setEnabled(bool enabled);
|
||||||
virtual bool isEnabled() const;
|
virtual bool isEnabled() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CPluginSpec();
|
PluginSpec();
|
||||||
|
|
||||||
bool setFileName(const QString &fileName);
|
bool setFileName(const QString &fileName);
|
||||||
|
bool setSpecFileName(const QString &specFileName);
|
||||||
|
bool readSpec();
|
||||||
|
void parseSpec(QXmlStreamReader &reader);
|
||||||
|
void parseDependency(QXmlStreamReader &reader);
|
||||||
bool loadLibrary();
|
bool loadLibrary();
|
||||||
bool resolveDependencies(const QList<CPluginSpec *> &specs);
|
bool resolveDependencies(const QList<PluginSpec *> &specs);
|
||||||
bool initializePlugin();
|
bool initializePlugin();
|
||||||
bool initializeExtensions();
|
bool initializeExtensions();
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -77,16 +83,19 @@ private:
|
||||||
QString m_vendor;
|
QString m_vendor;
|
||||||
QString m_description;
|
QString m_description;
|
||||||
|
|
||||||
|
QString m_nameSpecFile;
|
||||||
|
QString m_suffix;
|
||||||
int m_state;
|
int m_state;
|
||||||
bool m_enabled, m_enabledStartup;
|
bool m_enabled, m_enabledStartup;
|
||||||
bool m_hasError;
|
bool m_hasError;
|
||||||
QString m_errorString;
|
QString m_errorString;
|
||||||
|
QStringList m_dependencies;
|
||||||
|
|
||||||
IPlugin *m_plugin;
|
IPlugin *m_plugin;
|
||||||
IPluginManager *m_pluginManager;
|
IPluginManager *m_pluginManager;
|
||||||
QList<CPluginSpec *> m_dependencySpecs;
|
QList<PluginSpec *> m_dependencySpecs;
|
||||||
|
|
||||||
friend class CPluginManager;
|
friend class PluginManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ExtensionSystem
|
} // namespace ExtensionSystem
|
||||||
|
|
|
@ -148,7 +148,7 @@ sint main(int argc, char **argv)
|
||||||
NLMISC::CLibrary::addLibPath((qApp->applicationDirPath() + QString("/../PlugIns/nel")).toStdString());
|
NLMISC::CLibrary::addLibPath((qApp->applicationDirPath() + QString("/../PlugIns/nel")).toStdString());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ExtensionSystem::CPluginManager pluginManager;
|
ExtensionSystem::PluginManager pluginManager;
|
||||||
pluginManager.setSettings(settings);
|
pluginManager.setSettings(settings);
|
||||||
QStringList pluginPaths;
|
QStringList pluginPaths;
|
||||||
#if !defined(NL_OS_MAC)
|
#if !defined(NL_OS_MAC)
|
||||||
|
|
Loading…
Reference in a new issue