ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-2.0/src/utils/GenericFactory.hpp
Revision: 1829
Committed: Thu Dec 2 05:14:58 2004 UTC (19 years, 7 months ago) by tim
File size: 7601 byte(s)
Log Message:
minor fix

File Contents

# Content
1 /*
2 * Copyright (C) 2000-2004 Object Oriented Parallel Simulation Engine (OOPSE) project
3 *
4 * Contact: oopse@oopse.org
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 * All we ask is that proper credit is given for our work, which includes
11 * - but is not limited to - adding the above copyright notice to the beginning
12 * of your source code files, and to any copyright notice that you may distribute
13 * with programs based on this work.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 */
25
26 /**
27 * @file GenericFactory.hpp
28 * @author Teng Lin
29 * @date 10/24/2004
30 * @version 1.0
31 */
32 #ifndef UTIL_GENERICFACTORY_HPP
33 #define UTIL_GENERICFACTORY_HPP
34 #include <cassert>
35 #include <map>
36 #include <string>
37 #include <vector>
38
39 namespace oopse {
40
41 /**
42 * @class GenericFactory GenericFactory.hpp "utils/GenericFactory.hpp"
43 * @brief GenericFactory is a template based Object Factory
44 * Factory pattern is used to define an interface for creating an object.
45 *
46 * @param Object the base class of the hierarchy for which you provide the object factory.
47 * @param IdentType the object that identifies the type of the concrete object. Default type is std::string * @param Creator the callable entity that creates objects. This type must support operator(),
48 * taking no parameters and returning a pointer to Object. Default type is function pointer.
49 *
50 * Usage:
51 * @code
52 * //Shape class
53 * class Shape {
54 * ...
55 * };
56 *
57 * //instantiating a new object factory
58 * typedef GenericFactory<Shape> ShapeFactory;
59 *
60 * //Line class
61 * class Line : public Shape{
62 * ...
63 * };
64 *
65 * //declare function to create Line
66 * Shape* createLine() {
67 * return new Line;
68 * }
69 *
70 * //register createLine
71 * //note: must put ShapeFactory::getInstance()->registerCreator("Line", createLine) on the right
72 * //hand side, otherwise the compiler will consider it as a function declaration
73 * const bool registeredLine = ShapeFactory::getInstance()->registerCreator("Line", createLine);
74 *
75 * //Circle class
76 * class Circle : public Shape{
77 * ...
78 * };
79 *
80 * //declare function to create Circle
81 * Shape* createCircle() {
82 * return new Circle;
83 * }
84 *
85 * //register createCircle
86 * const bool registeredCircle = ShapeFactory::getInstance()->registerCreator("Circle", createCircle);
87 *
88 * //create object by ident
89 * Line* line = ShapeFactory::getInstance()->createObject("Line");
90 * Circle* circle = ShapeFactory::getInstance()->createObject("Circle");
91 * @endcode
92 *
93 * Or the user can use predefined macro DECLARE_CREATOR and REGISTER_CREATOR
94 * @code
95 * //Shape class
96 * class Shape {
97 * ...
98 * };
99 *
100 * //instantiating a new object factory
101 * typedef GenericFactory<Shape> ShapeFactory;
102 *
103 * //Line class
104 * class Line : public Shape{
105 * ...
106 * };
107 *
108 * //declare function using macro
109 * DECLARE_CREATOR(Shape, Line)
110 *
111 * //register using macro
112 * REGISTER_CREATOR(ShapeFactory, "Line", Line);
113
114 * //Circle class
115 * class Circle : public Shape{
116 * ...
117 * };
118 *
119 * //declare function using macro
120 * DECLARE_CREATOR(Shape, Circle)
121 *
122 * //register using macro
123 * REGISTER_CREATOR(ShapeFactory, "Circle", Circle);
124 * @endcode
125 */
126 template<class Object, typename IdentType = std::string, typename Creator = Object* (*)()>
127 class GenericFactory {
128 public:
129 typedef GenericFactory<Object, IdentType, Creator> FactoryType;
130 typedef std::map<IdentType, Creator> CreatorMapType;
131
132 /**
133 * Returns an instance of object factory
134 * @return an instance of object factory
135 */
136 static FactoryType* getInstance(){
137 if (instance_ == NULL)
138 instance_ = new FactoryType;
139 return instance_;
140 }
141
142 /**
143 * Registers a creator with a type identifier
144 * @return true if registration is succeed, otherwise return false
145 * @id the identification of the concrete object
146 * @creator the object responsible to create the concrete object
147 */
148 bool registerCreator(const IdentType& id, Creator creator) {
149 return creatorMap_.insert(
150 CreatorMapType::value_type(id, creator)).second;
151 }
152
153 /**
154 * Unregisters the creator for the given type identifier. If the type identifier
155 * was previously registered, the function returns true.
156 * @return truethe type identifier was previously registered and the creator is removed,
157 * otherwise return false
158 * @id the identification of the concrete object
159 */
160 bool unregisterCreator(const IdentType& id) {
161 return creatorMap_.erase(id) == 1;
162 }
163
164 /**
165 * Looks up the type identifier in the internal map. If it is found, it invokes the
166 * corresponding creator for the type identifier and returns its result.
167 * @return a pointer of the concrete object, return NULL if no creator is registed for
168 * creating this concrete object
169 * @param id the identification of the concrete object
170 */
171 Object* createObject(const IdentType& id) {
172 typename CreatorMapType::iterator i = creatorMap_.find(id);
173 if (i != creatorMap_.end()) {
174 //invoke functor to create object
175 return (i->second)();
176 } else {
177 return NULL;
178 }
179 }
180
181 /**
182 * Returns all of the registed type identifiers
183 * @return all of the registed type identifiers
184 */
185 std::vector<IdentType> getIdents() {
186 std::vector<IdentType> idents;
187 typename CreatorMapType::iterator i;
188
189 for (i = creatorMap_.begin(); i != creatorMap_.end(); ++i) {
190 idents.push_back(i->first);
191 }
192
193 return idents;
194 }
195
196 public:
197 static FactoryType* instance_;
198 CreatorMapType creatorMap_;
199 };
200
201 /** write out all of the type identifiers to an output stream */
202 template<typename O, typename I, typename C>
203 std::ostream& operator <<(std::ostream& o, GenericFactory<O, I, C>& factory) {
204 std::vector<I> idents;
205 std::vector<I>::iterator i;
206
207 idents = factory.getIdents();
208
209 o << "Avaliable type identifiers in this factory: " << std::endl;
210 for (i = idents.begin(); i != idents.end(); ++i) {
211 o << *i << std::endl;
212 }
213
214 return o;
215 }
216
217 //static template class member
218 template<class Object, typename IdentType,typename Creator>
219 GenericFactory<Object,IdentType,Creator>* GenericFactory<Object,IdentType,Creator>::instance_ ;
220
221
222 #define DECLARE_CREATOR(abstractObject, concreteObject) \
223 inline abstractObject* create##concreteObject(){\
224 return new concreteObject;\
225 }
226
227 #define REGISTER_CREATOR(factory, ident, concreteObject) \
228 const bool registered##concreteObject = factory::getInstance()->registerCreator(ident, create##concreteObject);
229
230
231 }//namespace oopse
232 #endif //UTIL_GENERICFACTORY_HPP
233