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 1592 by tim, Mon Oct 18 17:07:27 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   namespace oopse {
40 < template<class Product, typename ProductIdentType = std::string, typename Creator = Product* (*)() >
41 < class GenericFactory{
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 std::map<ProductIdentType,  Creator*> CreatorMapType;
134 <        typedef GenericFactory<Product, ProductIdentType, Creator> SelfType;
135 <        static SelfType* getInstance() {
136 <            if (instance_ == NULL) {
137 <                instance_ = new GenericFactory<Product, ProductIdentType, Creator>();
138 <            }
139 <
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          }
50        
51        //bool register( const ProductIdentType& id, Creator creator) {
142  
143 <            //insert method in std::map will return a pair<iterator, bool>. the second
144 <            //element of this pair indicates whether the result of the operation
145 <            //return creatorMap_.insert(CreatorMapType::value_type(id, creator)).second;
146 <        //}
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 unregister(const ProductIdentType& id) {
155 <            
156 <            return creatorMap_->erase(id) == 1;
157 <
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          }
63        
64        bool hasCreator( const ProductIdentType& id ) {
65            CreatorMapType::iterator i;
164  
165 <            i = creatorMap_.find(id);
166 <
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 <                return true;
175 >                //invoke functor to create object
176 >                return (i->second)();
177              } else {
178 <                return false;
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 <        
191 <        //}
80 <
81 <        Product* createProduct( const ProductIdentType& id ) {
82 <            CreatorMapType::iterator i;
83 <
84 <            i = creatorMap_.find(id);
85 <
86 <            if (i != creatorMap_.end()) {
87 <                //call the function to create the product
88 <                return (i->second)();
89 <            } else {
90 <                return NULL;
190 >            for (i = creatorMap_.begin(); i != creatorMap_.end(); ++i) {
191 >                idents.push_back(i->first);
192              }
193 +            
194 +            return idents;
195          }
196 <        
197 <    private:
198 <        GenericFactory(){}
96 <        static SelfType* instance_;
196 >
197 >    public:
198 >        static FactoryType* instance_;
199          CreatorMapType creatorMap_;
200   };
201  
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 < #define REGISTER_CREATOR(factory, product, id) \
209 <    product * create##product() {\
210 <        return new product(); \
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