Database: sqlite default to appdata kworship.db
[kworship.git] / include / Factory.h
blob5d2fe8c7d04eb114610f30a88102d4d051bf8eb0
1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifndef _Factory_h_
21 #define _Factory_h_
23 /**
24 * @file Factory.h
25 * @brief A generic object factory.
26 * @author James Hogan <james@albanarts.com>
29 #include "functionInfo.h"
31 #include <QHash>
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>
37 class Factory
39 public:
42 * Constructors + destructor
45 /// Default constructor.
46 Factory()
47 : m_constructors()
51 /// Destructor.
52 ~Factory()
54 foreach (BaseConstructor* constructor, m_constructors)
56 delete constructor;
61 * Type registration
64 /** Add a type to the factory.
65 * @param T Type to add.
66 * @param key Identifier used to construct.
68 template <typename T>
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>();
75 return true;
77 return false;
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())
89 delete *it;
90 m_constructors.erase(it);
91 return true;
93 return false;
97 * Construction
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);
126 else
128 return 0;
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);
158 else
160 return 0;
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();
183 private:
186 * Types
189 /// Base constructor class.
190 class BaseConstructor
192 public:
193 BaseConstructor()
194 : m_singleton(0)
197 virtual ~BaseConstructor()
199 delete m_singleton;
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);
210 return m_singleton;
212 /// Delete singleton if it exists.
213 void deleteSingleton()
215 delete m_singleton;
216 m_singleton = 0;
219 private:
220 // No copy construction
221 BaseConstructor(const BaseConstructor&);
223 BASE* m_singleton;
226 /** Type specific generic constructor.
227 * @param TYPE Type to construct.
229 template <typename TYPE>
230 class Constructor : public BaseConstructor
232 public:
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;
244 * Variables
247 /// Constructors by key.
248 ConstructorHash m_constructors;
251 #endif // _Factory_h_