1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * KWorship is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * KWorship is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with KWorship. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
25 * @brief A generic object factory.
26 * @author James Hogan <james@albanarts.com>
29 #include "functionInfo.h"
33 /** A generic object factory.
34 * Types can be registered to this class and then constructed using a key.
36 template <typename KEY
, typename BASE
, typename TUPLE
>
42 * Constructors + destructor
45 /// Default constructor.
54 foreach (BaseConstructor
* constructor
, m_constructors
)
64 /** Add a type to the factory.
65 * @param T Type to add.
66 * @param key Identifier used to construct.
69 bool addType(const KEY
& key
)
71 typename
ConstructorHash::const_iterator it
= m_constructors
.constFind(key
);
72 if (it
== m_constructors
.constEnd())
74 m_constructors
[key
] = new Constructor
<T
>();
80 /** Remove a type from the factory.
81 * @param key Identifier used to construct.
83 bool removeType(const KEY
& key
)
86 typename
ConstructorHash::iterator it
= m_constructors
.find(key
);
87 if (it
!= m_constructors
.end())
90 m_constructors
.erase(it
);
100 BASE
* construct(const KEY
& key
)
102 return constructFromPack(key
, TUPLE::pack());
104 template <typename Param1
>
105 BASE
* construct(const KEY
& key
, const Param1
& param1
)
107 return constructFromPack(key
, TUPLE::pack(param1
));
109 template <typename Param1
, typename Param2
>
110 BASE
* construct(const KEY
& key
, const Param1
& param1
, const Param2
& param2
)
112 return constructFromPack(key
, TUPLE::pack(param1
, param2
));
115 /** Construct a type using a pack of arguments.
116 * @param key identifier of type to construct.
117 * @param pack pack of arguments.
119 BASE
* constructFromPack(const KEY
& key
, const typename
TUPLE::Pack
& pack
)
121 typename
ConstructorHash::const_iterator it
= m_constructors
.constFind(key
);
122 if (it
!= m_constructors
.constEnd())
124 return (*it
)->construct(pack
);
132 BASE
* singleton(const KEY
& key
)
134 return singletonFromPack(key
, TUPLE::pack());
136 template <typename Param1
>
137 BASE
* singleton(const KEY
& key
, const Param1
& param1
)
139 return singletonFromPack(key
, TUPLE::pack(param1
));
141 template <typename Param1
, typename Param2
>
142 BASE
* singleton(const KEY
& key
, const Param1
& param1
, const Param2
& param2
)
144 return singletonFromPack(key
, TUPLE::pack(param1
, param2
));
147 /** Get a singleton of a type using a pack of arguments.
148 * @param key identifier of type to construct.
149 * @param pack pack of arguments.
151 BASE
* singletonFromPack(const KEY
& key
, const typename
TUPLE::Pack
& pack
)
153 typename
ConstructorHash::const_iterator it
= m_constructors
.constFind(key
);
154 if (it
!= m_constructors
.constEnd())
156 return (*it
)->singleton(pack
);
164 /// Delete any existing singleton of a type.
165 void deleteSingleton(const KEY
& key
)
167 typename
ConstructorHash::const_iterator it
= m_constructors
.constFind(key
);
168 if (it
!= m_constructors
.constEnd())
170 (*it
)->deleteSingleton();
174 /// Delete all singletons.
175 void deleteAllSingletons()
177 foreach (BaseConstructor
* constructor
, m_constructors
)
179 constructor
->deleteSingleton();
189 /// Base constructor class.
190 class BaseConstructor
197 virtual ~BaseConstructor()
201 /// Construct an instance of a dervied type.
202 virtual BASE
* construct(const typename
TUPLE::Pack
& pack
) const = 0;
203 /// Get a singleton object, constructing if necessary.
204 BASE
* singleton(const typename
TUPLE::Pack
& pack
)
206 if (0 == m_singleton
)
208 m_singleton
= construct(pack
);
212 /// Delete singleton if it exists.
213 void deleteSingleton()
220 // No copy construction
221 BaseConstructor(const BaseConstructor
&);
226 /** Type specific generic constructor.
227 * @param TYPE Type to construct.
229 template <typename TYPE
>
230 class Constructor
: public BaseConstructor
233 virtual ~Constructor() {}
234 virtual BASE
* construct(const typename
TUPLE::Pack
& pack
) const
236 return pack
.template construct
<TYPE
>();
240 /// Hash of keys to constructors.
241 typedef QHash
<KEY
, BaseConstructor
*> ConstructorHash
;
247 /// Constructors by key.
248 ConstructorHash m_constructors
;
251 #endif // _Factory_h_