![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 #ifndef REFLECTION_H 00002 #define REFLECTION_H 00003 00004 #include <typeinfo> 00005 #include <vector> 00006 00012 #define GET_TYPE_ID(lValue, constCharPtr){const std::type_info& typeInfo = typeid(lValue); constCharPtr = typeInfo.name();} 00013 00019 class IReflect 00020 { 00021 public: 00025 virtual ~IReflect() { } 00026 }; 00027 00031 class IType 00032 { 00033 public: 00037 virtual const char* getTypeId() = 0; 00038 00042 virtual size_t getSize() = 0; 00043 00049 virtual IReflect* createInstance() = 0; 00050 }; 00051 00060 class TypeManager 00061 { 00062 private: 00063 static std::vector<IType*> _types; 00064 00069 template<class ClassType> 00070 class Type : public IType 00071 { 00072 protected: 00073 const char* _typeName; 00074 public: 00075 00080 Type() 00081 { 00082 //the typeid mechanism maintains type_info instances 00083 //in at least VS2005, it is safe to hold onto just the name reference 00084 //this may not be safe in all compilers 00085 //ClassType type; 00086 const std::type_info & typeInfo = typeid(ClassType); 00087 00088 _typeName = typeInfo.name(); 00089 } 00090 00094 virtual const char* getTypeId() 00095 { 00096 return _typeName; 00097 }; 00098 00102 virtual size_t getSize() 00103 { 00104 return sizeof(ClassType); 00105 } 00106 00110 virtual IReflect* createInstance() 00111 { 00112 //If ClassType does not implement IReflect, 00113 //then we must be cautious to not cause a memory leak 00114 ClassType* instance = new ClassType(); 00115 IReflect* reflected = dynamic_cast<IReflect*>(instance); 00116 if(reflected == NULL) 00117 delete instance; 00118 return reflected; 00119 } 00120 }; 00121 00122 public: 00126 static void Release() 00127 { 00128 for(size_t i=0; i<_types.size(); ++i) 00129 { 00130 IType* t = _types[i]; 00131 delete t; 00132 } 00133 } 00138 template<class ClassType> 00139 static bool ContainsType() 00140 { 00141 Type<ClassType> type; 00142 00143 for(size_t i=0; i<_types.size(); ++i) 00144 if(strcmp(_types[i]->getTypeId(), type.getTypeId) == 0) 00145 return true; 00146 00147 return false; 00148 } 00149 00155 template<class ClassType> 00156 static IType* GetType() 00157 { 00158 Type<ClassType>* type = new Type<ClassType>(); 00159 for(size_t i=0; i<_types.size(); ++i) 00160 if(strcmp(_types[i]->getTypeId(), type->getTypeId()) == 0) 00161 { 00162 //delete type we created, we already have one 00163 delete type; 00164 return _types[i]; 00165 } 00166 00167 IType* ptr = dynamic_cast<IType*>(type); 00168 //do not delete type, because now it's going into the vector 00169 _types.push_back(ptr); 00170 return ptr; 00171 } 00172 00178 static IType* GetType(const char* typeId) 00179 { 00180 for(size_t i=0; i<_types.size(); ++i) 00181 if(strcmp(_types[i]->getTypeId(), typeId) == 0) 00182 return _types[i]; 00183 00184 return NULL; 00185 } 00186 00192 static IType* GetType(IReflect* object) 00193 { 00194 const std::type_info& typeInfo = typeid(*object); 00195 return GetType(typeInfo.name()); 00196 } 00197 00204 template<class ClassType> 00205 static const char* GetTypeId() 00206 { 00207 const std::type_info& typeInfo = typeid(ClassType); 00208 return typeInfo.name(); 00209 } 00210 00216 static size_t GetSize(IReflect* object) 00217 { 00218 IType* type = GetType(object); 00219 if(type == NULL) 00220 return 0; 00221 return type->getSize(); 00222 } 00223 00229 template<class ClassType> 00230 static ClassType CastType(void* object) 00231 { 00232 if(object == NULL) 00233 return NULL; 00234 ClassType ret = (ClassType)object; 00235 return dynamic_cast<ClassType>(ret); 00236 } 00237 }; 00238 00239 #endif
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.