Commit d2923d8e authored by Don Gagne's avatar Don Gagne

Track Singletons in QGCApplication

- allow unit tests to use QGCApplication
- clear global singletons for each unit test run
parent 8b84127e
......@@ -335,6 +335,7 @@ FORMS += \
HEADERS += \
src/MG.h \
src/QGCApplication.h \
src/QGCSingleton.h \
src/uas/UASInterface.h \
src/uas/UAS.h \
src/uas/UASManager.h \
......@@ -493,6 +494,7 @@ HEADERS += \
SOURCES += \
src/main.cc \
src/QGCApplication.cc \
src/QGCSingleton.cc \
src/uas/UASManager.cc \
src/uas/UAS.cc \
src/comm/LinkManager.cc \
......
......@@ -27,9 +27,30 @@
#include "AutoPilotPluginManager.h"
#include "PX4/PX4AutoPilotPlugin.h"
#include "Generic/GenericAutoPilotPlugin.h"
#include "QGCApplication.h"
AutoPilotPluginManager* AutoPilotPluginManager::_instance = NULL;
AutoPilotPluginManager* AutoPilotPluginManager::instance(void)
{
if (_instance == NULL) {
_instance = new AutoPilotPluginManager(qgcApp());
Q_CHECK_PTR(_instance);
}
Q_ASSERT(_instance);
return _instance;
}
void AutoPilotPluginManager::deleteInstance(void)
{
_instance = NULL;
delete this;
}
AutoPilotPluginManager::AutoPilotPluginManager(QObject* parent) :
QObject(parent)
QGCSingleton(parent)
{
// All plugins are constructed here so that they end up on the correct thread
_pluginMap[MAV_AUTOPILOT_PX4] = new PX4AutoPilotPlugin(this);
......
......@@ -30,32 +30,33 @@
#include "UASInterface.h"
#include "VehicleComponent.h"
#include "QGCApplication.h"
#include "AutoPilotPlugin.h"
#include "QGCSingleton.h"
/// @file
/// @brief The AutoPilotPlugin manager is a singleton which maintains the list of AutoPilotPlugin objects.
///
/// @author Don Gagne <don@thegagnes.com>
class AutoPilotPluginManager : public QObject
class AutoPilotPluginManager : public QGCSingleton
{
Q_OBJECT
public:
/// @brief Returns the AutoPilotPluginManager singleton
static AutoPilotPluginManager* instance(void);
virtual void deleteInstance(void);
/// @brief Returns the singleton AutoPilot instance for the specified auto pilot type.
/// @param autopilotType Specified using the MAV_AUTOPILOT_* values.
AutoPilotPlugin* getInstanceForAutoPilotPlugin(int autopilotType);
private:
/// @brief Only QGCQpplication is allowed to call constructor. All access to singleton is through
/// QGCApplication::singletonAutoPilotPluginManager.
/// All access to singleton is through AutoPilotPluginManager::instance
AutoPilotPluginManager(QObject* parent = NULL);
/// @brief Only QGCQpplication is allowed to call constructor. All access to singleton is through
/// QGCApplication::singletonAutoPilotPluginManager.
friend class QGCApplication;
static AutoPilotPluginManager* _instance;
QMap<int, AutoPilotPlugin*> _pluginMap;
};
......
......@@ -167,7 +167,7 @@ QString PX4AutoPilotPlugin::getShortModeText(uint8_t baseMode, uint32_t customMo
mode = "|OFFBOARD";
}
} else {
mode = qgcApp()->singletonAutoPilotPluginManager()->getInstanceForAutoPilotPlugin(MAV_AUTOPILOT_GENERIC)->getShortModeText(baseMode, customMode);
mode = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(MAV_AUTOPILOT_GENERIC)->getShortModeText(baseMode, customMode);
}
return mode;
......
/*=====================================================================
/*=====================================================================
QGroundControl Open Source Ground Control Station
......@@ -48,13 +48,21 @@
#include "GAudioOutput.h"
#include "CmdLineOptParser.h"
#include "QGCMessageBox.h"
#include "MainWindow.h"
#include "UDPLink.h"
#include "MAVLinkSimulationLink.h"
#include "SerialLink.h"
#include "QGCSingleton.h"
#include "LinkManager.h"
#include "UASManager.h"
#include "AutoPilotPluginManager.h"
#ifdef QGC_RTLAB_ENABLED
#include "OpalLink.h"
#endif
#include "UDPLink.h"
#include "MAVLinkSimulationLink.h"
#include "SerialLink.h"
QGCApplication* QGCApplication::_app = NULL;
const char* QGCApplication::_deleteAllSettingsKey = "DeleteAllSettingsNextBoot";
const char* QGCApplication::_settingsVersionKey = "SettingsVersion";
......@@ -77,9 +85,12 @@ const char* QGCApplication::_savedFileParameterDirectoryName = "SavedParameters"
QGCApplication::QGCApplication(int &argc, char* argv[]) :
QApplication(argc, argv),
_mainWindow(NULL)
QApplication(argc, argv),
_mainWindow(NULL)
{
Q_ASSERT(_app == NULL);
_app = this;
// Set application information
this->setApplicationName(QGC_APPLICATION_NAME);
this->setOrganizationName(QGC_ORG_NAME);
......@@ -119,7 +130,12 @@ _mainWindow(NULL)
}
bool QGCApplication::init(void)
void QGCApplication::_initCommon(void)
{
_createSingletons();
}
bool QGCApplication::_initForNormalAppBoot(void)
{
QSettings settings;
......@@ -169,16 +185,6 @@ bool QGCApplication::init(void)
}
}
// If we made it this far and we still don't have a location. Either the specfied location was invalid
// or we coudn't create a default location. Either way, we need to let the user know and prompt for a new
/// settings.
if (savedFilesLocation.isEmpty()) {
QMessageBox::warning(MainWindow::instance(),
tr("Bad save location"),
tr("The location to save files to is invalid, or cannot be written to. Please provide a new one."));
MainWindow::instance()->showSettings();
}
mode = (enum MainWindow::CUSTOM_MODE) settings.value("QGC_CUSTOM_MODE", (int)MainWindow::CUSTOM_MODE_PX4).toInt();
settings.sync();
......@@ -202,17 +208,10 @@ bool QGCApplication::init(void)
// "Warning: Do not use this function in conjunction with Qt Style Sheets."
// setFont(fontDatabase.font(fontFamilyName, "Roman", 12));
// Start the comm link manager
splashScreen->showMessage(tr("Starting communication links"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141));
startLinkManager();
// Start the UAS Manager
splashScreen->showMessage(tr("Starting UAS manager"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141));
startUASManager();
// Start the user interface
splashScreen->showMessage(tr("Starting user interface"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141));
_mainWindow = MainWindow::_create(splashScreen, mode);
_mainWindow = new MainWindow(splashScreen, mode);
Q_CHECK_PTR(_mainWindow);
UDPLink* udpLink = NULL;
......@@ -232,21 +231,30 @@ bool QGCApplication::init(void)
#ifdef QGC_RTLAB_ENABLED
// Add OpalRT Link, but do not connect
OpalLink* opalLink = new OpalLink();
MainWindow::instance()->addLink(opalLink);
_mainWindow->addLink(opalLink);
#endif
// Remove splash screen
splashScreen->finish(_mainWindow);
_mainWindow->splashScreenFinished();
// If we made it this far and we still don't have a location. Either the specfied location was invalid
// or we coudn't create a default location. Either way, we need to let the user know and prompt for a new
/// settings.
if (savedFilesLocation.isEmpty()) {
QGCMessageBox::warning(tr("Bad save location"),
tr("The location to save files to is invalid, or cannot be written to. Please provide a new one."));
_mainWindow->showSettings();
}
if (settingsUpgraded) {
_mainWindow->showInfoMessage(tr("Settings Cleared"),
tr("The format for QGroundControl saved settings has been modified. "
"Your saved settings have been reset to defaults."));
tr("The format for QGroundControl saved settings has been modified. "
"Your saved settings have been reset to defaults."));
}
// Check if link could be connected
if (udpLink && !LinkManager::instance()->connectLink(udpLink))
if (udpLink && LinkManager::instance()->connectLink(udpLink))
{
QMessageBox::StandardButton button = QGCMessageBox::critical(tr("Could not connect UDP port. Is an instance of %1 already running?").arg(qAppName()),
tr("It is recommended to close the application and stop all instances. Click Yes to close."),
......@@ -263,66 +271,18 @@ bool QGCApplication::init(void)
return true;
}
/**
* @brief Destructor for the groundstation. It destroys all loaded instances.
*
**/
QGCApplication::~QGCApplication()
bool QGCApplication::_initForUnitTests(void)
{
delete UASManager::instance();
delete LinkManager::instance();
return true;
}
/**
* @brief Start the link managing component.
* @brief Destructor for the groundstation. It destroys all loaded instances.
*
* The link manager keeps track of all communication links and provides the global
* packet queue. It is the main communication hub
**/
void QGCApplication::startLinkManager()
QGCApplication::~QGCApplication()
{
LinkManager::instance();
}
/**
* @brief Start the Unmanned Air System Manager
*
**/
void QGCApplication::startUASManager()
{
// Load UAS plugins
QDir pluginsDir = QDir(qApp->applicationDirPath());
#if defined(Q_OS_WIN)
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
pluginsDir.cdUp();
#elif defined(Q_OS_LINUX)
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
pluginsDir.cdUp();
#elif defined(Q_OS_MAC)
if (pluginsDir.dirName() == "MacOS") {
pluginsDir.cdUp();
pluginsDir.cdUp();
pluginsDir.cdUp();
}
#endif
pluginsDir.cd("plugins");
UASManager::instance();
// Load plugins
QStringList pluginFileNames;
foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
QObject *plugin = loader.instance();
if (plugin) {
//populateMenus(plugin);
pluginFileNames += fileName;
//printf(QString("Loaded plugin from " + fileName + "\n").toStdString().c_str());
}
}
}
void QGCApplication::deleteAllSettingsNextBoot(void)
......@@ -415,7 +375,48 @@ void QGCApplication::setPromptFlightDataSave(bool promptForSave)
/// @brief Returns the QGCApplication object singleton.
QGCApplication* qgcApp(void)
{
QGCApplication* app = dynamic_cast<QGCApplication*>(qApp);
Q_ASSERT(app);
return app;
Q_ASSERT(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)
{
LinkManager* linkManager = LinkManager::instance();
Q_UNUSED(linkManager);
Q_ASSERT(linkManager);
UASManagerInterface* uasManager = UASManager::instance();
Q_UNUSED(uasManager);
Q_ASSERT(uasManager);
AutoPilotPluginManager* pluginManager = AutoPilotPluginManager::instance();
Q_UNUSED(pluginManager);
Q_ASSERT(pluginManager);
}
void QGCApplication::destroySingletonsForUnitTest(void)
{
foreach(QGCSingleton* singleton, _singletons) {
Q_ASSERT(singleton);
singleton->deleteInstance();
}
if (_mainWindow) {
_mainWindow->deleteInstance();
_mainWindow = NULL;
}
_singletons.clear();
}
void QGCApplication::registerSingleton(QGCSingleton* singleton)
{
Q_ASSERT(singleton);
Q_ASSERT(!_singletons.contains(singleton));
_singletons.append(singleton);
}
......@@ -29,19 +29,18 @@
*
*/
#ifndef QGCAPPLICATION_H
#define QGCAPPLICATION_H
#include <QApplication>
#include "MainWindow.h"
#include "UASManager.h"
#include "LinkManager.h"
#ifdef QGC_RTLAB_ENABLED
#include "OpalLink.h"
#endif
// Work around circular header includes
class QGCSingleton;
class MainWindow;
/**
* @brief The main application and management class.
......@@ -58,10 +57,6 @@ public:
QGCApplication(int &argc, char* argv[]);
~QGCApplication();
/// @brief Initialize the applicaation.
/// @return false: init failed, app should exit
bool init(void);
/// @brief Sets the persistent flag to delete all settings the next time QGroundControl is started.
void deleteAllSettingsNextBoot(void);
......@@ -88,19 +83,34 @@ public:
/// @brief Sets the flag to log all mavlink connections
void setPromptFlightDataSave(bool promptForSave);
/// @brief All global singletons must be registered such that QGCApplication::destorySingletonsForUnitTest
/// can work correctly.
void registerSingleton(QGCSingleton* singleton);
/// @brief Creates non-ui based singletons for unit testing
void createSingletonsForUnitTest(void) { _createSingletons(); }
/// @brief Destroys all singletons. Used by unit test code to reset global state.
void destroySingletonsForUnitTest(void);
public:
/// @brief Perform initialize which is common to both normal application running and unit tests.
/// Although public should only be called by main.
void _initCommon(void);
/// @brief Intialize the application for normal application boot. Or in other words we are not going to run
/// unit tests. Although public should only be called by main.
bool _initForNormalAppBoot(void);
protected:
void startLinkManager();
/// @brief Intialize the application for normal application boot. Or in other words we are not going to run
/// unit tests. Although public should only be called by main.
bool _initForUnitTests(void);
/**
* @brief Start the robot managing system
*
* The robot manager keeps track of the configured robots.
**/
void startUASManager();
static QGCApplication* _app; ///< Our own singleton. Should be reference directly by qgcApp
private:
MainWindow* _mainWindow;
void _createSingletons(void);
static const char* _settingsVersionKey; ///< Settings key which hold settings version
static const char* _deleteAllSettingsKey; ///< If this settings key is set on boot, all settings will be deleted
......@@ -110,6 +120,10 @@ private:
static const char* _defaultSavedFileDirectoryName; ///< Default name for user visible save file directory
static const char* _savedFileMavlinkLogDirectoryName; ///< Name of mavlink log subdirectory
static const char* _savedFileParameterDirectoryName; ///< Name of parameter subdirectory
MainWindow* _mainWindow;
QList<QGCSingleton*> _singletons; ///< List of registered global singletons
};
/// @brief Returns the QGCApplication object singleton.
......
/*=====================================================================
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"
QGCSingleton::QGCSingleton(QObject* parent) :
QObject(parent)
{
qgcApp()->registerSingleton(this);
}
/*=====================================================================
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>
#ifndef QGCSINGLETON_H
#define QGCSINGLETON_H
#include <QObject>
#include "QGCApplication.h"
class QGCSingleton : public QObject
{
Q_OBJECT
public:
/// @brief Contructor will register singleton to QGCApplication
QGCSingleton(QObject* parent = NULL);
/// @brief Implementation should delete the singleton such that next call to instance
/// will create a new singleton.
virtual void deleteInstance(void) = 0;
};
#endif
......@@ -28,7 +28,7 @@
#include "ui_SetupView.h"
#include "UASManager.h"
#include "AutoPilotPlugin.h"
#include "AutoPilotPluginManager.h"
#include "VehicleComponent.h"
#include "VehicleComponentButton.h"
#include "SummaryPage.h"
......@@ -208,7 +208,7 @@ void SetupView::_parametersReady(void)
_ui->summaryButton->setVisible(true);
_components = AutoPilotPlugin::getInstanceForAutoPilotPlugin(_uasCurrent->getAutopilotType())->getVehicleComponents(_uasCurrent);
_components = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uasCurrent->getAutopilotType())->getVehicleComponents(_uasCurrent);
foreach(VehicleComponent* component, _components) {
VehicleComponentButton* button = new VehicleComponentButton(component, _ui->navBarWidget);
......
......@@ -36,26 +36,35 @@ This file is part of the QGROUNDCONTROL project
#include "LinkManager.h"
#include "MainWindow.h"
#include "QGCMessageBox.h"
#include "QGCApplication.h"
LinkManager* LinkManager::instance()
LinkManager* LinkManager::_instance = NULL;
LinkManager* LinkManager::instance(void)
{
static LinkManager* _instance = 0;
if(_instance == 0) {
_instance = new LinkManager();
/* Set the application as parent to ensure that this object
* will be destroyed when the main application exits */
_instance->setParent(qApp);
_instance = new LinkManager(qgcApp());
Q_CHECK_PTR(_instance);
}
Q_ASSERT(_instance);
return _instance;
}
void LinkManager::deleteInstance(void)
{
_instance = NULL;
delete this;
}
/**
* @brief Private singleton constructor
*
* This class implements the singleton design pattern and has therefore only a private constructor.
**/
LinkManager::LinkManager() :
LinkManager::LinkManager(QObject* parent) :
QGCSingleton(parent),
_connectionsSuspended(false)
{
_links = QList<LinkInterface*>();
......
......@@ -36,9 +36,11 @@ This file is part of the PIXHAWK project
#include <QList>
#include <QMultiMap>
#include <QMutex>
#include <LinkInterface.h>
#include <SerialLink.h>
#include <ProtocolInterface.h>
#include "LinkInterface.h"
#include "SerialLink.h"
#include "ProtocolInterface.h"
#include "QGCSingleton.h"
/**
* The Link Manager organizes the physical Links. It can manage arbitrary
......@@ -46,12 +48,16 @@ This file is part of the PIXHAWK project
* protocol instance to transport the link data into the application.
*
**/
class LinkManager : public QObject
class LinkManager : public QGCSingleton
{
Q_OBJECT
public:
static LinkManager* instance();
/// @brief Returns the LinkManager singleton
static LinkManager* instance(void);
virtual void deleteInstance(void);
~LinkManager();
void run();
......@@ -100,14 +106,16 @@ signals:
void linkRemoved(LinkInterface* link);
private:
LinkManager(void);
/// @brief All access to LinkManager is through LinkManager::instance
LinkManager(QObject* parent = NULL);
static LinkManager* _instance;
QList<LinkInterface*> _links;
QMultiMap<ProtocolInterface*,LinkInterface*> _protocolLinks;
QMutex _dataMutex;
bool _connectionsSuspendedMsg(void);
static LinkManager* _instance;
bool _connectionsSuspended; ///< true: all new connections should not be allowed
QString _connectionsSuspendedReason; ///< User visible reason for suspension
......
......@@ -124,8 +124,19 @@ int main(int argc, char *argv[])
_CrtSetReportHook(WindowsCrtReportHook);
#endif
}
#endif
QGCApplication* app = new QGCApplication(argc, argv);
Q_CHECK_PTR(app);
app->_initCommon();
#ifdef QT_DEBUG
if (runUnitTests) {
if (!app->_initForUnitTests()) {
return -1;
}
// Run the test
int failures = AutoTest::run(argc-1, argv);
if (failures == 0)
......@@ -136,16 +147,13 @@ int main(int argc, char *argv[])
{
qDebug() << failures << " TESTS FAILED!";
}
return failures;
}
return -failures;
} else
#endif
QGCApplication* app = new QGCApplication(argc, argv);
Q_CHECK_PTR(app);
if (!app->init()) {
return -1;
{
if (!app->_initForNormalAppBoot()) {
return -1;
}
return app->exec();
}
return app->exec();
}
......@@ -11,6 +11,7 @@
#include <QList>
#include <QString>
#include <QSharedPointer>
#include "QGCApplication.h"
namespace AutoTest
{
......@@ -51,10 +52,11 @@ namespace AutoTest
inline int run(int argc, char *argv[])
{
int ret = 0;
QApplication t(argc, argv);
foreach (QObject* test, testList())
{
ret += QTest::qExec(test, argc, argv);
{
qgcApp()->destroySingletonsForUnitTest();
qgcApp()->createSingletonsForUnitTest();
ret += QTest::qExec(test, argc, argv);
}
return ret;
......@@ -76,10 +78,4 @@ public:
#define DECLARE_TEST(className) static Test<className> t(#className);
#define TEST_MAIN \
int main(int argc, char *argv[]) \
{ \
return AutoTest::run(argc, argv); \
}
#endif // AUTOTEST_H
......@@ -53,6 +53,9 @@ public:
// MockUASManager methods
MockUASManager(void);
// Does not support singleton deletion
virtual void deleteInstance(void) { Q_ASSERT(false); }
/// Sets the currently active mock UAS
/// @param mockUAS new mock uas, NULL for no active UAS
void setMockActiveUAS(MockUAS* mockUAS);
......
......@@ -29,7 +29,7 @@
#include "SerialLink.h"
#include "UASParameterCommsMgr.h"
#include <Eigen/Geometry>
#include "AutoPilotPlugin.h"
#include "AutoPilotPluginManager.h"
#include "QGCMessageBox.h"
/**
......@@ -3304,7 +3304,7 @@ QString UAS::getAudioModeTextFor(int id)
*/
QString UAS::getShortModeTextFor(uint8_t base_mode, uint32_t custom_mode, int autopilot)
{
QString mode = AutoPilotPlugin::getInstanceForAutoPilotPlugin(autopilot)->getShortModeText(base_mode, custom_mode);
QString mode = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(autopilot)->getShortModeText(base_mode, custom_mode);
if (mode.length() == 0)
{
......
......@@ -18,11 +18,13 @@
#include "UASManager.h"
#include "QGC.h"
#include "QGCMessageBox.h"
#include "QGCApplication.h"
#define PI 3.1415926535897932384626433832795
#define MEAN_EARTH_DIAMETER 12756274.0
#define UMR 0.017453292519943295769236907684886
UASManager* UASManager::_instance = NULL;
UASManagerInterface* UASManager::_mockUASManager = NULL;
......@@ -37,17 +39,22 @@ UASManagerInterface* UASManager::instance()
return _mockUASManager;
}
static UASManager* _instance = 0;
if(_instance == 0) {
_instance = new UASManager();
// Set the application as parent to ensure that this object
// will be destroyed when the main application exits
_instance->setParent(qApp);
if(_instance == NULL) {
_instance = new UASManager(qgcApp());
Q_CHECK_PTR(_instance);
}
Q_ASSERT(_instance);
return _instance;
}
void UASManager::deleteInstance(void)
{
_instance = NULL;
delete this;
}
void UASManager::storeSettings()
{
QSettings settings;
......@@ -256,13 +263,14 @@ void UASManager::uavChangedHomePosition(int uav, double lat, double lon, double
*
* This class implements the singleton design pattern and has therefore only a private constructor.
**/
UASManager::UASManager() :
activeUAS(NULL),
offlineUASWaypointManager(NULL),
homeLat(47.3769),
homeLon(8.549444),
homeAlt(470.0),
homeFrame(MAV_FRAME_GLOBAL)
UASManager::UASManager(QObject* parent) :
UASManagerInterface(parent),
activeUAS(NULL),
offlineUASWaypointManager(NULL),
homeLat(47.3769),
homeLon(8.549444),
homeAlt(470.0),
homeFrame(MAV_FRAME_GLOBAL)
{
loadSettings();
setLocalNEDSafetyBorders(1, -1, 0, -1, 1, -1);
......
......@@ -38,6 +38,7 @@ This file is part of the QGROUNDCONTROL project
#include <UASInterface.h>
#include "../../libs/eigen/Eigen/Eigen"
#include "QGCGeo.h"
#include "QGCApplication.h"
/**
* @brief Central manager for all connected aerial vehicles
......@@ -50,7 +51,11 @@ class UASManager : public UASManagerInterface
Q_OBJECT
public:
static UASManagerInterface* instance();
/// @brief Returns the UASManager singleton
static UASManagerInterface* instance(void);
virtual void deleteInstance(void);
~UASManager();
/**
......@@ -249,7 +254,6 @@ public slots:
protected:
UASManager();
QList<UASInterface*> systems;
UASInterface* activeUAS;
UASWaypointManager *offlineUASWaypointManager;
......@@ -266,6 +270,11 @@ protected:
void initReference(const double & latitude, const double & longitude, const double & altitude);
private:
/// @brief All access to UASManager singleton is through UASManager::instance
UASManager(QObject* parent = NULL);
static UASManager* _instance;
static UASManagerInterface* _mockUASManager;
public:
......
......@@ -34,9 +34,11 @@
#include <QThread>
#include <QList>
#include <QMutex>
#include <UASInterface.h>
#include "UASInterface.h"
#include "../../libs/eigen/Eigen/Eigen"
#include "QGCGeo.h"
#include "QGCSingleton.h"
/**
* @brief Central manager for all connected aerial vehicles
......@@ -50,11 +52,13 @@
*
* See UASManager.h for method documentation
**/
class UASManagerInterface : public QObject
class UASManagerInterface : public QGCSingleton
{
Q_OBJECT
public:
UASManagerInterface(QObject* parent = NULL) : QGCSingleton(parent) { }
virtual UASInterface* getActiveUAS() = 0;
virtual UASWaypointManager *getActiveUASWaypointManager() = 0;
virtual UASInterface* silentGetActiveUAS() = 0;
......
......@@ -108,6 +108,12 @@ MainWindow* MainWindow::instance(void)
return _instance;
}
void MainWindow::deleteInstance(void)
{
delete _instance;
_instance = NULL;
}
/// @brief Private constructor for MainWindow. MainWindow singleton is only ever created
/// by MainWindow::_create method. Hence no other code should have access to
/// constructor.
......
......@@ -102,6 +102,9 @@ public:
/// been created.
static MainWindow* instance(void);
/// @brief Deletes the MainWindow singleton
void deleteInstance(void);
/// @brief Creates the MainWindow singleton. Should only be called once by QGCApplication.
static MainWindow* _create(QSplashScreen* splashScreen, enum MainWindow::CUSTOM_MODE mode);
......@@ -469,6 +472,11 @@ private:
/// Constructor is private since all creation should be through MainWindow::instance.
MainWindow(QSplashScreen* splashScreen, enum MainWindow::CUSTOM_MODE mode);
/// @brief Two phase construction such that MainWindow::instance is available to code
void _init(void);
friend class QGCApplication;
void _hideSplashScreen(void);
void _openUrl(const QString& url, const QString& errorMessage);
......
......@@ -39,7 +39,7 @@ This file is part of the PIXHAWK project
#include <UASManager.h>
#include <UAS.h>
#include "QGC.h"
#include "AutoPilotPlugin.h"
#include "AutoPilotPluginManager.h"
UASControlWidget::UASControlWidget(QWidget *parent) : QWidget(parent),
uasID(-1),
......@@ -68,7 +68,7 @@ void UASControlWidget::updateModesList()
}
}
AutoPilotPlugin* autopilotPlugin = AutoPilotPlugin::getInstanceForAutoPilotPlugin(autopilot);
AutoPilotPlugin* autopilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(autopilot);
_modeList = autopilotPlugin->getModes();
......
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