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+
1116namespace QtNodes {
1217
1318PluginsManager *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,36 @@ 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+ SetDllDirectory (folderPath.toStdWString ().c_str ());
102+ #endif
103+ loadPluginFromPath (it.filePath ());
104+
105+ #if defined(Q_OS_WIN)
106+ SetDllDirectory (NULL );
107+ #endif
60108 }
61109 }
62110}
@@ -72,12 +120,11 @@ void PluginsManager::unloadPlugins()
72120
73121PluginInterface *PluginsManager::loadPluginFromPath (const QString &filePath)
74122{
75- // if (!QLibrary::isLibrary(filePath))
76- // return nullptr;
123+ qInfo () << " >> " << filePath;
77124
78125 QPluginLoader *loader = new QPluginLoader (filePath);
79126
80- qDebug () << loader->metaData ();
127+ // qDebug() << loader->metaData();
81128
82129 if (loader->isLoaded ()) {
83130 PluginInterface *plugin = qobject_cast<PluginInterface *>(loader->instance ());
@@ -105,12 +152,30 @@ PluginInterface *PluginsManager::loadPluginFromPath(const QString &filePath)
105152 return nullptr ;
106153}
107154
108- std::vector<PluginInterface *> PluginsManager::loadPluginFromPaths (const QStringList filePaths)
155+ std::vector<PluginInterface *> PluginsManager::loadPluginFromPaths (const QStringList filePaths,
156+ const QStringList &nameFilters)
109157{
110158 std::vector<PluginInterface *> vecPlugins;
111159 vecPlugins.clear ();
160+
161+ auto IsLibrary = [](const QFileInfo f, const QStringList &nameFilters) {
162+ if (!f.isFile ())
163+ return false ;
164+
165+ if (nameFilters.isEmpty ())
166+ return QLibrary::isLibrary (f.absoluteFilePath ());
167+
168+ for (auto nf : nameFilters) {
169+ if (nf.endsWith (f.suffix (), Qt::CaseInsensitive))
170+ return true ;
171+ }
172+ return false ;
173+ };
174+
112175 for (auto path : filePaths) {
113- vecPlugins.push_back (loadPluginFromPath (path));
176+ QFileInfo f (path);
177+ if (IsLibrary (f, nameFilters))
178+ vecPlugins.push_back (loadPluginFromPath (path));
114179 }
115180 return vecPlugins;
116181}
0 commit comments