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,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
73125PluginInterface *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