Skip to content

Commit 49779db

Browse files
committed
add load plugin action , Currently only one path can be added
1 parent 6214f2c commit 49779db

File tree

4 files changed

+107
-63
lines changed

4 files changed

+107
-63
lines changed

examples/plugin_text/PluginDefinition.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
using QtNodes::NodeDelegateModelRegistry;
1616
using QtNodes::PluginInterface;
1717

18-
#define PLUGIN_NAME "plugin_text"
18+
#define PLUGIN_NAME "pluginText"
1919

2020
class DLL_EXPORT Plugin
2121
: public QObject

examples/plugins_load/main.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#include <QApplication>
22
#include <QMenuBar>
33
#include <QVBoxLayout>
4+
#include <QFileDialog>
5+
#include <QObject>
6+
47
#include <QtNodes/DataFlowGraphModel>
58
#include <QtNodes/DataFlowGraphicsScene>
69
#include <QtNodes/GraphicsView>
@@ -44,17 +47,36 @@ main(int argc, char* argv[])
4447
PluginsManager* pluginsManager = PluginsManager::instance();
4548
std::shared_ptr<NodeDelegateModelRegistry> registry = pluginsManager->registry();
4649
pluginsManager->loadPlugins(R"(./nodes)");
47-
for (auto plugin : pluginsManager->pluginList())
50+
for (auto plugin : pluginsManager->plugins())
4851
{
49-
plugin->registerDataModels(registry);
52+
plugin.second->registerDataModels(registry);
5053
}
5154

5255
QWidget mainWidget;
5356

5457
auto menuBar = new QMenuBar();
55-
QMenu* menu = menuBar->addMenu("File");
56-
auto saveAction = menu->addAction("Save Scene");
57-
auto loadAction = menu->addAction("Load Scene");
58+
QMenu* menu = menuBar->addMenu("Plugins");
59+
auto loadAction = menu->addAction("Load Plugin");
60+
auto unloadAction = menu->addAction("Unload Plugin");
61+
62+
QObject::connect(loadAction, &QAction::triggered,
63+
[&]()
64+
{
65+
// TODO: load plugins
66+
QString fileName =
67+
QFileDialog::getOpenFileName(nullptr,
68+
"Load Plugin",
69+
QDir::homePath());
70+
71+
if (!QFileInfo::exists(fileName))
72+
return;
73+
74+
auto plugin = pluginsManager->loadPluginFromPath(fileName);
75+
if (plugin)
76+
{
77+
plugin->registerDataModels(registry);
78+
}
79+
});
5880

5981
QVBoxLayout* l = new QVBoxLayout(&mainWidget);
6082

@@ -69,12 +91,6 @@ main(int argc, char* argv[])
6991
l->setContentsMargins(0, 0, 0, 0);
7092
l->setSpacing(0);
7193

72-
QObject::connect(saveAction, &QAction::triggered,
73-
scene, &DataFlowGraphicsScene::save);
74-
75-
QObject::connect(loadAction, &QAction::triggered,
76-
scene, &DataFlowGraphicsScene::load);
77-
7894
QObject::connect(scene, &DataFlowGraphicsScene::sceneLoaded,
7995
view, &GraphicsView::centerScene);
8096

include/QtNodes/internal/PluginsManager.hpp

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,22 @@
33
#include "Export.hpp"
44
#include "PluginInterface.hpp"
55

6-
#include <QHash>
76
#include <QObject>
87
#include <QPluginLoader>
98
#include <vector>
9+
#include <unordered_map>
1010

