Skip to content

Commit f8c2012

Browse files
committed
Plugin manager: simplifies code, fixes a crash on exit
1 parent 41b7dc3 commit f8c2012

File tree

4 files changed

+85
-87
lines changed

4 files changed

+85
-87
lines changed

PluginManager.cpp

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ void PluginManager::AddPlugin(const filesystem::path& path)
200200
entry.info = info;
201201
entry.plugin = plugin;
202202
entry.loader = loader;
203-
entry.loaded = false;
204203
entry.path = path_string;
205204
entry.enabled = enabled;
206205
entry.widget = nullptr;
@@ -209,7 +208,7 @@ void PluginManager::AddPlugin(const filesystem::path& path)
209208

210209
loader->unload();
211210

212-
PluginManager::ActivePlugins.push_back(entry);
211+
ActivePlugins.push_back(entry);
213212

214213
if(entry.enabled)
215214
{
@@ -236,7 +235,6 @@ void PluginManager::AddPlugin(const filesystem::path& path)
236235
entry.info = info;
237236
entry.plugin = plugin;
238237
entry.loader = loader;
239-
entry.loaded = false;
240238
entry.path = path_string;
241239
entry.enabled = false;
242240
entry.widget = nullptr;
@@ -247,10 +245,24 @@ void PluginManager::AddPlugin(const filesystem::path& path)
247245

248246
PluginManager::ActivePlugins.push_back(entry);
249247

250-
loader->unload();
248+
bool unloaded = loader->unload();
249+
251250
LOG_WARNING("[PluginManager] Plugin %s has an incompatible API version", path.c_str());
251+
252+
if(!unloaded)
253+
{
254+
LOG_WARNING("[PluginManager] Plugin %s cannot be unloaded", path.c_str());
255+
}
252256
}
253257
}
258+
else
259+
{
260+
LOG_WARNING("[PluginManager] Plugin %s cannot be casted to OpenRGBPluginInterface", path.c_str());
261+
}
262+
}
263+
else
264+
{
265+
LOG_WARNING("[PluginManager] Plugin %s cannot be instantiated.", path.c_str());
254266
}
255267
}
256268
}
@@ -284,7 +296,7 @@ void PluginManager::RemovePlugin(const filesystem::path& path)
284296
/*---------------------------------------------------------------------*\
285297
| If the selected plugin is in the list and loaded, unload it |
286298
\*---------------------------------------------------------------------*/
287-
if(ActivePlugins[plugin_idx].loaded)
299+
if(ActivePlugins[plugin_idx].loader->isLoaded())
288300
{
289301
LOG_TRACE("[PluginManager] Plugin %s is active, unloading", path.c_str());
290302
UnloadPlugin(path);
@@ -330,10 +342,9 @@ void PluginManager::LoadPlugin(const filesystem::path& path)
330342
/*---------------------------------------------------------------------*\
331343
| If the selected plugin is in the list but not loaded, load it |
332344
\*---------------------------------------------------------------------*/
333-
if(!ActivePlugins[plugin_idx].loaded)
345+
if(!ActivePlugins[plugin_idx].loader->isLoaded())
334346
{
335347
ActivePlugins[plugin_idx].loader->load();
336-
ActivePlugins[plugin_idx].loaded = true;
337348

338349
QObject* instance = ActivePlugins[plugin_idx].loader->instance();
339350

@@ -390,7 +401,7 @@ void PluginManager::UnloadPlugin(const filesystem::path& path)
390401
/*---------------------------------------------------------------------*\
391402
| If the selected plugin is in the list and loaded, unload it |
392403
\*---------------------------------------------------------------------*/
393-
if(ActivePlugins[plugin_idx].loaded)
404+
if(ActivePlugins[plugin_idx].loader->isLoaded())
394405
{
395406
/*-------------------------------------------------*\
396407
| Call plugin's Unload function before GUI removal |
@@ -405,15 +416,30 @@ void PluginManager::UnloadPlugin(const filesystem::path& path)
405416
RemovePluginCallbackVal(RemovePluginCallbackArg, &ActivePlugins[plugin_idx]);
406417
}
407418

408-
ActivePlugins[plugin_idx].loader->unload();
409-
ActivePlugins[plugin_idx].loaded = false;
419+
bool unloaded = ActivePlugins[plugin_idx].loader->unload();
420+
421+
if(!unloaded)
422+
{
423+
LOG_WARNING("[PluginManager] Plugin %s cannot be unloaded", path.c_str());
424+
}
425+
else
426+
{
427+
LOG_TRACE("[PluginManager] Plugin %s successfully unloaded", path.c_str());
428+
}
429+
}
430+
else
431+
{
432+
LOG_TRACE("[PluginManager] Plugin %s was already unloaded", path.c_str());
410433
}
411434
}
412435

413436
void PluginManager::UnloadPlugins()
414437
{
415438
for(const OpenRGBPluginEntry& plugin_entry: ActivePlugins)
416439
{
417-
plugin_entry.plugin->Unload();
440+
if(plugin_entry.loader->isLoaded())
441+
{
442+
plugin_entry.plugin->Unload();
443+
}
418444
}
419445
}

PluginManager.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#pragma once
22

33
#include "OpenRGBPluginInterface.h"
4-
#include "ResourceManager.h"
54

65
#include <QPluginLoader>
76
#include <QLabel>
@@ -16,7 +15,6 @@ typedef struct
1615
OpenRGBPluginInfo info;
1716
OpenRGBPluginInterface* plugin;
1817
QPluginLoader* loader;
19-
bool loaded;
2018
QWidget* widget;
2119
QMenu* traymenu;
2220
std::string path;

qt/OpenRGBDialog2/OpenRGBDialog2.cpp

Lines changed: 36 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,78 +1001,61 @@ void OpenRGBDialog2::AddPlugin(OpenRGBPluginEntry* plugin)
10011001
void OpenRGBDialog2::RemovePlugin(OpenRGBPluginEntry* plugin)
10021002
{
10031003
/*-----------------------------------------------------*\
1004-
| Place plugin as its own top level tab |
1004+
| Remove plugin's tray menu |
10051005
\*-----------------------------------------------------*/
1006-
if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_TOP)
1007-
{
1008-
for(int tab_idx = 0; tab_idx < ui->MainTabBar->count(); tab_idx++)
1009-
{
1010-
if(dynamic_cast<OpenRGBPluginContainer*>(ui->MainTabBar->widget(tab_idx)) != nullptr)
1011-
{
1012-
if(dynamic_cast<OpenRGBPluginContainer*>(ui->MainTabBar->widget(tab_idx))->plugin_widget == plugin->widget)
1013-
{
1014-
ui->MainTabBar->removeTab(tab_idx);
1015-
delete plugin->widget;
1016-
}
1017-
}
1018-
}
1019-
}
1020-
/*-----------------------------------------------------*\
1021-
| Place plugin in the Devices tab |
1022-
\*-----------------------------------------------------*/
1023-
else if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_DEVICES)
1006+
if(plugin->traymenu)
10241007
{
1025-
for(int tab_idx = 0; tab_idx < ui->DevicesTabBar->count(); tab_idx++)
1008+
QWidget* plugin_tray_entry = trayIconMenu->find(plugin->traymenu->winId());
1009+
1010+
if(plugin_tray_entry)
10261011
{
1027-
if(dynamic_cast<OpenRGBPluginContainer*>(ui->DevicesTabBar->widget(tab_idx)) != nullptr)
1028-
{
1029-
if(dynamic_cast<OpenRGBPluginContainer*>(ui->DevicesTabBar->widget(tab_idx))->plugin_widget == plugin->widget)
1030-
{
1031-
ui->DevicesTabBar->removeTab(tab_idx);
1032-
delete plugin->widget;
1033-
}
1034-
}
1012+
trayIconMenu->removeAction(plugin->traymenu->menuAction());
10351013
}
1014+
1015+
//delete plugin->traymenu;
10361016
}
1017+
10371018
/*-----------------------------------------------------*\
1038-
| Place plugin in the Information tab |
1019+
| Find plugin's container |
10391020
\*-----------------------------------------------------*/
1040-
else if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_INFORMATION)
1021+
QTabWidget *plugin_parent_widget = nullptr;
1022+
1023+
switch(plugin->info.Location)
10411024
{
1042-
for(int tab_idx = 0; tab_idx < ui->InformationTabBar->count(); tab_idx++)
1043-
{
1044-
if(dynamic_cast<OpenRGBPluginContainer*>(ui->InformationTabBar->widget(tab_idx)) != nullptr)
1045-
{
1046-
if(dynamic_cast<OpenRGBPluginContainer*>(ui->InformationTabBar->widget(tab_idx))->plugin_widget == plugin->widget)
1047-
{
1048-
ui->InformationTabBar->removeTab(tab_idx);
1049-
delete plugin->widget;
1050-
}
1051-
}
1052-
}
1025+
case OPENRGB_PLUGIN_LOCATION_TOP:
1026+
plugin_parent_widget = ui->MainTabBar;
1027+
break;
1028+
case OPENRGB_PLUGIN_LOCATION_DEVICES:
1029+
plugin_parent_widget = ui->DevicesTabBar;
1030+
break;
1031+
case OPENRGB_PLUGIN_LOCATION_INFORMATION:
1032+
plugin_parent_widget = ui->InformationTabBar;
1033+
break;
1034+
case OPENRGB_PLUGIN_LOCATION_SETTINGS:
1035+
plugin_parent_widget = ui->InformationTabBar;
1036+
break;
1037+
default:
1038+
break;
10531039
}
1040+
10541041
/*-----------------------------------------------------*\
1055-
| Place plugin in the Settings tab |
1042+
| Remove plugin from its container |
10561043
\*-----------------------------------------------------*/
1057-
else if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_SETTINGS)
1044+
if(plugin_parent_widget != nullptr)
10581045
{
1059-
for(int tab_idx = 0; tab_idx < ui->SettingsTabBar->count(); tab_idx++)
1046+
for(int tab_idx = 0; tab_idx < plugin_parent_widget->count(); tab_idx++)
10601047
{
1061-
if(dynamic_cast<OpenRGBPluginContainer*>(ui->SettingsTabBar->widget(tab_idx)) != nullptr)
1048+
if(dynamic_cast<OpenRGBPluginContainer*>(plugin_parent_widget->widget(tab_idx)) != nullptr)
10621049
{
1063-
if(dynamic_cast<OpenRGBPluginContainer*>(ui->SettingsTabBar->widget(tab_idx))->plugin_widget == plugin->widget)
1050+
if(dynamic_cast<OpenRGBPluginContainer*>(plugin_parent_widget->widget(tab_idx))->plugin_widget == plugin->widget)
10641051
{
1065-
ui->SettingsTabBar->removeTab(tab_idx);
1066-
delete plugin->widget;
1052+
plugin_parent_widget->removeTab(tab_idx);
1053+
//delete plugin->widget;
1054+
break;
10671055
}
10681056
}
10691057
}
10701058
}
1071-
1072-
if(plugin->traymenu)
1073-
{
1074-
trayIconMenu->removeAction(plugin->traymenu->menuAction());
1075-
}
10761059
}
10771060

