Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #pragma once
00010
00011 #include <mvsim/basic_types.h>
00012 #include <map>
00013 #include <stdexcept>
00014 #include <string>
00015
00016 namespace mvsim
00017 {
00020 template <class CLASS, typename ARG1 = void, typename ARG2 = int>
00021 class ClassFactory
00022 {
00023 public:
00024 struct TClassData
00025 {
00026 CLASS* (*ptr_factory1)(ARG1);
00027 CLASS* (*ptr_factory2)(ARG1, ARG2);
00028 TClassData() : ptr_factory1(NULL), ptr_factory2(NULL) {}
00029 };
00030
00031 void do_register(const std::string& class_name, const TClassData& data)
00032 {
00033 m_classes[class_name] = data;
00034 }
00035
00036 CLASS* create(const std::string& class_name, ARG1 a1) const
00037 {
00038 typename std::map<std::string, TClassData>::const_iterator it =
00039 m_classes.find(class_name);
00040 if (it == m_classes.end())
00041 throw std::runtime_error(
00042 (std::string("ClassFactory: Unknown class ") + class_name)
00043 .c_str());
00044 if (!it->second.ptr_factory1)
00045 throw std::runtime_error(
00046 (std::string("ClassFactory: factory(1) pointer is NULL for ") +
00047 class_name)
00048 .c_str());
00049 return (*it->second.ptr_factory1)(a1);
00050 }
00051 CLASS* create(const std::string& class_name, ARG1 a1, ARG2 a2) const
00052 {
00053 typename std::map<std::string, TClassData>::const_iterator it =
00054 m_classes.find(class_name);
00055 if (it == m_classes.end())
00056 throw std::runtime_error(
00057 (std::string("ClassFactory: Unknown class ") + class_name)
00058 .c_str());
00059 if (!it->second.ptr_factory2)
00060 throw std::runtime_error(
00061 (std::string("ClassFactory: factory(2) pointer is NULL for ") +
00062 class_name)
00063 .c_str());
00064 return (*it->second.ptr_factory2)(a1, a2);
00065 }
00066
00067 private:
00068 std::map<std::string, TClassData> m_classes;
00069 };
00070
00071 #define DECLARES_REGISTER_CLASS1(CLASS_NAME, BASE_CLASS, ARG1) \
00072 public: \
00073 static BASE_CLASS* Create(ARG1 a1) { return new CLASS_NAME(a1); }
00074 #define DECLARES_REGISTER_CLASS2(CLASS_NAME, BASE_CLASS, ARG1, ARG2) \
00075 public: \
00076 static BASE_CLASS* Create(ARG1 a1, ARG2 a2) \
00077 { \
00078 return new CLASS_NAME(a1, a2); \
00079 }
00080
00081 #define REGISTER_CLASS1(FACTORY_TYPE, FACTORY_OBJ, TEXTUAL_NAME, CLASS_NAME) \
00082 { \
00083 FACTORY_TYPE::TClassData data; \
00084 data.ptr_factory1 = &CLASS_NAME::Create; \
00085 FACTORY_OBJ.do_register(TEXTUAL_NAME, data); \
00086 }
00087
00088 #define REGISTER_CLASS2(FACTORY_TYPE, FACTORY_OBJ, TEXTUAL_NAME, CLASS_NAME) \
00089 { \
00090 FACTORY_TYPE::TClassData data; \
00091 data.ptr_factory2 = &CLASS_NAME::Create; \
00092 FACTORY_OBJ.do_register(TEXTUAL_NAME, data); \
00093 }
00094 }