MyGUI_Singleton.h
Go to the documentation of this file.
/*
* This source file is part of MyGUI. For the latest info, see http://mygui.info/
* Distributed under the MIT License
* (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
*/
#ifndef MYGUI_SINGLETON_H_
#define MYGUI_SINGLETON_H_
#include "MyGUI_Diagnostic.h"
namespace MyGUI
{
#ifndef MYGUI_DONT_USE_OBSOLETE
template<class T>
class MYGUI_OBSOLETE("Singleton class is deprecated. Do not use singletons.") Singleton
{
public:
#if defined(__clang__)
// This constructor is called before the `T` object is fully constructed, and
// pointers are not dereferenced anyway, so UBSan shouldn't check vptrs.
__attribute__((no_sanitize("vptr")))
#endif
Singleton()
{
MYGUI_ASSERT(nullptr == msInstance, "Singleton instance " << getClassTypeName() << " already exsist");
msInstance = static_cast<T*>(this);
}
virtual ~Singleton()
{
if (nullptr == msInstance)
MYGUI_LOG(
Critical,
"Destroying Singleton instance " << getClassTypeName() << " before constructing it.");
msInstance = nullptr;
}
static T& getInstance()
{
MYGUI_ASSERT(
nullptr != getInstancePtr(),
"Singleton instance " << getClassTypeName() << " was not created");
return (*getInstancePtr());
}
static T* getInstancePtr()
{
return msInstance;
}
static std::string_view getClassTypeName()
{
return mClassTypeName;
}
private:
static T* msInstance;
static std::string_view mClassTypeName;
};
#endif
/*
// Template Singleton class was replaces with a set of macroses, because there were too many issues with it,
// all appearing in different compilers:
// - incorrect exporting template class;
// - static variables in headers issues;
// - explicit specialization/implicit instantiation issues;
// - many other related compile errors.
// It is possible to move all template definitions into cpp code, but result looked even worse.
// Usage:
// in header
class MyClass
{
MYGUI_SINGLETON_DECLARATION(MyClass);
MyClass()
// ...
};
// in cpp
MYGUI_SINGLETON_DEFINITION(MyClass);
MyClass() : mSingletonHolder(this)
{
// ...
}
*/
// proxy class to avoid calling initialiseSingleton/shutdownSingleton in constructor/destructor
template<class T>
class SingletonHolder
{
public:
SingletonHolder(T* instance) :
mInstance(instance)
{
mInstance->initialiseSingleton();
}
~SingletonHolder()
{
mInstance->shutdownSingleton();
}
private:
T* mInstance;
};
#define MYGUI_SINGLETON_DECLARATION(ClassName) \
private: \
friend MyGUI::SingletonHolder<ClassName>; \
MyGUI::SingletonHolder<ClassName> mSingletonHolder; \
void initialiseSingleton(); \
void shutdownSingleton(); \
\
public: \
static ClassName& getInstance(); \
static ClassName* getInstancePtr(); \
static std::string_view getClassTypeName(); \
ClassName(const ClassName&) = delete; \
ClassName& operator=(const ClassName&) = delete
#define MYGUI_SINGLETON_DEFINITION(ClassName) \
static ClassName* ClassName##Instance = nullptr; \
static std::string_view ClassName##ClassTypeName = #ClassName; \
\
void ClassName::initialiseSingleton() \
{ \
MYGUI_ASSERT( \
nullptr == ClassName##Instance, \
"Singleton instance " << getClassTypeName() << " already exsist"); \
ClassName##Instance = this; \
} \
\
void ClassName::shutdownSingleton() \
{ \
if (nullptr == ClassName##Instance) \
MYGUI_LOG(Critical, "Destroying Singleton instance " << getClassTypeName() << " before constructing it."); \
ClassName##Instance = nullptr; \
} \
\
ClassName& ClassName::getInstance() \
{ \
MYGUI_ASSERT(nullptr != getInstancePtr(), "Singleton instance " << getClassTypeName() << " was not created"); \
return (*getInstancePtr()); \
} \
\
ClassName* ClassName::getInstancePtr() \
{ \
return ClassName##Instance; \
} \
\
std::string_view ClassName::getClassTypeName() \
{ \
return ClassName##ClassTypeName; \
} \
static_assert(true, "require semicolon")
} // namespace MyGUI
#endif // MYGUI_SINGLETON_H_
MyGUI_Diagnostic.h
MYGUI_ASSERT
#define MYGUI_ASSERT(exp, dest)
Definition MyGUI_Diagnostic.h:31
MYGUI_OBSOLETE
#define MYGUI_OBSOLETE(text)
Definition MyGUI_Diagnostic.h:68
MYGUI_LOG
#define MYGUI_LOG(level, text)
Definition MyGUI_Diagnostic.h:17
MyGUI::SingletonHolder::SingletonHolder
SingletonHolder(T *instance)
Definition MyGUI_Singleton.h:98
MyGUI::SingletonHolder::~SingletonHolder
~SingletonHolder()
Definition MyGUI_Singleton.h:103
MyGUI::Singleton::Singleton
Singleton()
Definition MyGUI_Singleton.h:25
MyGUI::Singleton::getInstancePtr
static T * getInstancePtr()
Definition MyGUI_Singleton.h:48
MyGUI::Singleton::getClassTypeName
static std::string_view getClassTypeName()
Definition MyGUI_Singleton.h:53
MyGUI::Singleton::getInstance
static T & getInstance()
Definition MyGUI_Singleton.h:40
MyGUI::Singleton::~Singleton
virtual ~Singleton()
Definition MyGUI_Singleton.h:31
MyGUI
Definition MyGUI_ActionController.h:15