mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-20 20:40:29 +08:00
#31 Squashed merge of commits relating to the plugin system and IContext redesign, from the 'interconnect' branch.
This commit is contained in:
@@ -3,247 +3,224 @@
|
||||
//! License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
//! file, You can obtain one at http://mozilla.org/MPL/2.0/
|
||||
|
||||
#ifndef CONTEXT_H
|
||||
#define CONTEXT_H
|
||||
#ifndef BLACKMISC_CONTEXT_H
|
||||
#define BLACKMISC_CONTEXT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
class CLog;
|
||||
|
||||
class CDebug;
|
||||
|
||||
//! IContext Interface.
|
||||
/*!
|
||||
This interface abstracts any application and library context. Use it to
|
||||
add singleton classes and for application and library wide logging.
|
||||
*/
|
||||
class IContext
|
||||
{
|
||||
public:
|
||||
|
||||
//! Reference to IConext.
|
||||
/*!
|
||||
This static function returns a reference to the singleton object.
|
||||
Use always this method to retrieve the context, since you cannot
|
||||
instantiate your own one. Before it can be used you have to create
|
||||
either a CApplicationContext or a CLibraryContext in the very
|
||||
beginning of the executable/libary.
|
||||
*/
|
||||
static IContext &getInstance();
|
||||
|
||||
//! Returns true if the context is initialized and ready.
|
||||
/*!
|
||||
\return Returns true if context is initialized, otherwise false.
|
||||
*/
|
||||
static bool isInitialised();
|
||||
|
||||
//! Destructor.
|
||||
/*!
|
||||
Destroys the context.
|
||||
*/
|
||||
virtual ~IContext();
|
||||
|
||||
//! Pure virtual method returns the pointer to singletone object by its name.
|
||||
/*!
|
||||
\param singletonName a reference to the singletones name.
|
||||
\return Returns a pointer to the singleton object.
|
||||
*/
|
||||
virtual void *singletonPointer(const QString &singletonName) = 0;
|
||||
|
||||
//! Pure virtual method sets the singletone pointer, given by its name.
|
||||
/*!
|
||||
\param singletonName a reference to the singletones name.
|
||||
\param object a pointer to the singletone object.
|
||||
*/
|
||||
virtual void setSingletonPointer(const QString &singletonName, void *object) = 0;
|
||||
|
||||
//! Deallocates the object and removes the singletone pointer from the context map.
|
||||
/*!
|
||||
\param singletonName a reference to the singletones name.
|
||||
\param object a pointer to the singletone object.
|
||||
*/
|
||||
virtual void releaseSingletonPointer(const QString &singletonName, void *object) = 0;
|
||||
|
||||
//! Pure virtual method returns the pointer to debug object
|
||||
/*!
|
||||
\return Pointer to CDebug object
|
||||
*/
|
||||
virtual CDebug *getDebug() = 0;
|
||||
|
||||
//! Pure virtual function to set the global error log object
|
||||
/*!
|
||||
\param Pointer to CDebug object
|
||||
*/
|
||||
virtual void setDebug(CDebug *debug) = 0;
|
||||
|
||||
protected:
|
||||
//! Method to register the context.
|
||||
/*! This method should be called by the derived class. It sets the
|
||||
context variable to the calling object.*/
|
||||
/*!
|
||||
\param Pointer to CLog object
|
||||
*/
|
||||
void registerContext();
|
||||
|
||||
//! Pointer to the global context.
|
||||
/*!
|
||||
This variable holds a pointer to the application context.
|
||||
*/
|
||||
static IContext *m_context;
|
||||
|
||||
//! Pointer to the global Debug object.
|
||||
/*!
|
||||
This member variable contains all logging types, not only debug.
|
||||
*/
|
||||
CDebug *m_debug;
|
||||
|
||||
};
|
||||
|
||||
//! CApplicationContext.
|
||||
/*!
|
||||
This class implements the IContext interface for applications.
|
||||
*/
|
||||
class CApplicationContext : public IContext
|
||||
{
|
||||
public:
|
||||
CApplicationContext();
|
||||
|
||||
//! This method returns the pointer to singletone object by its name.
|
||||
/*!
|
||||
\param singletonName a reference to the singletones name.
|
||||
\return Returns a pointer to the singleton object.
|
||||
*/
|
||||
virtual void *singletonPointer(const QString &singletonName);
|
||||
|
||||
//! Sets the singletone pointer, given by its name.
|
||||
/*!
|
||||
\param singletonName a reference to the singletones name.
|
||||
\param object a pointer to the singletone object.
|
||||
*/
|
||||
virtual void setSingletonPointer(const QString &singletonName, void *object);
|
||||
|
||||
//! Deallocates the object and removes the singletone pointer from the context map.
|
||||
/*!
|
||||
\param singletonName a reference to the singletones name.
|
||||
\param object a pointer to the singletone object.
|
||||
*/
|
||||
virtual void releaseSingletonPointer(const QString &singletonName, void *ptr);
|
||||
|
||||
//! Pure virtual method returns the pointer to debug object
|
||||
/*!
|
||||
Keeps track of all singleton and pseudo-singleton objects.
|
||||
*/
|
||||
class IContext
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
\return Pointer to CDebug object
|
||||
Returns a reference to the static global context singleton.
|
||||
\return
|
||||
\warning Do not use this from within a plugin.
|
||||
*/
|
||||
virtual CDebug *getDebug();
|
||||
static IContext &getInstance();
|
||||
|
||||
//! Pure virtual function to set the global error log object
|
||||
/*!
|
||||
\param Pointer to CDebug object
|
||||
Destructor.
|
||||
*/
|
||||
virtual void setDebug(CDebug *debug);
|
||||
virtual ~IContext();
|
||||
|
||||
private:
|
||||
//! Typedef for the singleton map
|
||||
typedef QMap<QString, void*> TSingletonMap;
|
||||
|
||||
//! Map of all registered objects inside the application.
|
||||
/*!
|
||||
This map holds associates all registered singleton objects to their names.
|
||||
*/
|
||||
TSingletonMap m_singletonObjects;
|
||||
};
|
||||
|
||||
//! CApplicationContext.
|
||||
/*!
|
||||
This class implements the IContext interface for libraries.
|
||||
*/
|
||||
class CLibraryContext : public IContext
|
||||
{
|
||||
public:
|
||||
CLibraryContext (IContext &application);
|
||||
|
||||
//! This method returns the pointer to singletone object by its name.
|
||||
/*!
|
||||
\param singletonName a reference to the singletones name.
|
||||
\return Returns a pointer to the singleton object.
|
||||
*/
|
||||
virtual void *singletonPointer(const QString &singletonName);
|
||||
|
||||
//! Sets the singletone pointer, given by its name.
|
||||
/*!
|
||||
\param singletonName a reference to the singletones name.
|
||||
\param object a pointer to the singletone object.
|
||||
*/
|
||||
virtual void setSingletonPointer(const QString &singletonName, void *ptr);
|
||||
|
||||
//! Deallocates the object and removes the singletone pointer from the context map.
|
||||
/*!
|
||||
\param singletonName a reference to the singletones name.
|
||||
\param object a pointer to the singletone object.
|
||||
*/
|
||||
virtual void releaseSingletonPointer(const QString &singletonName, void *ptr);
|
||||
|
||||
//! Pure virtual method returns the pointer to debug object
|
||||
/*!
|
||||
\return Pointer to CDebug object
|
||||
Returns the pointer to a singleton object by its name.
|
||||
You usually use the template overload of this method instead.
|
||||
\param singletonName
|
||||
\return
|
||||
\throw std::logic_error The requested singleton is not present.
|
||||
*/
|
||||
virtual CDebug *getDebug();
|
||||
virtual QObject *singleton(const QString &singletonName) = 0;
|
||||
|
||||
//! Pure virtual function to set the global error log object
|
||||
/*!
|
||||
\param Pointer to CDebug object
|
||||
Returns true if a singleton object with the give name is present.
|
||||
You usually use the template overload of this method instead.
|
||||
\param singletonName
|
||||
\return
|
||||
*/
|
||||
virtual void setDebug(CDebug *debug);
|
||||
|
||||
private:
|
||||
//! Pointer the application context.
|
||||
/*!
|
||||
Libraries do not have their own context, because they are using
|
||||
the one from the linked application.
|
||||
*/
|
||||
IContext *m_applicationContext;
|
||||
};
|
||||
virtual bool hasSingleton(const QString &singletonName) const = 0;
|
||||
|
||||
/*!
|
||||
Sets a singleton pointer, given by its name.
|
||||
You usually use the template overload of this method instead.
|
||||
\param singletonName
|
||||
\param object
|
||||
*/
|
||||
virtual void setSingleton(const QString &singletonName, QObject *object) = 0;
|
||||
|
||||
/*!
|
||||
Removes the singleton pointer, given by its name.
|
||||
You usually use the template overload of this method instead.
|
||||
\param singletonName
|
||||
\param object
|
||||
*/
|
||||
virtual void releaseSingleton(const QString &singletonName) = 0;
|
||||
|
||||
/*!
|
||||
Return the singleton pointer with the type T.
|
||||
\tparam T An interface defined with the BLACK_INTERFACE macro.
|
||||
\return
|
||||
\throw std::logic_error The requested singleton is not present.
|
||||
*/
|
||||
template <class T>
|
||||
T *singleton()
|
||||
{
|
||||
QObject *qobj = singleton(T::blackInterfaceId());
|
||||
T *t = qobject_cast<T *>(qobj);
|
||||
Q_ASSERT_X(t, "IContext", "qobject_cast failed");
|
||||
return t;
|
||||
}
|
||||
|
||||
/*!
|
||||
Return true if the requested singleton in present in the context.
|
||||
\tparam T An interface defined with the BLACK_INTERFACE macro.
|
||||
\return
|
||||
*/
|
||||
template <class T>
|
||||
bool hasSingleton() const
|
||||
{
|
||||
return hasSingleton(T::blackInterfaceId());
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the singleton pointer with the type T.
|
||||
\tparam T An interface defined with the BLACK_INTERFACE macro.
|
||||
\param object
|
||||
*/
|
||||
template <class T>
|
||||
void setSingleton(T *object)
|
||||
{
|
||||
setSingleton(T::blackInterfaceId(), object);
|
||||
}
|
||||
|
||||
/*!
|
||||
Remove the singleton pointer with the type T.
|
||||
\tparam T An interface defined with the BLACK_INTERFACE macro.
|
||||
*/
|
||||
template <class T>
|
||||
void releaseSingleton()
|
||||
{
|
||||
releaseSingleton(T::blackInterfaceId());
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the global name of the application.
|
||||
\param appName
|
||||
*/
|
||||
virtual void setApplicationName(const QString &appName) = 0;
|
||||
|
||||
/*!
|
||||
Set the application name to the default.
|
||||
*/
|
||||
virtual void setDefaultApplicationName() = 0;
|
||||
|
||||
/*!
|
||||
Return the global name of the application.
|
||||
\return
|
||||
*/
|
||||
virtual const QString &getApplicationName() const = 0;
|
||||
|
||||
/*!
|
||||
Return the CDebug singleton.
|
||||
\return
|
||||
\deprecated Use getSingletonPointer<CDebug>() instead.
|
||||
\throw std::logic_error The requested singleton is not present.
|
||||
*/
|
||||
virtual CDebug *getDebug() = 0;
|
||||
|
||||
/*!
|
||||
Set the CDebug singleton.
|
||||
\param debug
|
||||
\deprecated Use setSingletonPointer<CDebug>() instead.
|
||||
*/
|
||||
virtual void setDebug(CDebug *debug) = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
This macros helps to create the body of a singletone class,
|
||||
which registers itself with the application context.
|
||||
*/
|
||||
#define SINGLETON_CLASS_DECLARATION(className) \
|
||||
private:\
|
||||
/* Singletone class constructor */ \
|
||||
className (const className &) {}\
|
||||
/* the local static pointer to the singleton instance */ \
|
||||
static className *m_instance; \
|
||||
public:\
|
||||
static className &getInstance() \
|
||||
Enable an interface to be manipulated with the template methods of IContext.
|
||||
Put this macro in the public section of the interface definition.
|
||||
\param FQNAME The fully qualified name of the interface (e.g. BlackMisc::IWhatever).
|
||||
*/
|
||||
#define BLACK_INTERFACE(FQNAME) static const char *blackInterfaceId() { return #FQNAME ; }
|
||||
|
||||
/*!
|
||||
Default implementation of the IContext interface.
|
||||
*/
|
||||
class CApplicationContext : public IContext
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Constructor
|
||||
*/
|
||||
CApplicationContext();
|
||||
|
||||
virtual QObject *singleton(const QString &singletonName);
|
||||
virtual bool hasSingleton(const QString &singletonName) const;
|
||||
virtual void setSingleton(const QString &singletonName, QObject *object);
|
||||
virtual void releaseSingleton(const QString &singletonName);
|
||||
virtual CDebug *getDebug();
|
||||
virtual void setDebug(CDebug *debug);
|
||||
virtual void setApplicationName(const QString &applicationName) { m_appName = applicationName; }
|
||||
virtual void setDefaultApplicationName();
|
||||
virtual const QString &getApplicationName() const { return m_appName; }
|
||||
|
||||
private:
|
||||
typedef QMap<QString, QObject *> TSingletonMap;
|
||||
|
||||
TSingletonMap m_singletons;
|
||||
|
||||
QString m_appName;
|
||||
};
|
||||
|
||||
/*!
|
||||
This macros helps to create the body of a singletone class,
|
||||
which registers itself with the application context.
|
||||
\warning Singletons defined with this macro will not be accessible in plugins.
|
||||
\deprecated Preferred way is, during application initialization,
|
||||
construct singletons and register them manually,
|
||||
and when you want to access them, do it through the IContext.
|
||||
*/
|
||||
#define SINGLETON_CLASS_DECLARATION(className) \
|
||||
private:\
|
||||
/* Forbid copying */ \
|
||||
className (const className &); \
|
||||
className &operator= (const className &); \
|
||||
/* the local static pointer to the singleton instance */ \
|
||||
static className *m_instance; \
|
||||
public:\
|
||||
static className &getInstance() \
|
||||
{ \
|
||||
if (m_instance == NULL) \
|
||||
{ \
|
||||
/* Get the singleton object from the context, if there is one */ \
|
||||
if (BlackMisc::IContext::getInstance().hasSingleton(#className)) \
|
||||
{ \
|
||||
if (m_instance == NULL) \
|
||||
{ \
|
||||
/* We need a valid context.*/ \
|
||||
bAssertstr(BlackMisc::IContext::isInitialised(), QString("You are trying to access a singleton without having initialized a context. The simplest correction is to add 'BlackMisc::CApplicationContext myApplicationContext;' at the very beginning of your application.")); \
|
||||
\
|
||||
/* Get the singleton object from the context, if there is one */ \
|
||||
void *object = BlackMisc::IContext::getInstance().singletonPointer(#className); \
|
||||
if (object == NULL) \
|
||||
{ \
|
||||
/* We have no allocated object yet, so do it now. */ \
|
||||
m_instance = new className; \
|
||||
BlackMisc::IContext::getInstance().setSingletonPointer(#className, m_instance); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Always use the c++ methods instead of casting the C way. */ \
|
||||
m_instance = reinterpret_cast<className*>(object); \
|
||||
} \
|
||||
} \
|
||||
return *m_instance; \
|
||||
m_instance = reinterpret_cast<className*>(BlackMisc::IContext::getInstance().singleton(#className)); \
|
||||
} \
|
||||
private:
|
||||
/* Put your class constructor directly after this makro and make sure it is private! */
|
||||
|
||||
|
||||
#define SINGLETON_CLASS_IMPLEMENTATION(className) className *className::m_instance = NULL;
|
||||
else \
|
||||
{ \
|
||||
/* We have no allocated object yet, so do it now. */ \
|
||||
m_instance = new className; \
|
||||
BlackMisc::IContext::getInstance().setSingleton(#className, m_instance); \
|
||||
} \
|
||||
} \
|
||||
return *m_instance; \
|
||||
} \
|
||||
private:
|
||||
/* Put your class constructor directly after this makro and make sure it is private! */
|
||||
|
||||
|
||||
#define SINGLETON_CLASS_IMPLEMENTATION(className) className *className::m_instance = NULL;
|
||||
|
||||
} // namespace BlackMisc
|
||||
|
||||
#endif CONTEXT_H
|
||||
#endif //BLACKMISC_CONTEXT_H
|
||||
|
||||
Reference in New Issue
Block a user