From 1856e1cb7e28f71ebaa5fe6509bd2941ff3558aa Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Tue, 26 May 2015 15:10:36 -0700 Subject: [PATCH] Return AutoPilotPlugin as QSharedPointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If Facts are referenced from FactPanelController, we need to reference count the AutoPilotPlugin such that it doesn’t get destroyed until after the FactPanelController is destroyed. --- src/AutoPilotPlugins/AutoPilotPlugin.cc | 5 +++++ src/AutoPilotPlugins/AutoPilotPlugin.h | 1 + src/AutoPilotPlugins/AutoPilotPluginManager.cc | 8 ++++---- src/AutoPilotPlugins/AutoPilotPluginManager.h | 7 ++++--- src/FactSystem/FactControls/FactPanelController.h | 4 ++-- src/FactSystem/FactSystemTestBase.cc | 2 +- src/QmlControls/ParameterEditor.qml | 2 +- src/QmlControls/ParameterEditorController.cc | 5 +++++ src/QmlControls/ParameterEditorController.h | 1 + src/VehicleSetup/SetupView.cc | 2 +- src/VehicleSetup/SetupViewTest.cc | 2 +- src/ViewWidgets/ViewWidgetController.cc | 4 ++-- src/ViewWidgets/ViewWidgetController.h | 6 +++--- src/qgcunittest/PX4RCCalibrationTest.cc | 2 +- src/ui/QGCMapRCToParamDialog.cpp | 2 +- src/ui/px4_configuration/PX4RCCalibration.h | 4 ++-- src/ui/toolbar/MainToolBar.cc | 4 ++-- 17 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/AutoPilotPlugins/AutoPilotPlugin.cc b/src/AutoPilotPlugins/AutoPilotPlugin.cc index 80bfd8b7f..41765aeec 100644 --- a/src/AutoPilotPlugins/AutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/AutoPilotPlugin.cc @@ -43,6 +43,11 @@ AutoPilotPlugin::AutoPilotPlugin(UASInterface* uas, QObject* parent) : connect(this, &AutoPilotPlugin::pluginReadyChanged, this, &AutoPilotPlugin::_pluginReadyChanged); } +AutoPilotPlugin::~AutoPilotPlugin() +{ + +} + void AutoPilotPlugin::_uasDisconnected(void) { _pluginReady = false; diff --git a/src/AutoPilotPlugins/AutoPilotPlugin.h b/src/AutoPilotPlugins/AutoPilotPlugin.h index 9f4c67ef6..4fbd9435f 100644 --- a/src/AutoPilotPlugins/AutoPilotPlugin.h +++ b/src/AutoPilotPlugins/AutoPilotPlugin.h @@ -51,6 +51,7 @@ class AutoPilotPlugin : public QObject public: AutoPilotPlugin(UASInterface* uas, QObject* parent); + ~AutoPilotPlugin(); /// true: plugin is ready for use, plugin should no longer be used Q_PROPERTY(bool pluginReady READ pluginReady NOTIFY pluginReadyChanged) diff --git a/src/AutoPilotPlugins/AutoPilotPluginManager.cc b/src/AutoPilotPlugins/AutoPilotPluginManager.cc index 624f00738..a18cb4eb9 100644 --- a/src/AutoPilotPlugins/AutoPilotPluginManager.cc +++ b/src/AutoPilotPlugins/AutoPilotPluginManager.cc @@ -74,13 +74,13 @@ void AutoPilotPluginManager::_uasCreated(UASInterface* uas) case MAV_AUTOPILOT_PX4: plugin = new PX4AutoPilotPlugin(uas, this); Q_CHECK_PTR(plugin); - _pluginMap[MAV_AUTOPILOT_PX4][uasId] = plugin; + _pluginMap[MAV_AUTOPILOT_PX4][uasId] = QSharedPointer(plugin); break; case MAV_AUTOPILOT_GENERIC: default: plugin = new GenericAutoPilotPlugin(uas, this); Q_CHECK_PTR(plugin); - _pluginMap[MAV_AUTOPILOT_GENERIC][uasId] = plugin; + _pluginMap[MAV_AUTOPILOT_GENERIC][uasId] = QSharedPointer(plugin); } } @@ -94,12 +94,12 @@ void AutoPilotPluginManager::_uasDeleted(UASInterface* uas) Q_ASSERT(uasId != 0); if (_pluginMap.contains(autopilotType) && _pluginMap[autopilotType].contains(uasId)) { - delete _pluginMap[autopilotType][uasId]; + _pluginMap[autopilotType][uasId].clear(); _pluginMap[autopilotType].remove(uasId); } } -AutoPilotPlugin* AutoPilotPluginManager::getInstanceForAutoPilotPlugin(UASInterface* uas) +QSharedPointer AutoPilotPluginManager::getInstanceForAutoPilotPlugin(UASInterface* uas) { Q_ASSERT(uas); diff --git a/src/AutoPilotPlugins/AutoPilotPluginManager.h b/src/AutoPilotPlugins/AutoPilotPluginManager.h index 03c760744..aa3808bae 100644 --- a/src/AutoPilotPlugins/AutoPilotPluginManager.h +++ b/src/AutoPilotPlugins/AutoPilotPluginManager.h @@ -47,9 +47,10 @@ class AutoPilotPluginManager : public QGCSingleton DECLARE_QGC_SINGLETON(AutoPilotPluginManager, AutoPilotPluginManager) public: - /// Returns the singleton AutoPilotPlugin instance for the specified uas. + /// Returns the singleton AutoPilotPlugin instance for the specified uas. Returned as QSharedPointer + /// to prevent shutdown ordering problems with Qml destruction happening after Facts are destroyed. /// @param uas Uas to get plugin for - AutoPilotPlugin* getInstanceForAutoPilotPlugin(UASInterface* uas); + QSharedPointer getInstanceForAutoPilotPlugin(UASInterface* uas); typedef struct { uint8_t baseMode; @@ -73,7 +74,7 @@ private: MAV_AUTOPILOT _installedAutopilotType(MAV_AUTOPILOT autopilot); - QMap > _pluginMap; ///< Map of AutoPilot plugins _pluginMap[MAV_TYPE][UASid] + QMap > > _pluginMap; ///< Map of AutoPilot plugins _pluginMap[MAV_TYPE][UASid] }; #endif diff --git a/src/FactSystem/FactControls/FactPanelController.h b/src/FactSystem/FactControls/FactPanelController.h index 6714f85c3..e2da76fd1 100644 --- a/src/FactSystem/FactControls/FactPanelController.h +++ b/src/FactSystem/FactControls/FactPanelController.h @@ -62,8 +62,8 @@ protected: /// Report a missing parameter to the FactPanel Qml element void _reportMissingParameter(int componentId, const QString& name); - UASInterface* _uas; - AutoPilotPlugin* _autopilot; + UASInterface* _uas; + QSharedPointer _autopilot; private slots: void _checkForMissingFactPanel(void); diff --git a/src/FactSystem/FactSystemTestBase.cc b/src/FactSystem/FactSystemTestBase.cc index 2e9ac9122..cd6a6433d 100644 --- a/src/FactSystem/FactSystemTestBase.cc +++ b/src/FactSystem/FactSystemTestBase.cc @@ -64,7 +64,7 @@ void FactSystemTestBase::_init(MAV_AUTOPILOT autopilot) AutoPilotPluginManager* pluginMgr = AutoPilotPluginManager::instance(); Q_ASSERT(pluginMgr); - _plugin = pluginMgr->getInstanceForAutoPilotPlugin(_uas); + _plugin = pluginMgr->getInstanceForAutoPilotPlugin(_uas).data(); Q_ASSERT(_plugin); // Wait for the plugin to be ready diff --git a/src/QmlControls/ParameterEditor.qml b/src/QmlControls/ParameterEditor.qml index ad55f0d97..7dbc52159 100644 --- a/src/QmlControls/ParameterEditor.qml +++ b/src/QmlControls/ParameterEditor.qml @@ -83,7 +83,7 @@ QGCView { } Repeater { - model: autopilot ? controller.getFactsForGroup(componentId, group) : 0 + model: controller.getFactsForGroup(componentId, group) Column { property Fact modelFact: controller.getParameterFact(componentId, modelData) diff --git a/src/QmlControls/ParameterEditorController.cc b/src/QmlControls/ParameterEditorController.cc index d4f091057..2ba5f61c7 100644 --- a/src/QmlControls/ParameterEditorController.cc +++ b/src/QmlControls/ParameterEditorController.cc @@ -42,6 +42,11 @@ ParameterEditorController::ParameterEditorController(void) } } +ParameterEditorController::~ParameterEditorController() +{ + +} + QStringList ParameterEditorController::getGroupsForComponent(int componentId) { const QMap >& groupMap = _autopilot->getGroupMap(); diff --git a/src/QmlControls/ParameterEditorController.h b/src/QmlControls/ParameterEditorController.h index ac533c0f1..0f556a309 100644 --- a/src/QmlControls/ParameterEditorController.h +++ b/src/QmlControls/ParameterEditorController.h @@ -40,6 +40,7 @@ class ParameterEditorController : public FactPanelController public: ParameterEditorController(void); + ~ParameterEditorController(); Q_PROPERTY(QStringList componentIds MEMBER _componentIds CONSTANT) diff --git a/src/VehicleSetup/SetupView.cc b/src/VehicleSetup/SetupView.cc index 31fc188cb..3878600e0 100644 --- a/src/VehicleSetup/SetupView.cc +++ b/src/VehicleSetup/SetupView.cc @@ -84,7 +84,7 @@ void SetupView::_setActiveUAS(UASInterface* uas) _uasCurrent = uas; if (_uasCurrent) { - _autoPilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uasCurrent); + _autoPilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uasCurrent).data(); _pluginReadyChanged(_autoPilotPlugin->pluginReady()); connect(_autoPilotPlugin, &AutoPilotPlugin::pluginReadyChanged, this, &SetupView::_pluginReadyChanged); } diff --git a/src/VehicleSetup/SetupViewTest.cc b/src/VehicleSetup/SetupViewTest.cc index b04605077..54a544f23 100644 --- a/src/VehicleSetup/SetupViewTest.cc +++ b/src/VehicleSetup/SetupViewTest.cc @@ -71,7 +71,7 @@ void SetupViewTest::_clickThrough_test(void) linkMgr->connectLink(link); QTest::qWait(5000); // Give enough time for UI to settle and heartbeats to go through - AutoPilotPlugin* autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(UASManager::instance()->getActiveUAS()); + AutoPilotPlugin* autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(UASManager::instance()->getActiveUAS()).data(); Q_ASSERT(autopilot); QSignalSpy spyPlugin(autopilot, SIGNAL(pluginReadyChanged(bool))); diff --git a/src/ViewWidgets/ViewWidgetController.cc b/src/ViewWidgets/ViewWidgetController.cc index 095bb4db3..c8434f7f5 100644 --- a/src/ViewWidgets/ViewWidgetController.cc +++ b/src/ViewWidgets/ViewWidgetController.cc @@ -41,13 +41,13 @@ void ViewWidgetController::_activeUasChanged(UASInterface* currentUas) if (_uas) { disconnect(_autopilot, &AutoPilotPlugin::pluginReadyChanged, this, &ViewWidgetController::_pluginReadyChanged); _uas = NULL; - _autopilot = NULL; + _autopilot = NULL; emit pluginDisconnected(); } if (currentUas) { _uas = currentUas; - _autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(currentUas); + _autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(currentUas).data(); Q_ASSERT(_autopilot); connect(_autopilot, &AutoPilotPlugin::pluginReadyChanged, this, &ViewWidgetController::_pluginReadyChanged); diff --git a/src/ViewWidgets/ViewWidgetController.h b/src/ViewWidgets/ViewWidgetController.h index 63a73f00d..64ba1cdcb 100644 --- a/src/ViewWidgets/ViewWidgetController.h +++ b/src/ViewWidgets/ViewWidgetController.h @@ -48,9 +48,9 @@ private slots: void _pluginReadyChanged(bool pluginReady); private: - AutoPilotPlugin* _autopilot; - UASManagerInterface* _uasManager; - UASInterface* _uas; + AutoPilotPlugin* _autopilot; + UASManagerInterface* _uasManager; + UASInterface* _uas; }; #endif \ No newline at end of file diff --git a/src/qgcunittest/PX4RCCalibrationTest.cc b/src/qgcunittest/PX4RCCalibrationTest.cc index a9780e4e1..633911505 100644 --- a/src/qgcunittest/PX4RCCalibrationTest.cc +++ b/src/qgcunittest/PX4RCCalibrationTest.cc @@ -151,7 +151,7 @@ void PX4RCCalibrationTest::init(void) LinkManager::instance()->connectLink(_mockLink); QTest::qWait(5000); // Give enough time for UI to settle and heartbeats to go through - _autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(UASManager::instance()->getActiveUAS()); + _autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(UASManager::instance()->getActiveUAS()).data(); Q_ASSERT(_autopilot); QSignalSpy spyPlugin(_autopilot, SIGNAL(pluginReadyChanged(bool))); diff --git a/src/ui/QGCMapRCToParamDialog.cpp b/src/ui/QGCMapRCToParamDialog.cpp index 95f399d2d..f4e9c5d43 100644 --- a/src/ui/QGCMapRCToParamDialog.cpp +++ b/src/ui/QGCMapRCToParamDialog.cpp @@ -101,7 +101,7 @@ ParamLoader::ParamLoader(QString paramName, UASInterface* uas, QObject* parent) _paramName(paramName), _paramReceived(false) { - _autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uas); + _autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uas).data(); Q_ASSERT(_autopilot); } diff --git a/src/ui/px4_configuration/PX4RCCalibration.h b/src/ui/px4_configuration/PX4RCCalibration.h index 718bb38e7..66d827e6f 100644 --- a/src/ui/px4_configuration/PX4RCCalibration.h +++ b/src/ui/px4_configuration/PX4RCCalibration.h @@ -256,8 +256,8 @@ private: RCValueWidget* _rgRCValueMonitorWidget[_chanMax]; ///< Array of radio channel value widgets QLabel* _rgRCValueMonitorLabel[_chanMax]; ///< Array of radio channel value labels - UASInterface* _uas; - AutoPilotPlugin* _autopilot; + UASInterface* _uas; + QSharedPointer _autopilot; Ui::PX4RCCalibration* _ui; diff --git a/src/ui/toolbar/MainToolBar.cc b/src/ui/toolbar/MainToolBar.cc index 470cd8ab7..d799d8bdd 100644 --- a/src/ui/toolbar/MainToolBar.cc +++ b/src/ui/toolbar/MainToolBar.cc @@ -282,7 +282,7 @@ void MainToolBar::_forgetUAS(UASInterface* uas) if (_mav != NULL && _mav == uas) { disconnect(UASMessageHandler::instance(), &UASMessageHandler::textMessageCountChanged, this, &MainToolBar::_handleTextMessage); disconnect(_mav, &UASInterface::remoteControlRSSIChanged, this, &MainToolBar::_remoteControlRSSIChanged); - disconnect(AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_mav), &AutoPilotPlugin::parameterListProgress, this, &MainToolBar::_setProgressBarValue); + disconnect(AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_mav).data(), &AutoPilotPlugin::parameterListProgress, this, &MainToolBar::_setProgressBarValue); _mav = NULL; } } @@ -302,7 +302,7 @@ void MainToolBar::_setActiveUAS(UASInterface* active) { connect(UASMessageHandler::instance(), &UASMessageHandler::textMessageCountChanged, this, &MainToolBar::_handleTextMessage); connect(_mav, &UASInterface::remoteControlRSSIChanged, this, &MainToolBar::_remoteControlRSSIChanged); - connect(AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_mav), &AutoPilotPlugin::parameterListProgress, this, &MainToolBar::_setProgressBarValue); + connect(AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_mav).data(), &AutoPilotPlugin::parameterListProgress, this, &MainToolBar::_setProgressBarValue); } } -- 2.22.0