00001 #ifndef TEMPLATEFACTORY_H_
00002 #define TEMPLATEFACTORY_H_
00003
00004 #include <map>
00005 #include <string>
00006 #include <stdio.h>
00007 #include <iostream>
00008 #include <stdexcept>
00009
00010 #include "ModulesOptions.h"
00011 #include "ModulesParser.h"
00012
00013 template <typename BaseModule, typename OptionsType>
00014 class TemplateFactory{
00015 public:
00016
00017 typedef BaseModule*(*ModuleMaker)(OptionsType*);
00018 typedef std::vector<std::string> ArgumentsVector;
00019
00020 private:
00021 struct PerModule{
00022 OptionsType* opts;
00023 ModuleMaker maker;
00024 ArgumentsVector arguments;
00025 std::string product;
00026 PerModule():opts(NULL),maker(NULL){}
00027 };
00028 typedef std::map<std::string, PerModule> ModuleList;
00029
00030 protected:
00033 TemplateFactory(const std::string& name):fName(name){};
00034 virtual ~TemplateFactory(){
00035 fModules.clear();
00036 }
00037
00038 public:
00040 void registerModule(const std::string&, ModuleMaker,const std::string& out="");
00042 virtual BaseModule* createModule(const std::string&, OptionsType* opts=NULL);
00044 bool canCreate(const std::string& name)const{return (bool) fModules.count(name);};
00045 void addOptions(const std::string& name, OptionsType *opts);
00046 void addArguments(const std::string& all_args);
00047 void addArgument(const std::string& module,const std::string& argument);
00048 void addArgument(const std::string& argument);
00049 std::string GetArgumentName(const std::string& module,const int& argument);
00050 std::string GetProduct(const std::string& module);
00051
00052
00053 void SetDebug(bool debug=true){fDebug=debug;};
00054
00055 void PrintPossibleModules()const;
00056
00057 private:
00058 const PerModule& GetModuleDetails(const std::string&)const;
00059
00060
00061 ModuleList fModules;
00062
00063
00064 std::string fMostRecentRegister;
00065
00066
00067 bool fDebug;
00068 std::string fName;
00069 };
00070
00071 #include "TemplateFactory.tpl"
00072
00073 template <typename ConcreteClass,
00074 typename BaseClass,
00075 typename Options>
00076 BaseClass* RegistryProxyMaker(Options* opts){return new ConcreteClass(opts);};
00077
00078 template <typename ConcreteClass,
00079 typename BaseClass,
00080 typename Options,
00081 typename Factory>
00082 class RegistryProxy{
00083 public:
00084 RegistryProxy(const char* Name, const char* ArgumentNames, const char* Product="")
00085 {
00086 Factory *f = Factory::Instance();
00087 f->registerModule( Name , &RegistryProxyMaker<ConcreteClass,BaseClass,Options>, Product);
00088
00089 f->addArguments( ArgumentNames);
00090 }
00091 };
00092
00093 #endif //TEMPLATEFACTORY_H_