##// END OF EJS Templates
Some minor improvements on plugin loading:...
Some minor improvements on plugin loading: SciQLOP now looks recursively into a list of path and only tries to load dynamic library files. Signed-off-by: Alexis Jeandet <alexis.jeandet@member.fsf.org>

File last commit:

r609:7c40e9303976
r609:7c40e9303976
Show More
PluginManager.cpp
124 lines | 3.8 KiB | text/x-c | CppLexer
/ core / src / Plugin / PluginManager.cpp
Alexandre Leroux
Initializes plugin manager...
r66 #include <Plugin/PluginManager.h>
#include <Plugin/IPlugin.h>
#include <QDir>
Alexandre Leroux
Implements plugin loading method
r67 #include <QLibrary>
#include <QPluginLoader>
Alexandre Leroux
Initializes plugin manager...
r66
Q_LOGGING_CATEGORY(LOG_PluginManager, "PluginManager")
Alexandre Leroux
Implements plugin loading method
r67 namespace {
/// Key for retrieving metadata of the plugin
const auto PLUGIN_METADATA_KEY = QStringLiteral("MetaData");
/// Key for retrieving the name of the plugin in its metadata
const auto PLUGIN_NAME_KEY = QStringLiteral("name");
Alexandre Leroux
Adds logs in plugin loading method
r68 /// Helper to state the plugin loading operation
struct LoadPluginState {
explicit LoadPluginState(const QString &pluginPath)
: m_PluginPath{pluginPath}, m_Valid{true}, m_ErrorMessage{}
{
}
void log() const
{
if (m_Valid) {
qCDebug(LOG_PluginManager())
<< QObject::tr("File '%1' has been loaded as a plugin").arg(m_PluginPath);
}
else {
qCWarning(LOG_PluginManager())
<< QObject::tr("File '%1' can't be loaded as a plugin: %2")
.arg(m_PluginPath)
.arg(m_ErrorMessage);
}
}
void setError(const QString &errorMessage)
{
m_Valid = false;
m_ErrorMessage = errorMessage;
}
QString m_PluginPath;
bool m_Valid;
QString m_ErrorMessage;
};
Alexandre Leroux
Implements plugin loading method
r67 } // namespace
Alexandre Leroux
Initializes plugin manager...
r66 struct PluginManager::PluginManagerPrivate {
Alexandre Leroux
Implements plugin loading method
r67 /**
* Loads a single plugin into SciQlop. The method has no effect if the plugin is malformed (e.g.
* wrong library type, missing metadata, etc.)
* @param pluginPath the path to the plugin library.
*/
void loadPlugin(const QString &pluginPath)
{
qCDebug(LOG_PluginManager())
<< QObject::tr("Attempting to load file '%1' as a plugin").arg(pluginPath);
Alexandre Leroux
Adds logs in plugin loading method
r68 LoadPluginState loadState{pluginPath};
Alexandre Leroux
Implements plugin loading method
r67 if (QLibrary::isLibrary(pluginPath)) {
QPluginLoader pluginLoader{pluginPath};
// Retrieving the plugin name to check if it can be loaded (i.e. no plugin with the same
// name has been registered yet)
auto metadata = pluginLoader.metaData().value(PLUGIN_METADATA_KEY).toObject();
auto pluginName = metadata.value(PLUGIN_NAME_KEY).toString();
if (pluginName.isEmpty()) {
Alexandre Leroux
Adds logs in plugin loading method
r68 loadState.setError(QObject::tr("empty file name"));
Alexandre Leroux
Implements plugin loading method
r67 }
else if (m_RegisteredPlugins.contains(pluginName)) {
Alexandre Leroux
Adds logs in plugin loading method
r68 loadState.setError(QObject::tr("name '%1' already registered").arg(pluginName));
Alexandre Leroux
Implements plugin loading method
r67 }
else {
if (auto pluginInstance = qobject_cast<IPlugin *>(pluginLoader.instance())) {
pluginInstance->initialize();
m_RegisteredPlugins.insert(pluginName, pluginPath);
}
else {
Alexandre Leroux
Adds logs in plugin loading method
r68 loadState.setError(QObject::tr("the file is not a Sciqlop plugin"));
Alexandre Leroux
Implements plugin loading method
r67 }
}
}
else {
Alexandre Leroux
Adds logs in plugin loading method
r68 loadState.setError(QObject::tr("the file is not a library"));
Alexandre Leroux
Implements plugin loading method
r67 }
Alexandre Leroux
Adds logs in plugin loading method
r68
// Log loading result
loadState.log();
Alexandre Leroux
Implements plugin loading method
r67 }
/// Registered plugins (key: plugin name, value: plugin path)
QHash<QString, QString> m_RegisteredPlugins;
Alexandre Leroux
Initializes plugin manager...
r66 };
PluginManager::PluginManager() : impl{spimpl::make_unique_impl<PluginManagerPrivate>()}
{
}
void PluginManager::loadPlugins(const QDir &pluginDir)
{
// Load plugins
Some minor improvements on plugin loading:...
r609 auto pluginInfoList
= pluginDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
for (auto entryInfo : qAsConst(pluginInfoList)) {
if (entryInfo.isDir())
this->loadPlugins(QDir{entryInfo.absoluteFilePath()});
else {
if (QLibrary::isLibrary(entryInfo.absoluteFilePath()))
impl->loadPlugin(entryInfo.absoluteFilePath());
}
Alexandre Leroux
Initializes plugin manager...
r66 }
}
int PluginManager::nbPluginsLoaded() const noexcept
{
Alexandre Leroux
Implements method to get the number of plugins loaded
r69 return impl->m_RegisteredPlugins.size();
Alexandre Leroux
Initializes plugin manager...
r66 }