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 1640 by tim, Mon Oct 18 17:07:27 2004 UTC vs.
Revision 1641 by tim, Sun Oct 24 07:55:48 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 <map>
35   #include <string>
36 + #include <vector>
37 +
38   namespace oopse {
39 < template<class Product, typename ProductIdentType = std::string, typename Creator = Product* (*)() >
40 < class GenericFactory{
39 >
40 > /**
41 > * @class GenericFactory GenericFactory.hpp "utils/GenericFactory.hpp"
42 > * @brief GenericFactory is a template based Object Factory
43 > * Factory pattern is used to define an interface for creating an object.
44 > *
45 > * @param Object the base class of the hierarchy for which you provide the object factory.
46 > * @param IdentType the object that identifies the type of the concrete object. Default type is string
47 > * @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 > * @code
51 > * //Shape class
52 > * class Shape {
53 > * ...
54 > * };
55 > *
56 > * //instantiating a new object factory
57 > * typedef GenericFactory<Shape> ShapeFactory;
58 > *
59 > * //Line class
60 > * class Line : public Shape{
61 > * ...
62 > * };
63 > *
64 > * //declare function to create Line
65 > * Shape* createLine() {
66 > *   return new Line;
67 > * }
68 > *
69 > * //register createLine
70 > * ShapeFactory::getInstance()->registerCreator("Line", createLine);
71 > *
72 > * //Circle class
73 > * class Circle : public Shape{
74 > * ...
75 > * };
76 > *
77 > * //declare function to create Circle
78 > * Shape* createCircle() {
79 > *   return new Circle;
80 > * }
81 > *
82 > * //register createCircle
83 > * ShapeFactory::getInstance()->registerCreator("Circle", createCircle);
84 > *
85 > * //create object by ident
86 > * Line* line = ShapeFactory::getInstance()->createObject("Line");
87 > * Circle* circle = ShapeFactory::getInstance()->createObject("Circle");
88 > * @endcode
89 > */
90 > template<class Object, typename IdentType = std::string, typename Creator = Object* (*)()>
91 > class GenericFactory {
92      public:
93 +        typedef GenericFactory<Object, IdentType, Creator> FactoryType;
94 +        typedef std::map<IdentType, Creator> CreatorMapType;
95          
96 <        typedef std::map<ProductIdentType,  Creator*> CreatorMapType;
97 <        typedef GenericFactory<Product, ProductIdentType, Creator> SelfType;
98 <        static SelfType* getInstance() {
99 <            if (instance_ == NULL) {
100 <                instance_ = new GenericFactory<Product, ProductIdentType, Creator>();
101 <            }
102 <
96 >        /**
97 >         * Returns an instance of object factory
98 >         * @return an instance of object factory
99 >         */        
100 >        static FactoryType* getInstance(){
101 >            if (instance_ == NULL)
102 >                instance_ = new FactoryType;
103              return instance_;
104          }
50        
51        //bool register( const ProductIdentType& id, Creator creator) {
105  
106 <            //insert method in std::map will return a pair<iterator, bool>. the second
107 <            //element of this pair indicates whether the result of the operation
108 <            //return creatorMap_.insert(CreatorMapType::value_type(id, creator)).second;
109 <        //}
106 >        /**
107 >         * Registers a creator with a type identifier
108 >         * @return true if registration is succeed, otherwise return false
109 >         * @id the identification of the concrete object
110 >         * @creator the object responsible to create the concrete object
111 >         */
112 >        bool registerCreator(const IdentType& id, Creator creator) {
113 >            return creatorMap_.insert(
114 >                CreatorMapType::value_type(id, creator)).second;
115 >        }
116  
117 <        bool unregister(const ProductIdentType& id) {
118 <            
119 <            return creatorMap_->erase(id) == 1;
120 <
117 >        /**
118 >         * Unregisters the creator for the given type identifier. If the type identifier
119 >         * was previously registered, the function returns true.
120 >         * @return truethe type identifier was previously registered and the creator is removed,
121 >         * otherwise return false
122 >         * @id the identification of the concrete object
123 >         */
124 >        bool unregisterCreator(const IdentType& id) {
125 >            return creatorMap_.erase(id) == 1;
126          }
63        
64        bool hasCreator( const ProductIdentType& id ) {
65            CreatorMapType::iterator i;
127  
128 <            i = creatorMap_.find(id);
129 <
128 >        /**
129 >         * Looks up the type identifier in the internal map. If it is found, it invokes the
130 >         * corresponding creator for the type identifier and returns its result.
131 >         * @return a pointer of the concrete object, return NULL if no creator is registed for
132 >         * creating this concrete object
133 >         * @id the identification of the concrete object
134 >         */
135 >        Object* createObject(const IdentType& id) {
136 >            typename CreatorMapType::iterator i = creatorMap_.find(id);
137              if (i != creatorMap_.end()) {
138 <                return true;
138 >                return (i->second)();
139              } else {
140 <                return false;
140 >                return NULL;
141              }
142          }
143  
144 <        //const std::string toString() {
144 >        /**
145 >         *  Returns all of the registed  type identifiers
146 >         * @return all of the registed  type identifiers
147 >         */
148 >        std::vector<IdentType> getIdents() {
149 >            std::vector<IdentType> idents;
150 >            typename CreatorMapType::iterator i;
151  
152 <        
153 <        //}
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;
152 >            for (i = creatorMap_.begin(); i != creatorMap_.end(); ++i) {
153 >                idents.push_back(i->first);
154              }
155 +            
156 +            return idents;
157          }
158 <        
159 <    private:
160 <        GenericFactory(){}
96 <        static SelfType* instance_;
158 >
159 >    public:
160 >        static FactoryType* instance_;
161          CreatorMapType creatorMap_;
162   };
163  
164 + /** write out all of the type identifier to a output stream */
165 + template<typename O, typename I, typename C>
166 + std::ostream& operator <<(std::ostream& o, GenericFactory<O, I, C>& factory) {
167 +    std::vector<I> idents;
168 +    std::vector<I>::iterator i;
169  
170 < #define REGISTER_CREATOR(factory, product, id) \
171 <    product * create##product() {\
172 <        return new product(); \
170 >    idents = factory.getIdents();
171 >
172 >    o << "Avaliable type identifiers in this factory: " << std::endl;
173 >    for (i = idents.begin(); i != idents.end(); ++i) {
174 >        o << *i << std::endl;
175      }
176  
177 +    return o;
178 + }
179 +
180 + //static template class member
181 + template<class Object, typename IdentType,typename Creator>
182 + GenericFactory<Object,IdentType,Creator>* GenericFactory<Object,IdentType,Creator>::instance_ ;
183 +
184 + #define DECLARE_CREATOR(abstractObject, concreteObject) \
185 +    abstractObject* create##concreteObject(){\
186 +        return new concreteObject;\
187 +    }
188 +
189   }//namespace oopse
190   #endif //UTIL_GENERICFACTORY_HPP
191  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines