//=========================================================================== // GoTools Core - SINTEF Geometry Tools Core library, version 2.0.1 // // Copyright (C) 2000-2007, 2010 SINTEF ICT, Applied Mathematics, Norway. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., // 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // // Contact information: E-mail: tor.dokken@sintef.no // SINTEF ICT, Department of Applied Mathematics, // P.O. Box 124 Blindern, // 0314 Oslo, Norway. // // Other licenses are also available for this software, notably licenses // for: // - Building commercial software. // - Building software whose source code you wish to keep private. //=========================================================================== 00015 #ifndef _FACTORY_H 00016 #define _FACTORY_H 00017 00018 #include <map> 00019 #include "GoTools/geometry/GeomObject.h" 00020 #include <boost/smart_ptr.hpp> 00021 #include "GoTools/utils/config.h" 00022 00023 namespace Go 00024 { 00028 class Creator 00029 { 00030 public: 00031 virtual GeomObject* create() = 0; 00032 virtual ~Creator() {} 00033 }; 00034 00038 template <class T> 00039 class ConcreteCreator : public Creator 00040 { 00041 public: 00042 ConcreteCreator() {} 00043 GeomObject* create() 00044 { 00045 return new T; 00046 } 00047 }; 00048 00057 class Factory 00058 { 00059 public: 00060 ~Factory() 00061 { 00062 std::map<ClassType, Creator*>::iterator it; 00063 for (it = themap_.begin(); it != themap_.end(); ++it) 00064 delete it->second; 00065 } 00066 00071 static GeomObject* createObject(ClassType class_type) 00072 { 00073 return globalFactory()->doCreateObject(class_type); 00074 } 00075 00085 void registerClass(ClassType class_type, Creator* c) 00086 { 00087 themap_[class_type] = c; 00088 } 00089 00092 static Factory* globalFactory() 00093 { 00094 static Factory factory_singleton; 00095 return &factory_singleton; 00096 // if (global_factory_.get() == 0) 00097 // global_factory_ = boost::shared_ptr<Factory>(new Factory); 00098 // return global_factory_.get(); 00099 } 00100 private: 00101 // private constructor. User should not need to explicitly construct 00102 // Factory. 00103 Factory() 00104 { 00105 } 00106 00107 GeomObject* doCreateObject(ClassType class_type) 00108 { 00109 std::map<ClassType, Creator*>::iterator it; 00110 it = themap_.find(class_type); 00111 if (it==themap_.end()) { 00112 THROW("Class type number " << class_type 00113 << " is not registered."); 00114 } 00115 return it->second->create(); 00116 } 00117 //static GO_API boost::shared_ptr<Factory> global_factory_; 00118 std::map<ClassType, Creator*> themap_; 00119 }; 00120 00127 template <class T> 00128 void Register() 00129 { 00130 Factory* f = Factory::globalFactory(); 00131 ConcreteCreator<T>* c = new ConcreteCreator<T>; 00132 f->registerClass(T::classType(), c); 00133 delete c; 00134 } 00135 00140 // @afr: I have no idea why, but VS6 refuses to do 00141 00147 template <class T> 00148 class Registrator 00149 { 00150 public: 00151 Registrator() 00152 { 00153 Factory* f = Factory::globalFactory(); 00154 ConcreteCreator<T>* c = new ConcreteCreator<T>; 00155 f->registerClass(T::classType(), c); 00156 } 00157 }; 00158 00159 00160 } // namespace Go 00161 00162 #endif // _FACTORY_H 00163