1111
namespace QtNodes
1212
{
1313

1414
class NodeDelegateModelRegistry;
1515

16-
/**
17-
* @brief PluginsManager
18-
*
19-
* @code {.cpp}
20-
* PluginsManager *pluginsManager = PluginsManager::instance();
21-
* std::shared_ptr<NodeDelegateModelRegistry> registry = pluginsManager->registry();
22-
* pluginsManager->loadPlugins(R"(./nodes)");
23-
* for (auto plugin : pluginsManager->pluginList())
24-
* {
25-
* plugin->registerDataModels(registry);
26-
* }
27-
* @endcode
28-
*/
2916
class NODE_EDITOR_PUBLIC PluginsManager
3017
{
3118
PluginsManager();
3219

3320
~PluginsManager();
3421

35-
PluginsManager(const PluginsManager &rhs);
36-
37-
const PluginsManager &operator=(const PluginsManager &rhs);
38-
3922
public:
4023

4124
static
@@ -45,33 +28,49 @@ class NODE_EDITOR_PUBLIC PluginsManager
4528
std::shared_ptr<NodeDelegateModelRegistry>
4629
registry();
4730

48-
int
31+
void
4932
loadPlugins(const QString &folderPath = "./plugins");
5033

5134
void
5235
unloadPlugins();
5336

54-
int
37+
/**
38+
* @brief Load the plug-in from the full file path
39+
*
40+
* @param filePath "C:/plugin_text.dll"
41+
* @return PluginInterface*
42+
*/
43+
PluginInterface*
5544
loadPluginFromPath(const QString &filePath);
5645

46+
/**
47+
* @brief Unload the plugin from the full file path
48+
*
49+
* @param filePath "C:/plugin_text.dll"
50+
* @return int
51+
*/
5752
int
5853
unloadPluginFromPath(const QString &filePath);
5954

60-
inline
61-
std::vector<PluginInterface*>
62-
pluginList()
63-
{ return _plugins; };
55+
/**
56+
* @brief Uninstall a plugin by its name, not its file name
57+
*
58+
* @param pluginName "pluginText"
59+
* @return int
60+
*/
61+
int
62+
unloadPluginFromName(const QString &pluginName);
6463

6564
inline
66-
QHash<QString, QPluginLoader*>
67-
loaderList()
68-
{ return _loaders; };
65+
std::unordered_map<QString, PluginInterface*>
66+
plugins()
67+
{ return _plugins; };
6968

7069
private:
7170
static PluginsManager* _instance;
7271

73-
std::vector<PluginInterface*> _plugins;
74-
QHash<QString, QPluginLoader*> _loaders; ///< plugin path
72+
std::unordered_map<QString, PluginInterface*> _plugins;
73+
std::unordered_map<QString, QPluginLoader*> _loaders; ///< plugin path
7574

7675
std::shared_ptr<NodeDelegateModelRegistry> _register;
7776
};

src/PluginsManager.cpp

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <QDir>
77
#include <QPluginLoader>
88
#include <algorithm>
9+
#include <utility>
910

1011
namespace QtNodes
1112
{
@@ -49,7 +50,7 @@ registry()
4950
{ return _register; };
5051

5152

52-
int
53+
void
5354
PluginsManager::
5455
loadPlugins(const QString &folderPath)
5556
{
@@ -68,44 +69,47 @@ loadPlugins(const QString &folderPath)
6869
{
6970
if (fileInfo.isFile())
7071
{
71-
qDebug() << "plugin path: " << fileInfo.absoluteFilePath();
7272
loadPluginFromPath(fileInfo.absoluteFilePath());
7373
}
7474
else
7575
{
7676
loadPlugins(fileInfo.absoluteFilePath());
7777
}
7878
}
79-
return 0;
8079
}
8180

8281

8382
void
8483
PluginsManager::
8584
unloadPlugins()
8685
{
87-
for (QString filePath : _loaders.keys())
88-
unloadPluginFromPath(filePath);
86+
for (auto loadMap : _loaders)
87+
{
88+
unloadPluginFromPath(loadMap.second->fileName());
89+
}
8990
}
9091

9192

92-
int
93+
PluginInterface*
9394
PluginsManager::
9495
loadPluginFromPath(const QString & filePath)
9596
{
9697
if (!QLibrary::isLibrary(filePath))
97-
return -1;
98+
return nullptr;
9899

99100
QPluginLoader* loader = new QPluginLoader(filePath);
100101
if (loader->load())
101102
{
102103
PluginInterface* plugin = qobject_cast<PluginInterface*>(loader->instance());
103104
if (plugin)
104105
{
105-
_plugins.push_back(plugin);
106-
_loaders.insert(filePath, loader);
107-
qDebug() << "add plugin: " << plugin->name();
108-
return 0;
106+
const QString name = plugin->name();
107+
qDebug() << "add plugin: " << name;
108+
109+
_loaders[name] = loader;
110+
_plugins[filePath] = plugin;
111+
112+
return plugin;
109113
}
110114
else
111115
{
@@ -117,29 +121,54 @@ loadPluginFromPath(const QString & filePath)
117121
{
118122
qCritical() << "loadPlugin:" << filePath << loader->errorString();
119123
}
120-
return -1;
124+
return nullptr;
121125
}
122126

123127

124128
int
125129
PluginsManager::
126130
unloadPluginFromPath(const QString & filePath)
127131
{
128-
QPluginLoader* loader = _loaders.value(filePath);
129-
PluginInterface* plugin = qobject_cast<PluginInterface*>(loader->instance());
130-
if (plugin)
132+
auto pluginIter = _plugins.find(filePath);
133+
if(pluginIter != _plugins.end())
131134
{
132-
// TODO: Verification required
133-
_plugins.erase(std::remove(_plugins.begin(), _plugins.end(), plugin), _plugins.end());
135+
auto loaderIter = _loaders.find(pluginIter->second->name());
136+
if(loaderIter != _loaders.end())
137+
{
138+
// delete loader
139+
loaderIter->second->unload();
140+
delete loaderIter->second;
141+
_loaders.erase(loaderIter->first);
142+
}
143+
144+
// delete plugin
145+
_plugins.erase(pluginIter->first);
146+
return 0;
134147
}
148+
return -1;
149+
}
135150

136-
if (loader->unload())
151+
int
152+
PluginsManager::
153+
unloadPluginFromName(const QString &pluginName)
154+
{
155+
auto loaderIter = _loaders.find(pluginName);
156+
if(loaderIter != _loaders.end())
137157
{
138-
_loaders.remove(filePath);
139-
delete loader;
140-
loader = nullptr;
158+
auto pluginIter = _plugins.find(loaderIter->second->fileName());
159+
if(pluginIter != _plugins.end())
160+
{
161+
// delete plugin
162+
_plugins.erase(pluginIter->first);
163+
}
164+
165+
// delete loaders
166+
loaderIter->second->unload();
167+
delete loaderIter->second;
168+
_loaders.erase(loaderIter->first);
169+
return 0;
141170
}
142-
return 0;
171+
return -1;
143172
}
144173

145174
} // namespace QtNodes

0 commit comments

Comments
 (0)