10781061
void OpenRGBDialog2::AddI2CToolsPage()

qt/OpenRGBPluginsPage/OpenRGBPluginsPage.cpp

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,25 @@ void Ui::OpenRGBPluginsPage::RefreshList()
4444
ui->PluginsList->clear();
4545
entries.clear();
4646

47-
for(unsigned int plugin_idx = 0; plugin_idx < plugin_manager->ActivePlugins.size(); plugin_idx++)
47+
for(const OpenRGBPluginEntry& plugin: plugin_manager->ActivePlugins)
4848
{
4949
OpenRGBPluginsEntry* entry = new OpenRGBPluginsEntry();
5050

5151
/*---------------------------------------------------------*\
5252
| Fill in plugin information fields |
5353
\*---------------------------------------------------------*/
54-
entry->ui->NameValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Name));
55-
entry->ui->DescriptionValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Description));
56-
entry->ui->VersionValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Version));
57-
entry->ui->CommitValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Commit));
58-
entry->ui->URLValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.URL));
59-
entry->ui->APIVersionValue->setText(QString::number(plugin_manager->ActivePlugins[plugin_idx].api_version));
54+
entry->ui->NameValue->setText(QString::fromStdString(plugin.info.Name));
55+
entry->ui->DescriptionValue->setText(QString::fromStdString(plugin.info.Description));
56+
entry->ui->VersionValue->setText(QString::fromStdString(plugin.info.Version));
57+
entry->ui->CommitValue->setText(QString::fromStdString(plugin.info.Commit));
58+
entry->ui->URLValue->setText(QString::fromStdString(plugin.info.URL));
59+
entry->ui->APIVersionValue->setText(QString::number(plugin.api_version));
6060

