Salome HOME
Revert "Synchronize adm files"
[modules/kernel.git] / src / Utils / Utils_SINGLETON.hxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME Utils : general SALOME's definitions and tools
24 //  File   : Utils_SINGLETON.hxx
25 //  Author : Antoine YESSAYAN, EDF
26 //  Module : SALOME
27 //  $Header$
28 //
29 # if !defined( __SINGLETON__H__ )
30 # define __SINGLETON__H__
31
32 #include "SALOME_Utils.hxx"
33
34 # include "Utils_DESTRUCTEUR_GENERIQUE.hxx"
35 # include <list>
36
37 /*!\class SINGLETON_
38  *
39  * <B>Definition</B>
40  * 
41  * A singleton is a data which is created and deleted only once in the application.
42  * The C++ compiler allow the user to create static data before the first executable statement.
43  * They are deleted after the last statement.statement.
44  *
45  * The SINGLETON_ template class deals with dynamic singleton. It is useful for functor objects.
46  * For example, an object which, when created, connects the application to a system and
47  * disconnects the application at deletion.
48  *
49  *
50  * <B>Usage</B>
51  * 
52  * To create a single instance a POINT_ object :
53  * 
54  * # include "Utils_SINGLETON.hxx"
55  *      ...
56  *      ptrPoint = SINGLETON_<POINT_>::Instance() ;
57  * 
58  * 
59  * <B>Design description</B>
60  *
61  *      -# the user creates an object of class TYPE By using a class method : SINGLETON_<TYPE>::Instance() which
62  *         returns a pointer to the single object ;
63  *      -# this class method uses the default constructor to create an object ;
64  *      -# at the same time, this class method reate a destructor object which is added to the generic list
65  *         of destructors objects to be executed at the end of the application (atexit) ;
66  *      -# at the end of the application process all the deletions are performed by the Nettoyage() C function
67  *         which execute the destructions objects then deletes the destructions objects themselves ;
68  *      -# the Nettoyage() C function is recorded using atexit() C function through the creation of a static
69  *         single object ATEXIT_().
70  */
71
72
73 template <class TYPE> class SINGLETON_
74 {
75
76 public :
77
78         static TYPE *Instance( void );          //!< Singleton dynamic creation using the default builder
79         static bool IsAlreadyExisting( void );  //!< returns True if the singleton is already existing
80         static int Destruction( void );         //!< destroys the Singleton before the end of the application process
81
82 private :
83
84         TYPE _Instance ;
85         static SINGLETON_ *PtrSingleton ;
86
87         SINGLETON_( void );
88         ~SINGLETON_();
89
90 } ;     /* class SINGLETON_<TYPE> */
91
92
93
94
95 template <class TYPE> SINGLETON_<TYPE> *SINGLETON_<TYPE>::PtrSingleton=NULL ;
96
97
98
99 /*!
100  * The class method Instance :
101  *  -# creates an object of class TYPE ;
102  *  -# creates a destruction object DESTRUCTEUR_DE_<TYPE> which is appended to the list of destruction objects to be
103  *     executed ;
104  *  -# returns a pointer to the created object.
105  *
106  *  Note that the two created objects are deleted at the end of the process in the function Nettoyage().
107  */
108 template <class TYPE> TYPE *SINGLETON_<TYPE>::Instance( void )
109 {
110         if ( ! PtrSingleton )
111         {
112                 //MESSAGE("SINGLETON_<TYPE>::Instance( void )") ;
113                 PtrSingleton = new SINGLETON_<TYPE> ;
114                 new DESTRUCTEUR_DE_<TYPE>( PtrSingleton->_Instance ) ;
115         }
116         return &PtrSingleton->_Instance ;
117 }
118
119
120 template <class TYPE> bool SINGLETON_<TYPE>::IsAlreadyExisting( void )
121 {
122         return PtrSingleton ? true : false ;
123 }
124
125
126
127
128 template <class TYPE> SINGLETON_<TYPE>::SINGLETON_( void )
129 {
130         //MESSAGE("CREATION d'un SINGLETON_") ;
131 }
132
133
134
135
136 /*!
137         The method SINGLETON_<TYPE>::Destruction can be called by the user. If it is not
138         the function nettoyage() calls it atexit.
139
140         N.B. : the singleton objects are destroyed in the reverse order of there creation.
141 */
142 template <class TYPE> int SINGLETON_<TYPE>::Destruction( void )
143 {
144         int k = - 1 ;
145         //BEGIN_OF("SINGLETON_<TYPE>::Destruction( void )") ;
146         if ( PtrSingleton )
147         {
148           //MESSAGE("Destruction du SINGLETON_") ;
149
150
151                 std::list<DESTRUCTEUR_GENERIQUE_ *>::iterator k ;
152                 for( k=DESTRUCTEUR_GENERIQUE_::Destructeurs->begin() ; k!=DESTRUCTEUR_GENERIQUE_::Destructeurs->end();k++)
153                 {
154                         if ( *k == PtrSingleton->_Instance )
155                         {
156                                 DESTRUCTEUR_GENERIQUE_::Destructeurs->erase( k ) ;
157                                 break ;
158                         }
159                 }
160                 delete PtrSingleton ;
161                 PtrSingleton = NULL ;
162         }
163         //END_OF("SINGLETON_<TYPE>::Destruction( void )") ;
164         return k ;
165 }
166
167
168 template <class TYPE> SINGLETON_<TYPE>::~SINGLETON_()
169 {
170   //MESSAGE("passage dans SINGLETON_<TYPE>::~SINGLETON_( void )") ;
171 }
172
173 # endif         /* # if !defined( __SINGLETON__H__ ) */