Factory.h

00001 //===========================================================================
00002 // GoTools - SINTEF Geometry Tools version 1.1
00003 //
00004 // GoTools module: CORE
00005 //
00006 // Copyright (C) 2000-2007 SINTEF ICT, Applied Mathematics, Norway.
00007 //
00008 // This program is free software; you can redistribute it and/or          
00009 // modify it under the terms of the GNU General Public License            
00010 // as published by the Free Software Foundation version 2 of the License. 
00011 //
00012 // This program is distributed in the hope that it will be useful,        
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of         
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
00015 // GNU General Public License for more details.                           
00016 //
00017 // You should have received a copy of the GNU General Public License      
00018 // along with this program; if not, write to the Free Software            
00019 // Foundation, Inc.,                                                      
00020 // 59 Temple Place - Suite 330,                                           
00021 // Boston, MA  02111-1307, USA.                                           
00022 //
00023 // Contact information: E-mail: tor.dokken@sintef.no                      
00024 // SINTEF ICT, Department of Applied Mathematics,                         
00025 // P.O. Box 124 Blindern,                                                 
00026 // 0314 Oslo, Norway.                                                     
00027 //
00028 // Other licenses are also available for this software, notably licenses
00029 // for:
00030 // - Building commercial software.                                        
00031 // - Building software whose source code you wish to keep private.        
00032 //===========================================================================
00033 #ifndef _GOFACTORY_H
00034 #define _GOFACTORY_H
00035 
00036 #include <map>
00037 #include "GeomObject.h"
00038 #include <boost/smart_ptr.hpp>
00039 
00040 
00041 namespace Go
00042 {
00045 
00049     class Creator
00050     {
00051     public:
00052         virtual GeomObject* create() = 0;
00053         virtual ~Creator() {}
00054     };
00055 
00059     template <class T>
00060     class ConcreteCreator : public Creator
00061     {
00062     public:
00063         ConcreteCreator() {}
00064         GeomObject* create()
00065         {
00066             return new T;
00067         }
00068     };
00069     
00078     class Factory
00079     {
00080     public:
00081         ~Factory()
00082         {
00083             std::map<ClassType, Creator*>::iterator it;
00084             for (it = themap_.begin(); it != themap_.end(); ++it)
00085                 delete it->second;
00086         }
00087 
00092         static GeomObject* createObject(ClassType class_type)
00093         {
00094             return globalFactory()->doCreateObject(class_type);
00095         }
00096 
00106         void registerClass(ClassType class_type, Creator* c)
00107         {
00108             themap_[class_type] = c;
00109         }
00110 
00113         static Factory* globalFactory()
00114         {
00115             if (global_factory_.get() == 0)
00116                 global_factory_ = boost::shared_ptr<Factory>(new Factory);
00117             return global_factory_.get();
00118         }
00119     private:
00120         // private constructor.  User should not need to explicitly construct 
00121         // Factory.
00122         Factory()
00123         {
00124         }
00125 
00126         GeomObject* doCreateObject(ClassType class_type)
00127         {
00128             std::map<ClassType, Creator*>::iterator it;
00129             it = themap_.find(class_type);
00130             if (it==themap_.end()) {
00131                 THROW("Class type number " << class_type
00132                       << " is not registered.");
00133             }
00134             return it->second->create();
00135         }
00136         static boost::shared_ptr<Factory> global_factory_;
00137         std::map<ClassType, Creator*> themap_;
00138     };
00139 
00146     template <class T>
00147     void Register()
00148     {
00149         Factory* f = Factory::globalFactory();
00150         ConcreteCreator<T>* c = new ConcreteCreator<T>;
00151         f->registerClass(T::classType(), c);
00152     }
00153 
00158     // @afr: I have no idea why, but VS6 refuses to do 
00159 
00165     template <class T>
00166     class Registrator
00167     {
00168     public:
00169         Registrator()
00170         {
00171             Factory* f = Factory::globalFactory();
00172             ConcreteCreator<T>* c = new ConcreteCreator<T>;
00173             f->registerClass(T::classType(), c);
00174         }
00175     };
00176 
00177 
00179 } // namespace Go
00180 
00181 #endif // _GOFACTORY_H
00182 
00183 

Generated on Mon Jun 11 14:48:18 2007 for GoTools Core Library by  doxygen 1.5.1