Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core7/src/libraries/util/Singleton.h @ 10400

Last change on this file since 10400 was 10398, checked in by landauf, 10 years ago

improved output

  • Property svn:eol-style set to native
File size: 6.2 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @defgroup SingletonScope Singletons and Scope
31    @ingroup Util
32*/
33
34/**
35    @file
36    @ingroup SingletonScope
37    @brief Definition of the Singleton template that is used as base class for classes that allow only one instance.
38
39    @anchor SingletonExample
40
41    Classes that inherit from orxonox::Singleton follow the singleton pattern and thus
42    allow only one instance of the class to exist. This istance is stored in a static
43    variable called @c singletonPtr_s. orxonox::Singleton will access this variable, but
44    it must be implemented in the deriving class.
45
46    Example:
47    @code
48    class TestSingleton : public Singleton<TestSingleton>   // inherit from Singleton, pass the own class as template argument
49    {
50        friend class Singleton<TestSingleton>;              // friend declaration so Singleton can access singletonPtr_s
51
52        public:
53            TestSingleton();                                // public constructor because we may want to manage this singleton
54                                                            //     with an orxonox::ScopedSingletonManager (see below)
55            virtual ~TestSingleton();                       // public destructor
56
57            void testFunction();                            // put your functions here
58
59        private:
60            int testValue_;                                 // put your variables here
61
62            static TestSingleton* singletonPtr_s;           // static singleton instance pointer, used by the Singleton template
63    };
64    @endcode
65
66    And don't forget to initialize the static singleton pointer in the source (*.cc) %file:
67    @code
68    TestSingleton* TestSingleton::singletonPtr_s = NULL;
69    @endcode
70
71    Usually a singleton gets created automatically when it is first used, but it will never
72    be destroyed (unless the singleton explicitly deletes itself). To allow controlled
73    construction and destruction, the singleton can be put within a virtual scope. This is
74    done by registering the singleton class with orxonox::ScopedSingletonManager. To
75    do so, the ManageScopedSingleton() macro has to be called:
76
77    @code
78    ManageScopedSingleton(TestSingleton, ScopeID::Graphics, false); // muste be called in a source (*.cc) file
79    @endcode
80
81    @b Important: If you call ManageScopedSingleton(), you don't have to initialize singletonPtr_s anymore,
82    because that's already done by the macro.
83
84    Now the singleton TestSingleton gets automatically created if the scope Graphics becomes
85    active and also gets destroyed if the scope is deactivated.
86
87    Note that not all singletons must register with a scope, but it's recommended.
88
89    If a class inherits from orxonox::Singleton, it also inherits its functions. The most important
90    function is orxonox::Singleton::getInstance() which returns a reference to the only instance
91    of the singleton.
92
93    Example:
94    @code
95    TestSingleton::TestSingleton()                          // implement the constructor
96    {
97        this->testValue_ = 15;
98    }
99
100    void TestSingleton::testFunction()                      // implement testFunction
101    {
102        orxout() << "My value is " << this->testValue_ << endl;
103    }
104
105    TestSingleton::getInstance().testFunction();            // prints "My value is 15"
106    @endcode
107*/
108
109#ifndef __Util_Singleton_H__
110#define __Util_Singleton_H__
111
112#include "UtilPrereqs.h"
113
114#include <cstring>
115#include <typeinfo>
116
117#include "OrxAssert.h"
118
119namespace orxonox
120{
121    /**
122    @brief
123        Base for singleton classes.
124
125        Usage:
126        Inherit publicly from Singleton<MyClass> and provide access to MyClass::singletonPtr_s.
127        This can easily be done with a friend declaration.
128
129        See @ref SingletonExample "this example" for an exemplary implementation.
130    */
131    template <class T>
132    class Singleton
133    {
134    public:
135        //! Returns a reference to the singleton instance
136        static T& getInstance()
137        {
138            OrxVerify(T::singletonPtr_s != NULL, "T=" << typeid(T).name());
139            return *T::singletonPtr_s;
140        }
141
142        //! Tells whether the singleton has been created
143        static bool exists()
144        {
145            return (T::singletonPtr_s != NULL);
146        }
147
148        //! Update method called by ClassSingletonManager (if used)
149        void preUpdateSingleton(const Clock& time) { static_cast<T*>(T::singletonPtr_s)->preUpdate(time); }
150        //! Empty update method for the static polymorphism
151        void preUpdate(const Clock& time) { }
152        //! Update method called by ClassSingletonManager (if used)
153        void postUpdateSingleton(const Clock& time) { static_cast<T*>(T::singletonPtr_s)->postUpdate(time); }
154        //! Empty update method for the static polymorphism
155        void postUpdate(const Clock& time) { }
156
157    protected:
158        //! Constructor sets the singleton instance pointer
159        Singleton()
160        {
161            OrxVerify(T::singletonPtr_s == NULL, "T=" << typeid(T).name());
162            T::singletonPtr_s = static_cast<T*>(this);
163        }
164
165        //! Destructor resets the singleton instance pointer
166        virtual ~Singleton()
167        {
168            OrxVerify(T::singletonPtr_s != NULL, "T=" << typeid(T).name());
169            T::singletonPtr_s = NULL;
170        }
171
172    private:
173        Singleton(const Singleton& rhs); //!< Don't use (undefined)
174    };
175}
176
177#endif /* __Util_Singleton_H__ */
Note: See TracBrowser for help on using the repository browser.