Commit ab25a46a authored by DonLakeFlyer's avatar DonLakeFlyer

Fix crash on exit due to bad parenting/shutdown sequence

parent 4928cccf
......@@ -15,6 +15,7 @@
#include "QGCMAVLink.h"
#include <QtQml>
#include <QQmlEngine>
Fact::Fact(QObject* parent)
: QObject(parent)
......@@ -27,6 +28,9 @@ Fact::Fact(QObject* parent)
{
FactMetaData* metaData = new FactMetaData(_type, this);
setMetaData(metaData);
// Better sage than sorry on object ownership
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
}
Fact::Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObject* parent)
......@@ -41,12 +45,14 @@ Fact::Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObjec
{
FactMetaData* metaData = new FactMetaData(_type, this);
setMetaData(metaData);
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
}
Fact::Fact(const Fact& other, QObject* parent)
: QObject(parent)
{
*this = other;
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
}
const Fact& Fact::operator=(const Fact& other)
......
......@@ -19,8 +19,8 @@
const char* FactSystem::_factSystemQmlUri = "QGroundControl.FactSystem";
FactSystem::FactSystem(QGCApplication* app)
: QGCTool(app)
FactSystem::FactSystem(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
{
}
......
......@@ -31,7 +31,7 @@ class FactSystem : public QGCTool
public:
/// All access to FactSystem is through FactSystem::instance, so constructor is private
FactSystem(QGCApplication* app);
FactSystem(QGCApplication* app, QGCToolbox* toolbox);
// Override from QGCTool
virtual void setToolbox(QGCToolbox *toolbox);
......
......@@ -14,8 +14,8 @@
#include "FirmwarePluginManager.h"
#include "FirmwarePlugin.h"
FirmwarePluginManager::FirmwarePluginManager(QGCApplication* app)
: QGCTool(app)
FirmwarePluginManager::FirmwarePluginManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _genericFirmwarePlugin(NULL)
{
......
......@@ -29,7 +29,7 @@ class FirmwarePluginManager : public QGCTool
Q_OBJECT
public:
FirmwarePluginManager(QGCApplication* app);
FirmwarePluginManager(QGCApplication* app, QGCToolbox* toolbox);
~FirmwarePluginManager();
/// Returns list of firmwares which are supported by the system
......
......@@ -30,8 +30,8 @@
QGC_LOGGING_CATEGORY(VideoManagerLog, "VideoManagerLog")
//-----------------------------------------------------------------------------
VideoManager::VideoManager(QGCApplication* app)
: QGCTool(app)
VideoManager::VideoManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _videoSurface(NULL)
, _videoReceiver(NULL)
, _videoRunning(false)
......
......@@ -29,7 +29,7 @@ class VideoManager : public QGCTool
Q_OBJECT
public:
VideoManager (QGCApplication* app);
VideoManager (QGCApplication* app, QGCToolbox* toolbox);
~VideoManager ();
Q_PROPERTY(bool hasVideo READ hasVideo NOTIFY hasVideoChanged)
......
......@@ -17,8 +17,8 @@
#include "Vehicle.h"
#include "PositionManager.h"
FollowMe::FollowMe(QGCApplication* app)
: QGCTool(app), estimatation_capabilities(0)
FollowMe::FollowMe(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox), estimatation_capabilities(0)
{
memset(&_motionReport, 0, sizeof(motionReport_s));
runTime.start();
......@@ -27,11 +27,6 @@ FollowMe::FollowMe(QGCApplication* app)
connect(&_gcsMotionReportTimer, &QTimer::timeout, this, &FollowMe::_sendGCSMotionReport);
}
FollowMe::~FollowMe()
{
_disable();
}
void FollowMe::followMeHandleManager(const QString&)
{
QmlObjectListModel & vehicles = *_toolbox->multiVehicleManager()->vehicles();
......
......@@ -27,8 +27,7 @@ class FollowMe : public QGCTool
Q_OBJECT
public:
FollowMe(QGCApplication* app);
~FollowMe();
FollowMe(QGCApplication* app, QGCToolbox* toolbox);
public slots:
void followMeHandleManager(const QString&);
......
......@@ -30,8 +30,8 @@
#include <QtAndroidExtras/QAndroidJniObject>
#endif
GAudioOutput::GAudioOutput(QGCApplication* app)
: QGCTool(app)
GAudioOutput::GAudioOutput(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
#ifndef __android__
, thread(new QThread())
, worker(new QGCAudioWorker())
......
......@@ -39,7 +39,7 @@ class GAudioOutput : public QGCTool
Q_OBJECT
public:
GAudioOutput(QGCApplication* app);
GAudioOutput(QGCApplication* app, QGCToolbox* toolbox);
~GAudioOutput();
/** @brief List available voices */
......
......@@ -27,8 +27,8 @@ QGC_LOGGING_CATEGORY(JoystickManagerLog, "JoystickManagerLog")
const char * JoystickManager::_settingsGroup = "JoystickManager";
const char * JoystickManager::_settingsKeyActiveJoystick = "ActiveJoystick";
JoystickManager::JoystickManager(QGCApplication* app)
: QGCTool(app)
JoystickManager::JoystickManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _activeJoystick(NULL)
, _multiVehicleManager(NULL)
{
......
......@@ -25,7 +25,7 @@ class JoystickManager : public QGCTool
Q_OBJECT
public:
JoystickManager(QGCApplication* app);
JoystickManager(QGCApplication* app, QGCToolbox* toolbox);
~JoystickManager();
/// List of available joysticks
......
......@@ -21,8 +21,8 @@
#include <QQmlEngine>
MissionCommandTree::MissionCommandTree(QGCApplication* app, bool unitTest)
: QGCTool(app)
MissionCommandTree::MissionCommandTree(QGCApplication* app, QGCToolbox* toolbox, bool unitTest)
: QGCTool(app, toolbox)
, _allCommandsCategory(tr("All commands"))
, _settingsManager(NULL)
, _unitTest(unitTest)
......
......@@ -48,7 +48,7 @@ class MissionCommandTree : public QGCTool
Q_OBJECT
public:
MissionCommandTree(QGCApplication* app, bool unitTest = false);
MissionCommandTree(QGCApplication* app, QGCToolbox* toolbox, bool unitTest = false);
/// Returns the friendly name for the specified command
QString friendlyName(MAV_CMD command);
......
......@@ -11,10 +11,10 @@
#include "QGCApplication.h"
#include "QGCCorePlugin.h"
QGCPositionManager::QGCPositionManager(QGCApplication* app) :
QGCTool(app),
_updateInterval(0),
_currentSource(nullptr)
QGCPositionManager::QGCPositionManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _updateInterval(0)
, _currentSource(nullptr)
{
}
......
......@@ -21,7 +21,7 @@ class QGCPositionManager : public QGCTool {
public:
QGCPositionManager(QGCApplication* app);
QGCPositionManager(QGCApplication* app, QGCToolbox* toolbox);
~QGCPositionManager();
enum QGCPositionSource {
......
......@@ -133,7 +133,7 @@ static QObject* mavlinkQmlSingletonFactory(QQmlEngine*, QJSEngine*)
static QObject* qgroundcontrolQmlGlobalSingletonFactory(QQmlEngine*, QJSEngine*)
{
// We create this object as a QGCTool even though it isn't in the toolbox
QGroundControlQmlGlobal* qmlGlobal = new QGroundControlQmlGlobal(qgcApp());
QGroundControlQmlGlobal* qmlGlobal = new QGroundControlQmlGlobal(qgcApp(), qgcApp()->toolbox());
qmlGlobal->setToolbox(qgcApp()->toolbox());
return qmlGlobal;
......
......@@ -29,6 +29,7 @@
#include "QGCCorePlugin.h"
#include "QGCOptions.h"
#include "SettingsManager.h"
#include "QGCApplication.h"
#if defined(QGC_CUSTOM_BUILD)
#include CUSTOMHEADER
......@@ -57,28 +58,28 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
, _settingsManager(NULL)
{
// SettingsManager must be first so settings are available to any subsequent tools
_settingsManager = new SettingsManager(app);
_settingsManager = new SettingsManager(app, this);
//-- Scan and load plugins
_scanAndLoadPlugins(app);
_audioOutput = new GAudioOutput(app);
_factSystem = new FactSystem(app);
_firmwarePluginManager = new FirmwarePluginManager(app);
_audioOutput = new GAudioOutput (app, this);
_factSystem = new FactSystem (app, this);
_firmwarePluginManager = new FirmwarePluginManager (app, this);
#ifndef __mobile__
_gpsManager = new GPSManager(app);
_gpsManager = new GPSManager (app, this);
#endif
_imageProvider = new QGCImageProvider(app);
_joystickManager = new JoystickManager(app);
_linkManager = new LinkManager(app);
_mavlinkProtocol = new MAVLinkProtocol(app);
_missionCommandTree = new MissionCommandTree(app);
_multiVehicleManager = new MultiVehicleManager(app);
_mapEngineManager = new QGCMapEngineManager(app);
_uasMessageHandler = new UASMessageHandler(app);
_qgcPositionManager = new QGCPositionManager(app);
_followMe = new FollowMe(app);
_videoManager = new VideoManager(app);
_mavlinkLogManager = new MAVLinkLogManager(app);
_imageProvider = new QGCImageProvider (app, this);
_joystickManager = new JoystickManager (app, this);
_linkManager = new LinkManager (app, this);
_mavlinkProtocol = new MAVLinkProtocol (app, this);
_missionCommandTree = new MissionCommandTree (app, this);
_multiVehicleManager = new MultiVehicleManager (app, this);
_mapEngineManager = new QGCMapEngineManager (app, this);
_uasMessageHandler = new UASMessageHandler (app, this);
_qgcPositionManager = new QGCPositionManager (app, this);
_followMe = new FollowMe (app, this);
_videoManager = new VideoManager (app, this);
_mavlinkLogManager = new MAVLinkLogManager (app, this);
}
void QGCToolbox::setChildToolboxes(void)
......@@ -107,40 +108,21 @@ void QGCToolbox::setChildToolboxes(void)
_mavlinkLogManager->setToolbox(this);
}
QGCToolbox::~QGCToolbox()
{
delete _videoManager;
delete _mavlinkLogManager;
delete _audioOutput;
delete _factSystem;
delete _firmwarePluginManager;
delete _joystickManager;
delete _linkManager;
delete _mavlinkProtocol;
delete _missionCommandTree;
delete _mapEngineManager;
delete _multiVehicleManager;
delete _uasMessageHandler;
delete _followMe;
delete _qgcPositionManager;
delete _corePlugin;
}
void QGCToolbox::_scanAndLoadPlugins(QGCApplication* app)
{
#if defined (QGC_CUSTOM_BUILD)
//-- Create custom plugin (Static)
_corePlugin = (QGCCorePlugin*) new CUSTOMCLASS(app);
_corePlugin = (QGCCorePlugin*) new CUSTOMCLASS(app, app->toolbox());
if(_corePlugin) {
return;
}
#endif
//-- No plugins found, use default instance
_corePlugin = new QGCCorePlugin(app);
_corePlugin = new QGCCorePlugin(app, app->toolbox());
}
QGCTool::QGCTool(QGCApplication* app)
: QObject((QObject*)app)
QGCTool::QGCTool(QGCApplication* app, QGCToolbox* toolbox)
: QObject(toolbox)
, _app(app)
, _toolbox(NULL)
{
......
......@@ -34,11 +34,11 @@ class QGCCorePlugin;
class SettingsManager;
/// This is used to manage all of our top level services/tools
class QGCToolbox {
class QGCToolbox : public QObject {
Q_OBJECT
public:
QGCToolbox(QGCApplication* app);
~QGCToolbox();
FirmwarePluginManager* firmwarePluginManager(void) { return _firmwarePluginManager; }
GAudioOutput* audioOutput(void) { return _audioOutput; }
......@@ -95,11 +95,12 @@ class QGCTool : public QObject {
Q_OBJECT
public:
// All tools are parented to QGCAppliation and go through a two phase creation. First all tools are newed,
// and then setToolbox is called on all tools. The prevents creating an circular dependencies at constructor
// time.
QGCTool(QGCApplication* app);
// All tools must be parented to the QGCToolbox and go through a two phase creation. In the constructor the toolbox
// should only be passed to QGCTool constructor for correct parenting. It should not be referenced or set in the
// protected member. Then in the second phase of setToolbox calls is where you can reference the toolbox.
QGCTool(QGCApplication* app, QGCToolbox* toolbox);
// If you override this method, you must call the base class.
virtual void setToolbox(QGCToolbox* toolbox);
protected:
......
......@@ -22,8 +22,8 @@
#include <QPainter>
#include <QFont>
QGCImageProvider::QGCImageProvider(QGCApplication *app)
: QGCTool(app)
QGCImageProvider::QGCImageProvider(QGCApplication *app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, QQuickImageProvider(QQmlImageProviderBase::Image)
{
}
......
......@@ -29,7 +29,7 @@
class QGCImageProvider : public QGCTool, public QQuickImageProvider
{
public:
QGCImageProvider (QGCApplication* app);
QGCImageProvider (QGCApplication* app, QGCToolbox* toolbox);
~QGCImageProvider ();
QImage requestImage (const QString & id, QSize * size, const QSize & requestedSize);
void setImage (QImage* pImage, int id = 0);
......
......@@ -24,8 +24,8 @@ const char* QGroundControlQmlGlobal::_flightMapPositionLatitudeSettingsKey =
const char* QGroundControlQmlGlobal::_flightMapPositionLongitudeSettingsKey = "Longitude";
const char* QGroundControlQmlGlobal::_flightMapZoomSettingsKey = "FlightMapZoom";
QGroundControlQmlGlobal::QGroundControlQmlGlobal(QGCApplication* app)
: QGCTool(app)
QGroundControlQmlGlobal::QGroundControlQmlGlobal(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _flightMapInitialZoom(14.7) // About 500 meter scale
, _linkManager(NULL)
, _multiVehicleManager(NULL)
......
......@@ -34,7 +34,7 @@ class QGroundControlQmlGlobal : public QGCTool
Q_OBJECT
public:
QGroundControlQmlGlobal(QGCApplication* app);
QGroundControlQmlGlobal(QGCApplication* app, QGCToolbox* toolbox);
~QGroundControlQmlGlobal();
Q_PROPERTY(QString appName READ appName CONSTANT)
......
......@@ -30,8 +30,8 @@ QGC_LOGGING_CATEGORY(QGCMapEngineManagerLog, "QGCMapEngineManagerLog")
static const char* kQmlOfflineMapKeyName = "QGCOfflineMap";
//-----------------------------------------------------------------------------
QGCMapEngineManager::QGCMapEngineManager(QGCApplication* app)
: QGCTool(app)
QGCMapEngineManager::QGCMapEngineManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _topleftLat(0.0)
, _topleftLon(0.0)
, _bottomRightLat(0.0)
......
......@@ -26,7 +26,7 @@ class QGCMapEngineManager : public QGCTool
{
Q_OBJECT
public:
QGCMapEngineManager(QGCApplication* app);
QGCMapEngineManager(QGCApplication* app, QGCToolbox* toolbox);
~QGCMapEngineManager();
enum ImportAction {
......
......@@ -12,8 +12,8 @@
#include <QQmlEngine>
#include <QtQml>
SettingsManager::SettingsManager(QGCApplication* app)
: QGCTool(app)
SettingsManager::SettingsManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _appSettings(NULL)
, _unitsSettings(NULL)
, _autoConnectSettings(NULL)
......
......@@ -28,7 +28,7 @@ class SettingsManager : public QGCTool
Q_OBJECT
public:
SettingsManager(QGCApplication* app);
SettingsManager(QGCApplication* app, QGCToolbox* toolbox);
Q_PROPERTY(QObject* appSettings READ appSettings CONSTANT)
Q_PROPERTY(QObject* unitsSettings READ unitsSettings CONSTANT)
......
......@@ -295,8 +295,8 @@ MAVLinkLogProcessor::processStreamData(uint16_t sequence, uint8_t first_message,
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
MAVLinkLogManager::MAVLinkLogManager(QGCApplication* app)
: QGCTool(app)
MAVLinkLogManager::MAVLinkLogManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _enableAutoUpload(true)
, _enableAutoStart(false)
, _nam(NULL)
......
......@@ -106,7 +106,7 @@ class MAVLinkLogManager : public QGCTool
Q_OBJECT
public:
MAVLinkLogManager (QGCApplication* app);
MAVLinkLogManager (QGCApplication* app, QGCToolbox* toolbox);
~MAVLinkLogManager ();
Q_PROPERTY(QString emailAddress READ emailAddress WRITE setEmailAddress NOTIFY emailAddressChanged)
......
......@@ -27,8 +27,8 @@ QGC_LOGGING_CATEGORY(MultiVehicleManagerLog, "MultiVehicleManagerLog")
const char* MultiVehicleManager::_gcsHeartbeatEnabledKey = "gcsHeartbeatEnabled";
MultiVehicleManager::MultiVehicleManager(QGCApplication* app)
: QGCTool(app)
MultiVehicleManager::MultiVehicleManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _activeVehicleAvailable(false)
, _parameterReadyVehicleAvailable(false)
, _activeVehicle(NULL)
......
......@@ -33,7 +33,7 @@ class MultiVehicleManager : public QGCTool
Q_OBJECT
public:
MultiVehicleManager(QGCApplication* app);
MultiVehicleManager(QGCApplication* app, QGCToolbox* toolbox);
Q_INVOKABLE void saveSetting (const QString &key, const QString& value);
Q_INVOKABLE QString loadSetting (const QString &key, const QString& defaultValue);
......
......@@ -79,8 +79,8 @@ QGCCorePlugin::~QGCCorePlugin()
}
}
QGCCorePlugin::QGCCorePlugin(QGCApplication *app)
: QGCTool(app)
QGCCorePlugin::QGCCorePlugin(QGCApplication *app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _showTouchAreas(false)
, _showAdvancedUI(true)
{
......
......@@ -31,7 +31,7 @@ class QGCCorePlugin : public QGCTool
{
Q_OBJECT
public:
QGCCorePlugin(QGCApplication* app);
QGCCorePlugin(QGCApplication* app, QGCToolbox* toolbox);
~QGCCorePlugin();
Q_PROPERTY(QVariantList settingsPages READ settingsPages NOTIFY settingsPagesChanged)
......
......@@ -42,8 +42,8 @@ const int LinkManager::_autoconnectConnectDelayMSecs = 6000;
const int LinkManager::_autoconnectConnectDelayMSecs = 1000;
#endif
LinkManager::LinkManager(QGCApplication* app)
: QGCTool(app)
LinkManager::LinkManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _configUpdateSuspended(false)
, _configurationsLoaded(false)
, _connectionsSuspended(false)
......
......@@ -58,7 +58,7 @@ class LinkManager : public QGCTool
friend class LinkManagerTest;
public:
LinkManager(QGCApplication* app);
LinkManager(QGCApplication* app, QGCToolbox* toolbox);
~LinkManager();
Q_PROPERTY(bool isBluetoothAvailable READ isBluetoothAvailable CONSTANT)
......
......@@ -50,8 +50,8 @@ const char* MAVLinkProtocol::_logFileExtension = "mavlink"; ///< Ext
* The default constructor will create a new MAVLink object sending heartbeats at
* the MAVLINK_HEARTBEAT_DEFAULT_RATE to all connected links.
*/
MAVLinkProtocol::MAVLinkProtocol(QGCApplication* app)
: QGCTool(app)
MAVLinkProtocol::MAVLinkProtocol(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, m_enable_version_check(true)
, versionMismatchIgnore(false)
, systemId(255)
......
......@@ -43,7 +43,7 @@ class MAVLinkProtocol : public QGCTool
Q_OBJECT
public:
MAVLinkProtocol(QGCApplication* app);
MAVLinkProtocol(QGCApplication* app, QGCToolbox* toolbox);
~MAVLinkProtocol();
/** @brief Get the human-friendly name of this protocol */
......
......@@ -39,8 +39,8 @@ bool UASMessage::severityIsError()
}
}
UASMessageHandler::UASMessageHandler(QGCApplication* app)
: QGCTool(app)
UASMessageHandler::UASMessageHandler(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _activeVehicle(NULL)
, _activeComponent(-1)
, _multiComp(false)
......
......@@ -72,7 +72,7 @@ class UASMessageHandler : public QGCTool
Q_OBJECT
public:
explicit UASMessageHandler(QGCApplication* app);
explicit UASMessageHandler(QGCApplication* app, QGCToolbox* toolbox);
~UASMessageHandler();
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment