Commit e4e71de7 authored by Don Gagne's avatar Don Gagne

Remove remaining singletons

parent f9d58d34
...@@ -239,7 +239,6 @@ HEADERS += \ ...@@ -239,7 +239,6 @@ HEADERS += \
src/QGCPalette.h \ src/QGCPalette.h \
src/QGCQmlWidgetHolder.h \ src/QGCQmlWidgetHolder.h \
src/QGCQuickWidget.h \ src/QGCQuickWidget.h \
src/QGCSingleton.h \
src/QGCTemporaryFile.h \ src/QGCTemporaryFile.h \
src/QGCToolbox.h \ src/QGCToolbox.h \
src/QmlControls/CoordinateVector.h \ src/QmlControls/CoordinateVector.h \
...@@ -353,7 +352,6 @@ SOURCES += \ ...@@ -353,7 +352,6 @@ SOURCES += \
src/QGCPalette.cc \ src/QGCPalette.cc \
src/QGCQmlWidgetHolder.cpp \ src/QGCQmlWidgetHolder.cpp \
src/QGCQuickWidget.cc \ src/QGCQuickWidget.cc \
src/QGCSingleton.cc \
src/QGCTemporaryFile.cc \ src/QGCTemporaryFile.cc \
src/QGCToolbox.cc \ src/QGCToolbox.cc \
src/QGCGeo.cc \ src/QGCGeo.cc \
......
...@@ -27,9 +27,8 @@ ...@@ -27,9 +27,8 @@
#include "ArduCopterFirmwarePlugin.h" #include "ArduCopterFirmwarePlugin.h"
#include "Generic/GenericFirmwarePlugin.h" #include "Generic/GenericFirmwarePlugin.h"
IMPLEMENT_QGC_SINGLETON(ArduCopterFirmwarePlugin, ArduCopterFirmwarePlugin) APMCopterMode::APMCopterMode(uint32_t mode, bool settable) :
APMCustomMode(mode, settable)
APMCopterMode::APMCopterMode(uint32_t mode, bool settable) : APMCustomMode(mode, settable)
{ {
QMap<uint32_t,QString> enumToString; QMap<uint32_t,QString> enumToString;
enumToString.insert(STABILIZE, "Stabilize"); enumToString.insert(STABILIZE, "Stabilize");
......
...@@ -61,16 +61,9 @@ public: ...@@ -61,16 +61,9 @@ public:
class ArduCopterFirmwarePlugin : public APMFirmwarePlugin class ArduCopterFirmwarePlugin : public APMFirmwarePlugin
{ {
Q_OBJECT Q_OBJECT
DECLARE_QGC_SINGLETON(ArduCopterFirmwarePlugin, ArduCopterFirmwarePlugin)
public: public:
protected:
/// All access to singleton is through instance()
ArduCopterFirmwarePlugin(void); ArduCopterFirmwarePlugin(void);
private:
}; };
#endif #endif
...@@ -27,9 +27,8 @@ ...@@ -27,9 +27,8 @@
#include "ArduPlaneFirmwarePlugin.h" #include "ArduPlaneFirmwarePlugin.h"
#include "Generic/GenericFirmwarePlugin.h" #include "Generic/GenericFirmwarePlugin.h"
IMPLEMENT_QGC_SINGLETON(ArduPlaneFirmwarePlugin, ArduPlaneFirmwarePlugin) APMPlaneMode::APMPlaneMode(uint32_t mode, bool settable)
: APMCustomMode(mode, settable)
APMPlaneMode::APMPlaneMode(uint32_t mode, bool settable) : APMCustomMode(mode, settable)
{ {
QMap<uint32_t,QString> enumToString; QMap<uint32_t,QString> enumToString;
enumToString.insert(MANUAL, "Manual"); enumToString.insert(MANUAL, "Manual");
......
...@@ -59,16 +59,9 @@ public: ...@@ -59,16 +59,9 @@ public:
class ArduPlaneFirmwarePlugin : public APMFirmwarePlugin class ArduPlaneFirmwarePlugin : public APMFirmwarePlugin
{ {
Q_OBJECT Q_OBJECT
DECLARE_QGC_SINGLETON(ArduPlaneFirmwarePlugin, ArduPlaneFirmwarePlugin)
public: public:
protected:
/// All access to singleton is through instance()
ArduPlaneFirmwarePlugin(void); ArduPlaneFirmwarePlugin(void);
private:
}; };
#endif #endif
...@@ -27,9 +27,8 @@ ...@@ -27,9 +27,8 @@
#include "ArduRoverFirmwarePlugin.h" #include "ArduRoverFirmwarePlugin.h"
#include "Generic/GenericFirmwarePlugin.h" #include "Generic/GenericFirmwarePlugin.h"
IMPLEMENT_QGC_SINGLETON(ArduRoverFirmwarePlugin, ArduRoverFirmwarePlugin) APMRoverMode::APMRoverMode(uint32_t mode, bool settable)
: APMCustomMode(mode, settable)
APMRoverMode::APMRoverMode(uint32_t mode, bool settable) : APMCustomMode(mode, settable)
{ {
QMap<uint32_t,QString> enumToString; QMap<uint32_t,QString> enumToString;
enumToString.insert(MANUAL, "Manual"); enumToString.insert(MANUAL, "Manual");
......
...@@ -59,16 +59,9 @@ public: ...@@ -59,16 +59,9 @@ public:
class ArduRoverFirmwarePlugin : public APMFirmwarePlugin class ArduRoverFirmwarePlugin : public APMFirmwarePlugin
{ {
Q_OBJECT Q_OBJECT
DECLARE_QGC_SINGLETON(ArduRoverFirmwarePlugin, ArduRoverFirmwarePlugin)
public: public:
protected:
/// All access to singleton is through instance()
ArduRoverFirmwarePlugin(void); ArduRoverFirmwarePlugin(void);
private:
}; };
#endif #endif
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#ifndef FirmwarePlugin_H #ifndef FirmwarePlugin_H
#define FirmwarePlugin_H #define FirmwarePlugin_H
#include "QGCSingleton.h"
#include "QGCMAVLink.h" #include "QGCMAVLink.h"
#include "VehicleComponent.h" #include "VehicleComponent.h"
#include "AutoPilotPlugin.h" #include "AutoPilotPlugin.h"
...@@ -46,7 +45,7 @@ class Vehicle; ...@@ -46,7 +45,7 @@ class Vehicle;
/// in the base class supports mavlink generic firmware. Override the base clase virtuals /// in the base class supports mavlink generic firmware. Override the base clase virtuals
/// to create you firmware specific plugin. /// to create you firmware specific plugin.
class FirmwarePlugin : public QGCSingleton class FirmwarePlugin : public QObject
{ {
Q_OBJECT Q_OBJECT
...@@ -110,9 +109,6 @@ public: ...@@ -110,9 +109,6 @@ public:
/// Adds the parameter meta data to the Fact /// Adds the parameter meta data to the Fact
virtual void addMetaDataToFact(Fact* fact) = 0; virtual void addMetaDataToFact(Fact* fact) = 0;
protected:
FirmwarePlugin(void) { };
}; };
#endif #endif
/*===================================================================== /*=====================================================================
QGroundControl Open Source Ground Control Station QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
...@@ -31,51 +31,67 @@ ...@@ -31,51 +31,67 @@
#include "APM/ArduRoverFirmwarePlugin.h" #include "APM/ArduRoverFirmwarePlugin.h"
#include "PX4/PX4FirmwarePlugin.h" #include "PX4/PX4FirmwarePlugin.h"
FirmwarePluginManager::FirmwarePluginManager(QGCApplication* app)
: QGCTool(app)
, _arduCopterFirmwarePlugin(NULL)
, _arduPlaneFirmwarePlugin(NULL)
, _arduRoverFirmwarePlugin(NULL)
, _genericFirmwarePlugin(NULL)
, _px4FirmwarePlugin(NULL)
{
}
FirmwarePluginManager::~FirmwarePluginManager()
{
delete _arduCopterFirmwarePlugin;
delete _arduPlaneFirmwarePlugin;
delete _arduRoverFirmwarePlugin;
delete _genericFirmwarePlugin;
delete _px4FirmwarePlugin;
}
FirmwarePlugin* FirmwarePluginManager::firmwarePluginForAutopilot(MAV_AUTOPILOT autopilotType, MAV_TYPE vehicleType) FirmwarePlugin* FirmwarePluginManager::firmwarePluginForAutopilot(MAV_AUTOPILOT autopilotType, MAV_TYPE vehicleType)
{ {
switch (autopilotType) { switch (autopilotType) {
case MAV_AUTOPILOT_ARDUPILOTMEGA: case MAV_AUTOPILOT_ARDUPILOTMEGA:
switch (vehicleType) { switch (vehicleType) {
case MAV_TYPE_QUADROTOR: case MAV_TYPE_QUADROTOR:
case MAV_TYPE_HEXAROTOR: case MAV_TYPE_HEXAROTOR:
case MAV_TYPE_OCTOROTOR: case MAV_TYPE_OCTOROTOR:
case MAV_TYPE_TRICOPTER: case MAV_TYPE_TRICOPTER:
case MAV_TYPE_COAXIAL: case MAV_TYPE_COAXIAL:
case MAV_TYPE_HELICOPTER: case MAV_TYPE_HELICOPTER:
return ArduCopterFirmwarePlugin::instance(); if (!_arduCopterFirmwarePlugin) {
break; _arduCopterFirmwarePlugin = new ArduCopterFirmwarePlugin;
case MAV_TYPE_FIXED_WING: }
return ArduPlaneFirmwarePlugin::instance(); return _arduCopterFirmwarePlugin;
break; case MAV_TYPE_FIXED_WING:
case MAV_TYPE_GROUND_ROVER: if (!_arduPlaneFirmwarePlugin) {
case MAV_TYPE_SURFACE_BOAT: _arduPlaneFirmwarePlugin = new ArduPlaneFirmwarePlugin;
case MAV_TYPE_SUBMARINE:
return ArduRoverFirmwarePlugin::instance();
break;
case MAV_TYPE_GENERIC:
case MAV_TYPE_ANTENNA_TRACKER:
case MAV_TYPE_GCS:
case MAV_TYPE_AIRSHIP:
case MAV_TYPE_FREE_BALLOON:
case MAV_TYPE_ROCKET:
case MAV_TYPE_FLAPPING_WING:
case MAV_TYPE_KITE:
case MAV_TYPE_ONBOARD_CONTROLLER:
case MAV_TYPE_VTOL_DUOROTOR:
case MAV_TYPE_VTOL_QUADROTOR:
case MAV_TYPE_VTOL_TILTROTOR:
case MAV_TYPE_VTOL_RESERVED2:
case MAV_TYPE_VTOL_RESERVED3:
case MAV_TYPE_VTOL_RESERVED4:
case MAV_TYPE_VTOL_RESERVED5:
case MAV_TYPE_GIMBAL:
default:
return GenericFirmwarePlugin::instance();
break;
} }
case MAV_AUTOPILOT_PX4: return _arduPlaneFirmwarePlugin;
return PX4FirmwarePlugin::instance(); case MAV_TYPE_GROUND_ROVER:
case MAV_TYPE_SURFACE_BOAT:
case MAV_TYPE_SUBMARINE:
if (!_arduRoverFirmwarePlugin) {
_arduRoverFirmwarePlugin = new ArduRoverFirmwarePlugin;
}
return _arduRoverFirmwarePlugin;
default: default:
return GenericFirmwarePlugin::instance(); break;
}
case MAV_AUTOPILOT_PX4:
if (!_px4FirmwarePlugin) {
_px4FirmwarePlugin = new PX4FirmwarePlugin;
}
return _px4FirmwarePlugin;
default:
break;
}
if (!_genericFirmwarePlugin) {
_genericFirmwarePlugin = new GenericFirmwarePlugin;
} }
return _genericFirmwarePlugin;
} }
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
#include "QGCToolbox.h" #include "QGCToolbox.h"
class QGCApplication; class QGCApplication;
class ArduCopterFirmwarePlugin;
class ArduPlaneFirmwarePlugin;
class ArduRoverFirmwarePlugin;
class PX4FirmwarePlugin;
class GenericFirmwarePlugin;
/// FirmwarePluginManager is a singleton which is used to return the correct FirmwarePlugin for a MAV_AUTOPILOT type. /// FirmwarePluginManager is a singleton which is used to return the correct FirmwarePlugin for a MAV_AUTOPILOT type.
...@@ -42,13 +47,21 @@ class FirmwarePluginManager : public QGCTool ...@@ -42,13 +47,21 @@ class FirmwarePluginManager : public QGCTool
Q_OBJECT Q_OBJECT
public: public:
FirmwarePluginManager(QGCApplication* app) : QGCTool(app) { } FirmwarePluginManager(QGCApplication* app);
~FirmwarePluginManager();
/// Returns appropriate plugin for autopilot type. /// Returns appropriate plugin for autopilot type.
/// @param autopilotType Type of autopilot to return plugin for. /// @param autopilotType Type of autopilot to return plugin for.
/// @param vehicleType Vehicle type of autopilot to return plugin for. /// @param vehicleType Vehicle type of autopilot to return plugin for.
/// @return Singleton FirmwarePlugin instance for the specified MAV_AUTOPILOT. /// @return Singleton FirmwarePlugin instance for the specified MAV_AUTOPILOT.
FirmwarePlugin* firmwarePluginForAutopilot(MAV_AUTOPILOT autopilotType, MAV_TYPE vehicleType); FirmwarePlugin* firmwarePluginForAutopilot(MAV_AUTOPILOT autopilotType, MAV_TYPE vehicleType);
private:
ArduCopterFirmwarePlugin* _arduCopterFirmwarePlugin;
ArduPlaneFirmwarePlugin* _arduPlaneFirmwarePlugin;
ArduRoverFirmwarePlugin* _arduRoverFirmwarePlugin;
GenericFirmwarePlugin* _genericFirmwarePlugin;
PX4FirmwarePlugin* _px4FirmwarePlugin;
}; };
#endif #endif
...@@ -29,13 +29,6 @@ ...@@ -29,13 +29,6 @@
#include <QDebug> #include <QDebug>
IMPLEMENT_QGC_SINGLETON(GenericFirmwarePlugin, FirmwarePlugin)
GenericFirmwarePlugin::GenericFirmwarePlugin(void)
{
}
QList<VehicleComponent*> GenericFirmwarePlugin::componentsForVehicle(AutoPilotPlugin* vehicle) QList<VehicleComponent*> GenericFirmwarePlugin::componentsForVehicle(AutoPilotPlugin* vehicle)
{ {
Q_UNUSED(vehicle); Q_UNUSED(vehicle);
......
...@@ -32,8 +32,6 @@ ...@@ -32,8 +32,6 @@
class GenericFirmwarePlugin : public FirmwarePlugin class GenericFirmwarePlugin : public FirmwarePlugin
{ {
Q_OBJECT Q_OBJECT
DECLARE_QGC_SINGLETON(GenericFirmwarePlugin, FirmwarePlugin)
public: public:
// Overrides from FirmwarePlugin // Overrides from FirmwarePlugin
...@@ -49,9 +47,6 @@ public: ...@@ -49,9 +47,6 @@ public:
virtual bool sendHomePositionToVehicle(void); virtual bool sendHomePositionToVehicle(void);
virtual void addMetaDataToFact(Fact* fact); virtual void addMetaDataToFact(Fact* fact);
virtual QString getDefaultComponentIdParam(void) const { return QString(); } virtual QString getDefaultComponentIdParam(void) const { return QString(); }
private:
GenericFirmwarePlugin(void);
}; };
#endif #endif
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
#include <QDebug> #include <QDebug>
IMPLEMENT_QGC_SINGLETON(PX4FirmwarePlugin, FirmwarePlugin)
enum PX4_CUSTOM_MAIN_MODE { enum PX4_CUSTOM_MAIN_MODE {
PX4_CUSTOM_MAIN_MODE_MANUAL = 1, PX4_CUSTOM_MAIN_MODE_MANUAL = 1,
PX4_CUSTOM_MAIN_MODE_ALTCTL, PX4_CUSTOM_MAIN_MODE_ALTCTL,
...@@ -88,11 +86,6 @@ static const struct Modes2Name rgModes2Name[] = { ...@@ -88,11 +86,6 @@ static const struct Modes2Name rgModes2Name[] = {
}; };
PX4FirmwarePlugin::PX4FirmwarePlugin(void)
{
}
QList<VehicleComponent*> PX4FirmwarePlugin::componentsForVehicle(AutoPilotPlugin* vehicle) QList<VehicleComponent*> PX4FirmwarePlugin::componentsForVehicle(AutoPilotPlugin* vehicle)
{ {
Q_UNUSED(vehicle); Q_UNUSED(vehicle);
......
...@@ -34,11 +34,8 @@ class PX4FirmwarePlugin : public FirmwarePlugin ...@@ -34,11 +34,8 @@ class PX4FirmwarePlugin : public FirmwarePlugin
{ {
Q_OBJECT Q_OBJECT
DECLARE_QGC_SINGLETON(PX4FirmwarePlugin, FirmwarePlugin)
public: public:
// Overrides from FirmwarePlugin // Overrides from FirmwarePlugin
virtual bool isCapable(FirmwareCapabilities capabilities); virtual bool isCapable(FirmwareCapabilities capabilities);
virtual QList<VehicleComponent*> componentsForVehicle(AutoPilotPlugin* vehicle); virtual QList<VehicleComponent*> componentsForVehicle(AutoPilotPlugin* vehicle);
virtual QStringList flightModes(void); virtual QStringList flightModes(void);
...@@ -52,9 +49,6 @@ public: ...@@ -52,9 +49,6 @@ public:
virtual QString getDefaultComponentIdParam(void) const { return QString("SYS_AUTOSTART"); } virtual QString getDefaultComponentIdParam(void) const { return QString("SYS_AUTOSTART"); }
private: private:
/// All access to singleton is through AutoPilotPluginManager::instance
PX4FirmwarePlugin(void);
PX4ParameterMetaData _parameterMetaData; PX4ParameterMetaData _parameterMetaData;
}; };
......
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#include "QGCMessageBox.h" #include "QGCMessageBox.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "UDPLink.h" #include "UDPLink.h"
#include "QGCSingleton.h"
#include "LinkManager.h" #include "LinkManager.h"
#include "HomePositionManager.h" #include "HomePositionManager.h"
#include "UASMessageHandler.h" #include "UASMessageHandler.h"
...@@ -322,7 +321,11 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) ...@@ -322,7 +321,11 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting)
QGCApplication::~QGCApplication() QGCApplication::~QGCApplication()
{ {
_destroySingletons(); MainWindow* mainWindow = MainWindow::instance();
if (mainWindow) {
delete mainWindow;
}
shutdownVideoStreaming(); shutdownVideoStreaming();
delete _toolbox; delete _toolbox;
} }
...@@ -433,8 +436,6 @@ bool QGCApplication::_initForNormalAppBoot(void) ...@@ -433,8 +436,6 @@ bool QGCApplication::_initForNormalAppBoot(void)
{ {
QSettings settings; QSettings settings;
_createSingletons();
#ifdef __mobile__ #ifdef __mobile__
_styleIsDark = false; _styleIsDark = false;
#else #else
...@@ -573,37 +574,6 @@ QGCApplication* qgcApp(void) ...@@ -573,37 +574,6 @@ QGCApplication* qgcApp(void)
return QGCApplication::_app; return QGCApplication::_app;
} }
/// @brief We create all the non-ui based singletons here instead of allowing them to be created randomly
/// by calls to instance. The reason being that depending on boot sequence the singleton may end
/// up being creating on something other than the main thread.
void QGCApplication::_createSingletons(void)
{
// No dependencies
FirmwarePlugin* firmwarePlugin = GenericFirmwarePlugin::_createSingleton();
Q_UNUSED(firmwarePlugin);
Q_ASSERT(firmwarePlugin);
// No dependencies
firmwarePlugin = PX4FirmwarePlugin::_createSingleton();
firmwarePlugin = ArduCopterFirmwarePlugin::_createSingleton();
firmwarePlugin = ArduPlaneFirmwarePlugin::_createSingleton();
firmwarePlugin = ArduRoverFirmwarePlugin::_createSingleton();
}
void QGCApplication::_destroySingletons(void)
{
MainWindow* mainWindow = MainWindow::instance();
if (mainWindow) {
delete mainWindow;
}
GenericFirmwarePlugin::_deleteSingleton();
PX4FirmwarePlugin::_deleteSingleton();
ArduCopterFirmwarePlugin::_deleteSingleton();
ArduPlaneFirmwarePlugin::_deleteSingleton();
ArduRoverFirmwarePlugin::_deleteSingleton();
}
void QGCApplication::informationMessageBoxOnMainThread(const QString& title, const QString& msg) void QGCApplication::informationMessageBoxOnMainThread(const QString& title, const QString& msg)
{ {
QGCMessageBox::information(title, msg); QGCMessageBox::information(title, msg);
......
...@@ -168,8 +168,6 @@ private slots: ...@@ -168,8 +168,6 @@ private slots:
void _missingParamsDisplay(void); void _missingParamsDisplay(void);
private: private:
void _createSingletons(void);
void _destroySingletons(void);
void _loadCurrentStyle(void); void _loadCurrentStyle(void);
static const char* _settingsVersionKey; ///< Settings key which hold settings version static const char* _settingsVersionKey; ///< Settings key which hold settings version
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @brief Base class for global singletons
///
/// @author Don Gagne <don@thegagnes.com>
#include "QGCSingleton.h"
#include "QGCApplication.h"
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef QGCSINGLETON_H
#define QGCSINGLETON_H
#include <QObject>
#include <QMutex>
/// @def DECLARE_QGC_SINGLETON
/// Include this macro in your Derived Class definition
/// @param className Derived Class name
/// @param interfaceName If your class is accessed through an interface specify that, if not specify Derived class name.
#define DECLARE_QGC_SINGLETON(className, interfaceName) \
public: \
static interfaceName* instance(bool nullOk = false); \
static void setMockInstance(interfaceName* mock); \
static interfaceName* _createSingleton(void); \
static void _deleteSingleton(void); \
private: \
static interfaceName* _instance; \
static interfaceName* _mockInstance; \
static interfaceName* _realInstance; \
/// @def IMPLEMENT_QGC_SINGLETON
/// Include this macro in your Derived Class implementation
/// @param className Derived Class name
/// @param interfaceName If your class is accessed through an interface specify that, if not specify Derived class name.
#define IMPLEMENT_QGC_SINGLETON(className, interfaceName) \
interfaceName* className::_instance = NULL; \
interfaceName* className::_mockInstance = NULL; \
interfaceName* className::_realInstance = NULL; \
\
interfaceName* className::_createSingleton(void) \
{ \
Q_ASSERT(_instance == NULL); \
_instance = new className; \
return _instance; \
} \
\
void className::_deleteSingleton(void) \
{ \
if (className::_instance) { \
className* instance = qobject_cast<className*>(className::_instance); \
Q_ASSERT_X(instance != NULL, "QGCSingleton", "If you hit this assert you may have forgotten to clear a Mock instance"); \
className::_instance = NULL; \
delete instance; \
} \
} \
\
interfaceName* className::instance(bool nullOk) \
{ \
if (!nullOk) { \
Q_ASSERT_X(_instance, "QGCSingleton", "Request for singleton that is NULL. If you hit this, then you have likely run into a startup or shutdown sequence bug (possibly intermittent)."); \
} \
return _instance; \
} \
\
void className::setMockInstance(interfaceName* mock) \
{ \
if (mock) { \
Q_ASSERT(_instance); \
Q_ASSERT(!_realInstance); \
\
_realInstance = _instance; \
_instance = dynamic_cast<interfaceName*>(mock); \
Q_ASSERT(_instance); \
_mockInstance = mock; \
} else { \
Q_ASSERT(_instance); \
Q_ASSERT(_realInstance); \
\
_instance = _realInstance; \
_realInstance = NULL; \
_mockInstance = NULL; \
} \
}
class QGCApplication;
class UnitTest;
/// This is the base class for all app global singletons
///
/// All global singletons are created/destroyed at boot time by QGCApplication::_createSingletons and destroyed by QGC::Application::_destroySingletons.
/// This is done in order to make sure they are all created on the main thread. As such no other code other than Unit Test
/// code has access to the constructor/destructor. QGCSingleton supports replacing singletons with a mock implementation.
/// In this case your object must derive from an interface which in turn derives from QGCSingleton. Youu can then use
/// the setMock method to add and remove you mock implementation. See HomePositionManager example usage. In order to provide the
/// appropriate methods to make all this work you need to use the DECLARE_QGC_SINGLETON and IMPLEMENT_QGC_SINGLETON
/// macros as follows:
/// @code{.unparsed}
/// // Header file
///
/// class MySingleton : public QGCSingleton {
/// Q_OBJECT
///
/// DECLARE_QGC_SINGLETON(MySingleton, MySingleton)
///
/// ...
///
/// private:
/// // Constructor/Desctructor private since all access is through the singleton methods
/// MySingleton(QObject* parent == NULL);
/// ~MySingleton();
///
/// ...
/// }
///
/// // Code file
///
/// IMPLEMENT_QGC_SINGLETON(MySingleton, MySingleton)
///
/// MySingleton::MySingleton(QObject* parent) :
/// QGCSigleton(parent)