6161
/*---------------------------------------------------------*\
6262
| If the plugin is incompatible, highlight the API version |
6363
| in red and disable the enable checkbox |
6464
\*---------------------------------------------------------*/
65-
if(plugin_manager->ActivePlugins[plugin_idx].incompatible)
65+
if(plugin.incompatible)
6666
{
6767
entry->ui->APIVersionValue->setStyleSheet("QLabel { color : red; }");
6868
entry->ui->EnabledCheckBox->setEnabled(false);
@@ -71,20 +71,20 @@ void Ui::OpenRGBPluginsPage::RefreshList()
7171
/*---------------------------------------------------------*\
7272
| Fill in plugin icon |
7373
\*---------------------------------------------------------*/
74-
QPixmap pixmap(QPixmap::fromImage(plugin_manager->ActivePlugins[plugin_idx].info.Icon));
74+
QPixmap pixmap(QPixmap::fromImage(plugin.info.Icon));
7575

7676
entry->ui->IconView->setPixmap(pixmap);
7777
entry->ui->IconView->setScaledContents(true);
7878

7979
/*---------------------------------------------------------*\
8080
| Fill in plugin path |
8181
\*---------------------------------------------------------*/
82-
entry->ui->PathValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].path));
82+
entry->ui->PathValue->setText(QString::fromStdString(plugin.path));
8383

