00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <pch.h>
00033 #include "Sim/Foundation/Resource/Builder/ResourceFactory.h"
00034
00035 using namespace Onikiri;
00036
00037
00038
00039
00040
00041 ResourceFactory::ResourceFactory()
00042 {
00043 InitializeResourceMap();
00044 }
00045
00046
00047
00048
00049 template <typename T>
00050 class ResourceInterfaceTrait : public ResourceTypeTraitBase
00051 {
00052 public:
00053 ResourceInterfaceTrait()
00054 {
00055 }
00056
00057 virtual PhysicalResourceNode* CreateInstance()
00058 {
00059 return NULL;
00060 }
00061
00062 virtual void* DynamicCast(PhysicalResourceIF* ptr)
00063 {
00064 return dynamic_cast<T*>(ptr);
00065 }
00066 };
00067
00068 template <typename T>
00069 class ResourceTypeTrait : public ResourceTypeTraitBase
00070 {
00071 public:
00072 ResourceTypeTrait()
00073 {
00074 }
00075
00076 virtual PhysicalResourceNode* CreateInstance()
00077 {
00078 return new T();
00079 }
00080
00081 virtual void* DynamicCast(PhysicalResourceIF* ptr)
00082 {
00083 return dynamic_cast<T*>(ptr);
00084 }
00085 };
00086
00087
00088
00089
00090 void ResourceFactory::CheckTypeRegistered(const String& typeName)
00091 {
00092 MapType::iterator i = m_resTypeMap.find( typeName );
00093 if( i != m_resTypeMap.end() ){
00094 THROW_RUNTIME_ERROR(
00095 "'%s' is already registered in 'ResourceFactory'.",
00096 typeName.c_str()
00097 );
00098 }
00099 }
00100
00101
00102
00103
00104 ResourceTypeTraitBase* ResourceFactory::GetTrait( const String& typeName )
00105 {
00106 MapType::iterator i = m_resTypeMap.find( typeName );
00107 if(i == m_resTypeMap.end()){
00108 THROW_RUNTIME_ERROR(
00109 "The resource type '%s' is not registered in the map of 'ResourceFactory'.",
00110 typeName.c_str()
00111 );
00112 }
00113 return i->second;
00114 }
00115
00116
00117
00118
00119 PhysicalResourceNode* ResourceFactory::CreateInstance(const String& typeName)
00120 {
00121 PhysicalResourceNode* instance =
00122 GetTrait( typeName )->CreateInstance();
00123
00124 if( !instance ){
00125 THROW_RUNTIME_ERROR(
00126 "Could not create the instance of the '%s'.\n"
00127 "This class is an interface.",
00128 typeName.c_str()
00129 );
00130 }
00131
00132 instance->SetTypeConverter( this );
00133 return instance;
00134 }
00135
00136
00137
00138
00139 void* ResourceFactory::DynamicCast(const String& typeName, PhysicalResourceIF* orgPtr)
00140 {
00141 return GetTrait( typeName )->DynamicCast( orgPtr );
00142 }
00143
00144
00145
00146
00147
00148 #define BEGIN_RESOURCE_TYPE_MAP() \
00149 void ResourceFactory::InitializeResourceMap(){
00150
00151 #define END_RESOURCE_TYPE_MAP() \
00152 InitializeUserResourceMap(); \
00153 }
00154
00155 #define BEGIN_USER_RESOURCE_TYPE_MAP() \
00156 void ResourceFactory::InitializeUserResourceMap(){
00157
00158 #define END_USER_RESOURCE_TYPE_MAP() \
00159 }
00160
00161 #define RESOURCE_TYPE_ENTRY( typeName ) \
00162 CheckTypeRegistered( #typeName ); \
00163 m_resTypeMap[ #typeName ] = new ResourceTypeTrait<typeName>();
00164
00165 #define RESOURCE_INTERFACE_ENTRY( typeName ) \
00166 CheckTypeRegistered( #typeName ); \
00167 m_resTypeMap[ #typeName ] = new ResourceInterfaceTrait<typeName>();
00168
00169 #include "Sim/ResourceMap.h"
00170 #include "User/UserResourceMap.h"