19 changed files with 84 additions and 331 deletions
@ -1,31 +0,0 @@ |
|||||||
/*=====================================================================
|
|
||||||
|
|
||||||
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" |
|
||||||
|
|
@ -1,152 +0,0 @@ |
|||||||
/*=====================================================================
|
|
||||||
|
|
||||||
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)
|
|
||||||
/// {
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Other class methods...
|
|
||||||
///
|
|
||||||
/// @endcode
|
|
||||||
/// The example above does not use an inteface so the second parameter to the macro is the class name as well.
|
|
||||||
|
|
||||||
class QGCSingleton : public QObject |
|
||||||
{ |
|
||||||
Q_OBJECT |
|
||||||
|
|
||||||
}; |
|
||||||
|
|
||||||
#endif |
|
Loading…
Reference in new issue