Skip to content

Commit 65a9f44

Browse files
committed
Support for filtering specified suffixes
1 parent 4a74b36 commit 65a9f44

File tree

4 files changed

+96
-24
lines changed

4 files changed

+96
-24
lines changed

examples/plugin_text/CMakeLists.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
foreach(OUTPUT_TYPES ${CMAKE_CONFIGURATION_TYPES})
2-
string(TOUPPER ${OUTPUT_TYPES} OUTPUT_CONFIG)
3-
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUT_CONFIG} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUT_CONFIG}}/plugins)
4-
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUT_CONFIG} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUT_CONFIG}}/plugins)
5-
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUT_CONFIG} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUT_CONFIG}}/plugins)
6-
# message(STATUS "CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUT_CONFIG} : ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUT_CONFIG}}")
2+
string(TOUPPER ${OUTPUT_TYPES} OUTPUT_CONFIG)
3+
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUT_CONFIG} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUT_CONFIG}}/plugins/text)
4+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUT_CONFIG} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUT_CONFIG}}/plugins/text)
5+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUT_CONFIG} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUT_CONFIG}}/plugins/text)
6+
# message(STATUS "CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUT_CONFIG} : ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUT_CONFIG}}")
77
endforeach(OUTPUT_TYPES CMAKE_CONFIGURATION_TYPES)
88

