ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/utils/GenericFactory.hpp
(Generate patch)

Comparing trunk/OOPSE-4/src/utils/GenericFactory.hpp (file contents):
Revision 1587 by tim, Mon Oct 18 05:23:21 2004 UTC vs.
Revision 1681 by tim, Thu Oct 28 22:26:32 2004 UTC

# Line 24 | Line 24
24   */
25  
26   /**
27 < * @file Vector3.hpp
27 > * @file GenericFactory.hpp
28   * @author Teng Lin
29 < * @date 09/14/2004
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 < template<class Product, typename Creator, typename ProductIdentType = std::string>
40 < class GenericFactory{
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 string
48 > * @param Creator  the callable entity that creates objects. This type must support operator(),
49 > * taking no parameters and returning a pointer to Object. Default type is function pointer.
50 > *
51 > * Usage:
52 > * @code
53 > * //Shape class
54 > * class Shape {
55 > * ...
56 > * };
57 > *
58 > * //instantiating a new object factory
59 > * typedef GenericFactory<Shape> ShapeFactory;
60 > *
61 > * //Line class
62 > * class Line : public Shape{
63 > * ...
64 > * };
65 > *
66 > * //declare function to create Line
67 > * Shape* createLine() {
68 > *   return new Line;
69 > * }
70 > *
71 > * //register createLine
72 > * //note: must put ShapeFactory::getInstance()->registerCreator("Line", createLine) on the right
73 > * //hand side, otherwise the compiler will consider it as a function declaration
74 > * const bool registeredLine = ShapeFactory::getInstance()->registerCreator("Line", createLine);
75 > *
76 > * //Circle class
77 > * class Circle : public Shape{
78 > * ...
79 > * };
80 > *
81 > * //declare function to create Circle
82 > * Shape* createCircle() {
83 > *   return new Circle;
84 > * }
85 > *
86 > * //register createCircle
87 > * const bool registeredCircle = ShapeFactory::getInstance()->registerCreator("Circle", createCircle);
88 > *
89 > * //create object by ident
90 > * Line* line = ShapeFactory::getInstance()->createObject("Line");
91 > * Circle* circle = ShapeFactory::getInstance()->createObject("Circle");
92 > * @endcode
93 > *
94 > * Or the user can use predefined macro DECLARE_CREATOR and REGISTER_CREATOR
95 > * @code
96 > * //Shape class
97 > * class Shape {
98 > * ...
99 > * };
100 > *
101 > * //instantiating a new object factory
102 > * typedef GenericFactory<Shape> ShapeFactory;
103 > *
104 > * //Line class
105 > * class Line : public Shape{
106 > * ...
107 > * };
108 > *
109 > * //declare function using macro
110 > * DECLARE_CREATOR(Shape, Line)
111 > *
112 > * //register using macro
113 > * REGISTER_CREATOR(ShapeFactory, "Line", Line);
114 >
115 > * //Circle class
116 > * class Circle : public Shape{
117 > * ...
118 > * };
119 > *
120 > * //declare function using macro
121 > * DECLARE_CREATOR(Shape, Circle)
122 > *
123 > * //register using macro
124 > * REGISTER_CREATOR(ShapeFactory, "Circle", Circle);
125 > * @endcode
126 > */
127 > template<class Object, typename IdentType = std::string, typename Creator = Object* (*)()>
128 > class GenericFactory {
129      public:
130 +        typedef GenericFactory<Object, IdentType, Creator> FactoryType;
131 +        typedef std::map<IdentType, Creator> CreatorMapType;
132          
133 <        typedef map<ProductIdentType,  Creator*> CreatorMapType;
134 <        ~GenericFactory();
133 >        /**
134 >         * Returns an instance of object factory
135 >         * @return an instance of object factory
136 >         */        
137 >        static FactoryType* getInstance(){
138 >            if (instance_ == NULL)
139 >                instance_ = new FactoryType;
140 >            return instance_;
141 >        }
142  
143 <        static GenericFactory* getInstance();
143 >        /**
144 >         * Registers a creator with a type identifier
145 >         * @return true if registration is succeed, otherwise return false
146 >         * @id the identification of the concrete object
147 >         * @creator the object responsible to create the concrete object
148 >         */
149 >        bool registerCreator(const IdentType& id, Creator creator) {
150 >            return creatorMap_.insert(
151 >                CreatorMapType::value_type(id, creator)).second;
152 >        }
153  
154 <        bool register(CreatorType*  creator);
154 >        /**
155 >         * Unregisters the creator for the given type identifier. If the type identifier
156 >         * was previously registered, the function returns true.
157 >         * @return truethe type identifier was previously registered and the creator is removed,
158 >         * otherwise return false
159 >         * @id the identification of the concrete object
160 >         */
161 >        bool unregisterCreator(const IdentType& id) {
162 >            return creatorMap_.erase(id) == 1;
163 >        }
164  
165 <        bool unregister();
166 <        
167 <        bool hasCreator( const ProductIdentType& id );
165 >        /**
166 >         * Looks up the type identifier in the internal map. If it is found, it invokes the
167 >         * corresponding creator for the type identifier and returns its result.
168 >         * @return a pointer of the concrete object, return NULL if no creator is registed for
169 >         * creating this concrete object
170 >         * @param id the identification of the concrete object
171 >         */
172 >        Object* createObject(const IdentType& id) {
173 >            typename CreatorMapType::iterator i = creatorMap_.find(id);
174 >            if (i != creatorMap_.end()) {
175 >                //invoke functor to create object
176 >                return (i->second)();
177 >            } else {
178 >                return NULL;
179 >            }
180 >        }
181  
182 <        const std::string toString();
182 >        /**
183 >         *  Returns all of the registed  type identifiers
184 >         * @return all of the registed  type identifiers
185 >         */
186 >        std::vector<IdentType> getIdents() {
187 >            std::vector<IdentType> idents;
188 >            typename CreatorMapType::iterator i;
189  
190 <        Product* createProduct( const ProductIdentType& id );
191 <        
192 <    private:
193 <        GenericFactory(){}
194 <        static GenericFactory* instance_;
195 <        map<string,  Creator*> creatorMap_;
190 >            for (i = creatorMap_.begin(); i != creatorMap_.end(); ++i) {
191 >                idents.push_back(i->first);
192 >            }
193 >            
194 >            return idents;
195 >        }
196 >
197 >    public:
198 >        static FactoryType* instance_;
199 >        CreatorMapType creatorMap_;
200   };
201  
202 < typedef GenericFactory<ForceFieldParser, > ForceFiledParserFactory;
203 < #endif
202 > /** write out all of the type identifiers to an output stream */
203 > template<typename O, typename I, typename C>
204 > std::ostream& operator <<(std::ostream& o, GenericFactory<O, I, C>& factory) {
205 >    std::vector<I> idents;
206 >    std::vector<I>::iterator i;
207  
208 +    idents = factory.getIdents();
209 +
210 +    o << "Avaliable type identifiers in this factory: " << std::endl;
211 +    for (i = idents.begin(); i != idents.end(); ++i) {
212 +        o << *i << std::endl;
213 +    }
214 +
215 +    return o;
216 + }
217 +
218 + //static template class member
219 + template<class Object, typename IdentType,typename Creator>
220 + GenericFactory<Object,IdentType,Creator>* GenericFactory<Object,IdentType,Creator>::instance_ ;
221 +
222 +
223 + #define DECLARE_CREATOR(abstractObject, concreteObject) \
224 +    inline abstractObject* create##concreteObject(){\
225 +        return new concreteObject;\
226 +    }
227 +
228 + #define REGISTER_CREATOR(factory, ident, concreteObject) \
229 +        const bool registered##concreteObject = factory::getInstance()->registerCreator(ident, create##concreteObject);
230 +
231 +
232 + }//namespace oopse
233 + #endif //UTIL_GENERICFACTORY_HPP
234 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines