00001 #ifndef EvSimObjectTypeUtils_H_
00002 #define EvSimObjectTypeUtils_H_
00003
00004 #include "EvSimObject.h"
00005 #include "EvSimObjectCloneFactory.h"
00006 #include "evesim_hash.h"
00007
00008 #include <string>
00009 using std::string;
00010
00011 #include <cstddef>
00012
00013 #include <iostream>
00014
00015 #include <boost/format.hpp>
00016
00017
00018 #define EV_SIM_OBJECT(type) \
00019 public: \
00020 static EvSimObjectTypeUtils<type> simobj_utils; \
00021 \
00022 friend void field_registrator_func<type>(type *); \
00023 \
00024 virtual const EvSimObjectTypeUtilsBase * getSimObjTypeUtils() const; \
00025
00026
00027
00028 #define EV_SIM_OBJECT_POST(OBJECTTYPE) \
00029 EvSimObjectTypeUtils<OBJECTTYPE > OBJECTTYPE::simobj_utils = \
00030 EvSimObjectTypeUtils<OBJECTTYPE >(#OBJECTTYPE); \
00031 \
00032 const EvSimObjectTypeUtilsBase * OBJECTTYPE::getSimObjTypeUtils() const \
00033 { \
00034 return &OBJECTTYPE::simobj_utils; \
00035 } \
00036
00037
00038 #define FIELD_REGISTRATOR(OBJECTTYPE) \
00039 template<> \
00040 void field_registrator_func<OBJECTTYPE>(OBJECTTYPE *obj_ptr) \
00041
00042
00043 #define REGISTER_FIELD(OBJECTTYPE, FIELDNAME) \
00044 OBJECTTYPE::simobj_utils.registerVariable(string(#FIELDNAME), \
00045 (char *)&obj_ptr->FIELDNAME - (char *)obj_ptr, \
00046 typeid(obj_ptr->FIELDNAME)); \
00047
00048
00049
00050 class EvSimObjectTypeUtilsBase {
00051 public:
00052 EvSimObjectTypeUtilsBase(const string &type_name) : type_name(type_name) {};
00053
00054 virtual ~EvSimObjectTypeUtilsBase() {};
00055
00056 virtual EvSimObject* copy(const EvSimObject * source) const = 0;
00057
00058 virtual void registerVariable(const string &var_name, ptrdiff_t offset, const type_info &t_info) = 0;
00059
00060 virtual void * const getVariablePtr(const EvSimObject *obj, const string &var_name) const = 0;
00061
00062 virtual const type_info & getVariableType(const EvSimObject *obj, const string &var_name) const = 0;
00063
00064 virtual const string &getTypeName() const {
00065 return type_name;
00066 }
00067
00068 protected:
00069 string type_name;
00070 };
00071
00072
00073 template<class T>
00074 class EvSimObjectTypeUtils : public EvSimObjectTypeUtilsBase {
00075 public:
00076
00077 EvSimObjectTypeUtils<T>(const string &type_name) : EvSimObjectTypeUtilsBase(type_name) {
00078 T *example_obj = (T *)200000;
00079 field_registrator_func(example_obj);
00080 };
00081
00082 virtual ~EvSimObjectTypeUtils<T>() {};
00083
00084 virtual EvSimObject* copy(const EvSimObject * source) const
00085 {
00086 return new T(*dynamic_cast<const T*>(source));
00087 };
00088
00089 virtual void registerVariable(const string &var_name, ptrdiff_t offset, const type_info &t_info) {
00090 field_offsets.insert(make_pair(var_name, offset));
00091 field_types.insert(make_pair(var_name, &t_info));
00092 }
00093
00094 virtual void * const getVariablePtr(const EvSimObject *obj, const string &var_name) const {
00095 const T *downcast_obj = dynamic_cast<const T *>(obj);
00096 field_offsets_map_type::const_iterator it;
00097 if ((it = field_offsets.find(var_name)) != field_offsets.end())
00098 return reinterpret_cast<void * const>((char *)downcast_obj + it->second);
00099 return 0;
00100 };
00101
00102 virtual const type_info & getVariableType(const EvSimObject *obj, const string &var_name) const
00103 {
00104 field_types_map_type::const_iterator it;
00105 if ((it = field_types.find(var_name)) != field_types.end())
00106 return *it->second;
00107 return typeid(NoVariableFound);
00108 };
00109
00110 protected:
00111 typedef hash_map< string, ptrdiff_t, evesim::hash<string> > field_offsets_map_type;
00112 typedef hash_map< string, const type_info *, evesim::hash<string> > field_types_map_type;
00113
00114 field_offsets_map_type field_offsets;
00115 field_types_map_type field_types;
00116 };
00117
00118
00119 template<typename T>
00120 void field_registrator_func(T * ) {}
00121
00122 #endif