99
file(GLOB_RECURSE CPPS ./*.cpp)

examples/plugins_load/PluginsManagerDlg.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ PluginsManagerDlg::PluginsManagerDlg(QWidget *parent)
2020
{
2121
setMinimumSize(300, 250);
2222

23-
_pluginsFolder.setPath(QDir::cleanPath(QCoreApplication::applicationDirPath()
24-
+ QDir::separator() + R"(./plugins)"));
23+
_pluginsFolder.setPath(
24+
QDir::cleanPath(QCoreApplication::applicationDirPath() + QDir::separator() + "plugins"));
2525

2626
QGridLayout *layout = new QGridLayout();
2727
setLayout(layout);
@@ -47,7 +47,6 @@ PluginsManagerDlg::PluginsManagerDlg(QWidget *parent)
4747
QPushButton *addButton = new QPushButton("+");
4848
layout->addWidget(addButton, 1, 0);
4949
connect(addButton, &QPushButton::clicked, this, [this]() {
50-
// TODO: How to switch different suffixes according to different os
5150
QString fileName
5251
= QFileDialog::getOpenFileName(this,
5352
tr("Load Plugin"),
@@ -135,7 +134,9 @@ void PluginsManagerDlg::loadPluginsFromFolder()
135134
{
136135
PluginsManager *pluginsManager = PluginsManager::instance();
137136
std::shared_ptr<NodeDelegateModelRegistry> registry = pluginsManager->registry();
138-
pluginsManager->loadPlugins(_pluginsFolder.absolutePath());
137+
pluginsManager->loadPlugins(_pluginsFolder.absolutePath(),
138+
QStringList() << "*.node"
139+
<< "*.data");
139140

140141
for (auto l : pluginsManager->loaders()) {
141142
PluginInterface *plugin = qobject_cast<PluginInterface *>(l.second->instance());

include/QtNodes/internal/PluginsManager.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class NODE_EDITOR_PUBLIC PluginsManager
2323

2424
std::shared_ptr<NodeDelegateModelRegistry> registry();
2525

26-
void loadPlugins(const QString &folderPath = "./plugins");
26+
void loadPlugins(const QString &folderPath = "./plugins",
27+
const QStringList &nameFilters = QStringList());
2728

2829
void unloadPlugins();
2930

@@ -35,7 +36,8 @@ class NODE_EDITOR_PUBLIC PluginsManager
3536
*/
3637
PluginInterface *loadPluginFromPath(const QString &filePath);
3738

38-
std::vector<PluginInterface *> loadPluginFromPaths(const QStringList filePaths);
39+
std::vector<PluginInterface *> loadPluginFromPaths(const QStringList filePaths,
40+
const QStringList &nameFilters);
3941

4042
/**
4143
* @brief Unload the plugin from the full file path

src/PluginsManager.cpp

Lines changed: 82 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
66
#include <utility>
77
#include <QDebug>
88
#include <QDir>
9+
#include <QDirIterator>
910
#include <QPluginLoader>
1011

12+
#if defined(Q_OS_WIN)
13+
#include <Windows.h>
14+
#endif
15+
1116
namespace QtNodes {
1217

1318
PluginsManager *PluginsManager::_instance = nullptr;
@@ -40,7 +45,28 @@ std::shared_ptr<NodeDelegateModelRegistry> PluginsManager::registry()
4045
return _register;
4146
}
4247

43-
void PluginsManager::loadPlugins(const QString &folderPath)
48+
/**
49+
* @brief Recursively loads all plugins with the specified suffix according to the folder path.
50+
* If no suffix is specified then the choice is up to the OS. For example, Windows OS selects `*.dll`
51+
*
52+
* ```
53+
* │ plugins_load
54+
* │ QtNodes.dll
55+
* │
56+
* └─plugins
57+
* │
58+
* └─text
59+
* plugin_text.node
60+
* text_dependent.dll
61+
* ```
62+
* @TODO: Currently only tested and passed under windows, is there a solution for Qt for all three platforms?
63+
* 1. `plugins_Load` can successfully load `plugin_text.node`
64+
* 2. After changing the folder name `text` it still loads successfully
65+
*
66+
* @param folderPath
67+
* @param nameFilters
68+
*/
69+
void PluginsManager::loadPlugins(const QString &folderPath, const QStringList &nameFilters)
4470
{
4571
QDir pluginsDir;
4672
if (!pluginsDir.exists(folderPath)) {
@@ -49,14 +75,40 @@ void PluginsManager::loadPlugins(const QString &folderPath)
4975
}
5076
pluginsDir.cd(folderPath);
5177

52-
QFileInfoList pluginsInfo = pluginsDir.entryInfoList(QDir::Dirs | QDir::Files
53-
| QDir::NoDotAndDotDot | QDir::Hidden);
78+
auto IsLibrary = [](const QFileInfo f, const QStringList &nameFilters) {
79+
if (!f.isFile())
80+
return false;
81+
82+
if (nameFilters.isEmpty())
83+
return QLibrary::isLibrary(f.absoluteFilePath());
5484

55-
for (QFileInfo fileInfo : pluginsInfo) {
56-
if (fileInfo.isFile()) {
57-
loadPluginFromPath(fileInfo.absoluteFilePath());
58-
} else {
59-
loadPlugins(fileInfo.absoluteFilePath());
85+
for (auto s : nameFilters) {
86+
if (s.endsWith(f.suffix(), Qt::CaseInsensitive))
87+
return true;
88+
}
89+
return false;
90+
};
91+
92+
QDirIterator it(pluginsDir.path(),
93+
QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden);
94+
while (it.hasNext()) {
95+
it.next();
96+
QFileInfo f = it.fileInfo();
97+
if (f.isDir()) {
98+
loadPlugins(it.filePath(), nameFilters);
99+
} else if (f.isFile() && IsLibrary(f, nameFilters)) {
100+
#if defined(Q_OS_WIN)
101+
#ifdef UNICODE
102+
SetDllDirectory(folderPath.toStdWString().c_str());
103+
#else
104+
SetDllDirectory(folderPath.toStdString().c_str());
105+
#endif // !UNICODE
106+
#endif
107+
loadPluginFromPath(it.filePath());
108+
109+
#if defined(Q_OS_WIN)
110+
SetDllDirectory(NULL);
111+
#endif
60112
}
61113
}
62114
}
@@ -72,12 +124,11 @@ void PluginsManager::unloadPlugins()
72124

73125
PluginInterface *PluginsManager::loadPluginFromPath(const QString &filePath)
74126
{
75-
// if (!QLibrary::isLibrary(filePath))
76-
// return nullptr;
127+
qInfo() << " >> " << filePath;
77128

78129
QPluginLoader *loader = new QPluginLoader(filePath);
79130

80-
qDebug() << loader->metaData();
131+
// qDebug() << loader->metaData();
81132

82133
if (loader->isLoaded()) {
83134
PluginInterface *plugin = qobject_cast<PluginInterface *>(loader->instance());
@@ -105,12 +156,30 @@ PluginInterface *PluginsManager::loadPluginFromPath(const QString &filePath)
105156
return nullptr;
106157
}
107158

108-
std::vector<PluginInterface *> PluginsManager::loadPluginFromPaths(const QStringList filePaths)
159+
std::vector<PluginInterface *> PluginsManager::loadPluginFromPaths(const QStringList filePaths,
160+
const QStringList &nameFilters)
109161
{
110162
std::vector<PluginInterface *> vecPlugins;
111163
vecPlugins.clear();
164+
165+
auto IsLibrary = [](const QFileInfo f, const QStringList &nameFilters) {
166+
if (!f.isFile())
167+
return false;
168+
169+
if (nameFilters.isEmpty())
170+
return QLibrary::isLibrary(f.absoluteFilePath());
171+
172+
for (auto nf : nameFilters) {
173+
if (nf.endsWith(f.suffix(), Qt::CaseInsensitive))
174+
return true;
175+
}
176+
return false;
177+
};
178+
112179
for (auto path : filePaths) {
113-
vecPlugins.push_back(loadPluginFromPath(path));
180+
QFileInfo f(path);
181+
if (IsLibrary(f, nameFilters))
182+
vecPlugins.push_back(loadPluginFromPath(path));
114183
}
115184
return vecPlugins;
116185
}

0 commit comments

Comments
 (0)