Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/util/Singleton.h @ 8614

Last change on this file since 8614 was 7904, checked in by landauf, 14 years ago

2x virtual because it may be required in some cases (Singleton & LANDiscoverable) and 2x for consistency

  • Property svn:eol-style set to native
File size: 6.1 KB
RevLine 
[3364]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
[7401]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        COUT(0) << "My value is " << this->testValue_ << std::endl;
103    }
104
105    TestSingleton::getInstance().testFunction();            // prints "My value is 15"
106    @endcode
107*/
108
[3364]109#ifndef __Util_Singleton_H__
110#define __Util_Singleton_H__
111
112#include "UtilPrereqs.h"
[7163]113
[3367]114#include <cassert>
[7163]115#include <cstring>
[3364]116
117namespace orxonox
118{
119    /**
120    @brief
121        Base for singleton classes.
122
123        Usage:
[7401]124        Inherit publicly from Singleton<MyClass> and provide access to MyClass::singletonPtr_s.
[3366]125        This can easily be done with a friend declaration.
[7401]126
127        See @ref SingletonExample "this example" for an exemplary implementation.
[3364]128    */
129    template <class T>
130    class Singleton
131    {
132    public:
133        //! Returns a reference to the singleton instance
[6751]134        static T& getInstance()
[3364]135        {
[6536]136            assert(T::singletonPtr_s != NULL);
[3366]137            return *T::singletonPtr_s;
[3364]138        }
139
[6536]140        //! Tells whether the singleton has been created
[6751]141        static bool exists()
[6536]142        {
143            return (T::singletonPtr_s != NULL);
144        }
145
[5929]146        //! Update method called by ClassSingletonManager (if used)
[6751]147        void preUpdateSingleton(const Clock& time) { static_cast<T*>(T::singletonPtr_s)->preUpdate(time); }
[5929]148        //! Empty update method for the static polymorphism
[6751]149        void preUpdate(const Clock& time) { }
[6417]150        //! Update method called by ClassSingletonManager (if used)
[6751]151        void postUpdateSingleton(const Clock& time) { static_cast<T*>(T::singletonPtr_s)->postUpdate(time); }
[6417]152        //! Empty update method for the static polymorphism
[6751]153        void postUpdate(const Clock& time) { }
[5929]154
[3364]155    protected:
[3366]156        //! Constructor sets the singleton instance pointer
[3364]157        Singleton()
158        {
[6536]159            assert(T::singletonPtr_s == NULL);
[3366]160            T::singletonPtr_s = static_cast<T*>(this);
[3364]161        }
[3366]162
[7401]163        //! Destructor resets the singleton instance pointer
[7904]164        virtual ~Singleton()
[3364]165        {
[6536]166            assert(T::singletonPtr_s != NULL);
167            T::singletonPtr_s = NULL;
[3364]168        }
169
170    private:
171        Singleton(const Singleton& rhs); //!< Don't use (undefined)
172    };
173}
174
175#endif /* __Util_Singleton_H__ */
Note: See TracBrowser for help on using the repository browser.