Shadowrun: Awakened 29 September 2011 - Build 871
Reflection.h
Go to the documentation of this file.
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.

GNU Lesser General Public License 3 Sourceforge.net