8484
/*---------------------------------------------------------*\
8585
| Fill in plugin enabled status |
8686
\*---------------------------------------------------------*/
87-
entry->ui->EnabledCheckBox->setChecked((plugin_manager->ActivePlugins[plugin_idx].enabled));
87+
entry->ui->EnabledCheckBox->setChecked((plugin.enabled));
8888

8989
entry->RegisterEnableClickCallback(EnableClickCallbackFunction, this);
9090

@@ -261,7 +261,7 @@ void Ui::OpenRGBPluginsPage::on_EnableButton_clicked(OpenRGBPluginsEntry* entry)
261261
\*-----------------------------------------------------*/
262262
std::string name = "";
263263
std::string description = "";
264-
bool enabled = true;
264+
bool enabled = entry->ui->EnabledCheckBox->isChecked();
265265
bool found = false;
266266
unsigned int plugin_ct = 0;
267267
unsigned int plugin_idx = 0;
@@ -270,15 +270,6 @@ void Ui::OpenRGBPluginsPage::on_EnableButton_clicked(OpenRGBPluginsEntry* entry)
270270
std::string entry_desc = entry->ui->DescriptionValue->text().toStdString();
271271
std::string entry_path = entry->ui->PathValue->text().toStdString();
272272

273-
if(entry->ui->EnabledCheckBox->isChecked())
274-
{
275-
enabled = true;
276-
}
277-
else
278-
{
279-
enabled = false;
280-
}
281-
282273
if(plugin_settings.contains("plugins"))
283274
{
284275
plugin_ct = plugin_settings["plugins"].size();

0 commit comments

Comments
 (0)