Skip to main content
History: -Singleton
View published page
Source of version: 9
(current)
{INCLUDE(page="ogrelex ext tpl")/} --- __Singleton__ - A class of which only one instance can exist at a given time. This instance can be accessed from anywhere in the program without passing a reference to it around. A useful design pattern, but apply with care. {maketoc} !!A general approach !!!Forum Answer Taken from here [http://www.ogre3d.org/phpBB2/viewtopic.php?t=7320|here]: __Mdobele:__Singleton Classes rock. Simply think of it as a way of ensuring that the class you are calling is created only once. That means it can be called from anywhere ( by including header of course ) and you know that your calling the 1 static instance and not creating another instance. I use them mostly for my main application and then for every single "manager" class that I use. Here is an example of a Menu manager {CODE(wrap="1", colors="c++")}// Class Declaration class MenuManager { public : // Constructor MenuManager(); // Destructor ~MenuManager(); // SingleTon Instance // Singleton Instance of our Menu manager static MenuManager &Instance(); // Create Main Menu void CreateMainMenu(); private: InheritedBase *m_BaseMenu; MainMenu * m_MainMenu; };{CODE}And the .cpp {CODE(wrap="1", colors="c++")}//SingleTon Instance MenuManager &MenuManager::Instance() { static MenuManager instance; return instance; } // Create MainMenu void MenuManager::CreateMainMenu() { m_MainMenu = new MainMenu(); m_MainMenu->CreateMainMenu(); }{CODE} So in any other file i simply include {CODE(wrap="1", colors="c++")}#include MenuManager.h{CODE} and I gain acess to it Knowing that its the one and only and not another instance. {CODE(wrap="1", colors="c++")}MenuManager::Instance().CreateMainMenu();{CODE} Hope that clears it up a bit. __bal__: ''IIRC, singletons are a design pattern (a way of creating classes that fits in most projects). There are a lot of different implementations but the point is always the same: having ONLY ONE instance of a class. '' !!Ogre's approach !!!Description Ogre's implementation differs in a couple of points from the approach described above. * Ogre::Singleton is a template, meaning you must instantiate it with the type, that you want to have as a Singleton. This allows us to handle all Singletons with the same code, which makes the code a bit more maintainable. * Ogre::Singleton must be constructed explicitly. You must call the constructor of your Singleton class, before you can obtain a reference to the instance. The implementation described above creates the singleton on the fly when the instance is obtained for the first time. The advantage of Ogre's implementation is that you can instantiate it with arbitrary parameters. The Source can be found [http://ogre.svn.sourceforge.net/viewvc/ogre/branches/v1-6/OgreMain/include/OgreSingleton.h?view=markup|here]. !!!How to use it NOTE: In Ogre 1.7, the static member ''msSingleton'' we are referring to below will actually be called ''ms_Singleton''. The code below assumes you use Ogre 1.8 or later. !!!!Making a class a singleton Pretend we want to convert the class MyManager to a Singleton. {CODE(wrap="1", colors="c++")}class MyManager { public: MyManager(); void doSomething(); };{CODE} So we need to extend and instantiate the Ogre::Singleton template and override the singleton access methods. Our header file will look like this: {CODE(wrap="1", colors="c++")}#include <OgreSingleton.h> class MyManager : public Ogre::Singleton<MyManager> { public: MyManager(); void doSomething(); static MyManager& getSingleton(void); static MyManager* getSingletonPtr(void); };{CODE} You don't have to override -+getSingleton()+- and -+getSingletonPtr()+- if your Singleton is not used outside of your EXE/DLL, but else you have to. The source file would now look like this: {CODE(wrap="1", colors="c++")}#include "MyManager.h" template<> MyManager* Ogre::Singleton<MyManager>::msSingleton = 0; MyManager* MyManager::getSingletonPtr(void) { return msSingleton; } MyManager& MyManager::getSingleton(void) { assert( msSingleton ); return ( *msSingleton ); } // The rest of your implementation is following. ...{CODE} !!!!Making a class (in another namespace) a singleton If you want to make a class from a specific namespace a singleton, you cannot use the previous method. Due to C++ specification (C++ Standard 14.7.3/2) you cannot specialize a template (like Ogre::Singleton<T>) in other namespace than its declaration's one. Here is a complement to the previous technique. There is two case where you need another namespace : # Your class is a part of an application directly using Ogre3D # Your class is a part of a library (DLL) directly using Ogre3D but, like all DLLs, attends to be used by another program. The two cases are pretty close. The fellowing code is needed only for the case 2. A good practice when developping a DLL is to define a macro for export/import depending on the building situation (building the lib itself => export ; build an app with the lib => import). {CODE(wrap="1", colors="c++")} // File MyLibPrereq.h # if defined(MYLIB_NONCLIENT_BUILD) // Export definition # define _MYLIBExport __declspec( dllexport ) # else // Import definition # define _MYLIBExport __declspec( dllimport ) # endif {CODE} The header file for MyManager in case 1 : {CODE(wrap="1", colors="c++")} #include "MyLibPrereq.h" #include <OgreSingleton.h> namespace MyLib { class MyManager; } template class _OgreExport Ogre::Singleton<MyLib::MyManager>; // export of explicit instantiation namespace MyLib { class MyManager : public Ogre::Singleton<MyManager> { public: MyManager(); void doSomething(); static MyManager& getSingleton(void); static MyManager* getSingletonPtr(void); }; }{CODE} Now the header for MyManager in case 2. The difference reside in the export directive, here we use our own directive : {CODE(wrap="1", colors="c++")} #include "MyLibPrereq.h" #include <OgreSingleton.h> namespace MyLib { class MyManager; } template class _MYLIBExport Ogre::Singleton<MyLib::MyManager>; // export of explicit instantiation namespace MyLib { class MyManager : public Ogre::Singleton<MyManager> { public: MyManager(); void doSomething(); static MyManager& getSingleton(void); static MyManager* getSingletonPtr(void); }; }{CODE} Then the source for __case 2__: {CODE(wrap="1", colors="c++")}#include "MyManager.h" // Template specialization template<> _MYLIBExport MyLib::MyManager* Ogre::Singleton<MyLib::MyManager>::msSingleton = 0; namespace MyLib { MyManager* MyManager::getSingletonPtr(void) { return msSingleton; } MyManager& MyManager::getSingleton(void) { assert( msSingleton ); return ( *msSingleton ); } // The rest of your implementation is following. ... } {CODE} For __case 1__ just remove -+_MYLIBExport+- in the template specialization. !!!!Using a singleton {CODE(wrap="1", colors="c++")}// Creating the manager. This may only be called once! new MyManager(); // Obtaining a reference to the manager instance MyManager& mgr = MyManager::getSingleton(); // Obtaining a pointer to the manager instance MyManager* pMgr = MyManager::getSingletonPtr();{CODE} __Note:__ You may call the Singleton constructor only once. Calling it more often will result in a runtime exception. There is another semantical difference between -+getSingleton()+- and -+getSingletonPtr()+-: If the constructor is not called beforehand -+getSingletonPtr()+- will return a NULL-Pointer and -+getSingleton()+- will throw a runtime exception. So it is probably better to use -+getSingleton()+- most of the time, even though it is slightly slower. But you get a clearer response when you set something up wrongly. !!Some Links: [http://www.drizzle.com/~scottb/publish/gpgems1_singleton.htm|Ogre's Singleton Method from 'Game Programming Gems' by Scott Bilas] [http://home.earthlink.net/~huston2/dp/singleton.html|Huston Design Patterns] [http://www.gamedev.net/reference/articles/article1825.asp|Gamedev.net] [http://www.codeproject.com/gen/design/singleton.asp|CodeProject.com] --- {INCLUDE(page="ogrelex ext tpl")/} --- Alias: (alias(Singleton))
Search by Tags
Search Wiki by Freetags
Latest Changes
Projects using OGRE
Building Your Projects With CMake
Compiled API Reference
Overlay Editor
Introduction - JaJDoo Shader Guide - Basics
RT Shader System
RapidXML Dotscene Loader
One Function Ogre
One Function Ogre
...more
Search
Find
Online Users
134 online users
OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username
Password
CapsLock is on.
Remember me (for 1 year)
Log in