BsScriptAssemblyManager.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsScriptAssemblyManager.h"
  4. #include "BsManagedSerializableObjectInfo.h"
  5. #include "BsMonoManager.h"
  6. #include "BsMonoAssembly.h"
  7. #include "BsMonoClass.h"
  8. #include "BsMonoField.h"
  9. #include "BsMonoMethod.h"
  10. #include "BsMonoProperty.h"
  11. #include "BsScriptManagedResource.h"
  12. #include "BsScriptComponent.h"
  13. #include "BsScriptSpriteTexture.h"
  14. #include "BsScriptMaterial.h"
  15. #include "BsScriptMesh.h"
  16. #include "BsScriptFont.h"
  17. #include "BsScriptShader.h"
  18. #include "BsScriptShaderInclude.h"
  19. #include "BsScriptPlainText.h"
  20. #include "BsScriptScriptCode.h"
  21. #include "BsScriptStringTable.h"
  22. #include "BsScriptGUISkin.h"
  23. #include "BsScriptPhysicsMaterial.h"
  24. #include "BsScriptPhysicsMesh.h"
  25. #include "BsScriptAudioClip.h"
  26. #include "BsScriptPrefab.h"
  27. #include "BsScriptAnimationClip.h"
  28. #include "BsBuiltinComponentLookup.generated.h"
  29. #include "BsScriptTexture.generated.h"
  30. namespace bs
  31. {
  32. ScriptAssemblyManager::ScriptAssemblyManager()
  33. : mBaseTypesInitialized(false), mSystemArrayClass(nullptr), mSystemGenericListClass(nullptr)
  34. , mSystemGenericDictionaryClass(nullptr), mSystemTypeClass(nullptr), mComponentClass(nullptr)
  35. , mManagedComponentClass(nullptr), mSceneObjectClass(nullptr), mMissingComponentClass(nullptr)
  36. , mSerializeObjectAttribute(nullptr), mDontSerializeFieldAttribute(nullptr), mSerializeFieldAttribute(nullptr)
  37. , mHideInInspectorAttribute(nullptr), mShowInInspectorAttribute(nullptr), mRangeAttribute(nullptr)
  38. , mStepAttribute(nullptr)
  39. {
  40. }
  41. ScriptAssemblyManager::~ScriptAssemblyManager()
  42. {
  43. }
  44. Vector<String> ScriptAssemblyManager::getScriptAssemblies() const
  45. {
  46. Vector<String> initializedAssemblies;
  47. for (auto& assemblyPair : mAssemblyInfos)
  48. initializedAssemblies.push_back(assemblyPair.first);
  49. return initializedAssemblies;
  50. }
  51. void ScriptAssemblyManager::loadAssemblyInfo(const String& assemblyName)
  52. {
  53. if(!mBaseTypesInitialized)
  54. initializeBaseTypes();
  55. initializeBuiltinComponentInfos();
  56. // Process all classes and fields
  57. UINT32 mUniqueTypeId = 1;
  58. MonoAssembly* curAssembly = MonoManager::instance().getAssembly(assemblyName);
  59. if(curAssembly == nullptr)
  60. return;
  61. SPtr<ManagedSerializableAssemblyInfo> assemblyInfo = bs_shared_ptr_new<ManagedSerializableAssemblyInfo>();
  62. assemblyInfo->mName = assemblyName;
  63. mAssemblyInfos[assemblyName] = assemblyInfo;
  64. MonoClass* managedResourceClass = ScriptManagedResource::getMetaData()->scriptClass;
  65. // Populate class data
  66. const Vector<MonoClass*>& allClasses = curAssembly->getAllClasses();
  67. for(auto& curClass : allClasses)
  68. {
  69. if ((curClass->isSubClassOf(mManagedComponentClass) || curClass->isSubClassOf(managedResourceClass) ||
  70. curClass->hasAttribute(mSerializeObjectAttribute)) && curClass != mManagedComponentClass &&
  71. curClass != managedResourceClass)
  72. {
  73. SPtr<ManagedSerializableTypeInfoObject> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoObject>();
  74. typeInfo->mTypeNamespace = curClass->getNamespace();
  75. typeInfo->mTypeName = curClass->getTypeName();
  76. typeInfo->mTypeId = mUniqueTypeId++;
  77. MonoPrimitiveType monoPrimitiveType = MonoUtil::getPrimitiveType(curClass->_getInternalClass());
  78. if(monoPrimitiveType == MonoPrimitiveType::ValueType)
  79. typeInfo->mValueType = true;
  80. else
  81. typeInfo->mValueType = false;
  82. SPtr<ManagedSerializableObjectInfo> objInfo = bs_shared_ptr_new<ManagedSerializableObjectInfo>();
  83. objInfo->mTypeInfo = typeInfo;
  84. objInfo->mMonoClass = curClass;
  85. assemblyInfo->mTypeNameToId[objInfo->getFullTypeName()] = typeInfo->mTypeId;
  86. assemblyInfo->mObjectInfos[typeInfo->mTypeId] = objInfo;
  87. }
  88. }
  89. // Populate field & property data
  90. for(auto& curClassInfo : assemblyInfo->mObjectInfos)
  91. {
  92. SPtr<ManagedSerializableObjectInfo> objInfo = curClassInfo.second;
  93. UINT32 mUniqueFieldId = 1;
  94. const Vector<MonoField*>& fields = objInfo->mMonoClass->getAllFields();
  95. for(auto& field : fields)
  96. {
  97. if(field->isStatic())
  98. continue;
  99. SPtr<ManagedSerializableTypeInfo> typeInfo = getTypeInfo(field->getType());
  100. if (typeInfo == nullptr)
  101. continue;
  102. SPtr<ManagedSerializableFieldInfo> fieldInfo = bs_shared_ptr_new<ManagedSerializableFieldInfo>();
  103. fieldInfo->mFieldId = mUniqueFieldId++;
  104. fieldInfo->mName = field->getName();
  105. fieldInfo->mMonoField = field;
  106. fieldInfo->mTypeInfo = typeInfo;
  107. fieldInfo->mParentTypeId = objInfo->mTypeInfo->mTypeId;
  108. MonoMemberVisibility visibility = field->getVisibility();
  109. if (visibility == MonoMemberVisibility::Public)
  110. {
  111. if (!field->hasAttribute(mDontSerializeFieldAttribute))
  112. fieldInfo->mFlags |= ScriptFieldFlag::Serializable;
  113. if (!field->hasAttribute(mHideInInspectorAttribute))
  114. fieldInfo->mFlags |= ScriptFieldFlag::Inspectable;
  115. fieldInfo->mFlags |= ScriptFieldFlag::Animable;
  116. }
  117. else
  118. {
  119. if (field->hasAttribute(mSerializeFieldAttribute))
  120. fieldInfo->mFlags |= ScriptFieldFlag::Serializable;
  121. if (field->hasAttribute(mShowInInspectorAttribute))
  122. fieldInfo->mFlags |= ScriptFieldFlag::Inspectable;
  123. }
  124. if (field->hasAttribute(mRangeAttribute))
  125. fieldInfo->mFlags |= ScriptFieldFlag::Range;
  126. if (field->hasAttribute(mStepAttribute))
  127. fieldInfo->mFlags |= ScriptFieldFlag::Step;
  128. objInfo->mFieldNameToId[fieldInfo->mName] = fieldInfo->mFieldId;
  129. objInfo->mFields[fieldInfo->mFieldId] = fieldInfo;
  130. }
  131. const Vector<MonoProperty*>& properties = objInfo->mMonoClass->getAllProperties();
  132. for (auto& property : properties)
  133. {
  134. SPtr<ManagedSerializableTypeInfo> typeInfo = getTypeInfo(property->getReturnType());
  135. if (typeInfo == nullptr)
  136. continue;
  137. SPtr<ManagedSerializablePropertyInfo> propertyInfo = bs_shared_ptr_new<ManagedSerializablePropertyInfo>();
  138. propertyInfo->mFieldId = mUniqueFieldId++;
  139. propertyInfo->mName = property->getName();
  140. propertyInfo->mMonoProperty = property;
  141. propertyInfo->mTypeInfo = typeInfo;
  142. propertyInfo->mParentTypeId = objInfo->mTypeInfo->mTypeId;
  143. if (!property->isIndexed())
  144. {
  145. MonoMemberVisibility visibility = property->getVisibility();
  146. if (visibility == MonoMemberVisibility::Public)
  147. propertyInfo->mFlags |= ScriptFieldFlag::Animable;
  148. if (property->hasAttribute(mSerializeFieldAttribute))
  149. propertyInfo->mFlags |= ScriptFieldFlag::Serializable;
  150. if (property->hasAttribute(mShowInInspectorAttribute))
  151. propertyInfo->mFlags |= ScriptFieldFlag::Inspectable;
  152. }
  153. if (property->hasAttribute(mRangeAttribute))
  154. propertyInfo->mFlags |= ScriptFieldFlag::Range;
  155. if (property->hasAttribute(mStepAttribute))
  156. propertyInfo->mFlags |= ScriptFieldFlag::Step;
  157. objInfo->mFieldNameToId[propertyInfo->mName] = propertyInfo->mFieldId;
  158. objInfo->mFields[propertyInfo->mFieldId] = propertyInfo;
  159. }
  160. }
  161. // Form parent/child connections
  162. for(auto& curClass : assemblyInfo->mObjectInfos)
  163. {
  164. MonoClass* base = curClass.second->mMonoClass->getBaseClass();
  165. while(base != nullptr)
  166. {
  167. SPtr<ManagedSerializableObjectInfo> baseObjInfo;
  168. if(getSerializableObjectInfo(base->getNamespace(), base->getTypeName(), baseObjInfo))
  169. {
  170. curClass.second->mBaseClass = baseObjInfo;
  171. baseObjInfo->mDerivedClasses.push_back(curClass.second);
  172. break;
  173. }
  174. base = base->getBaseClass();
  175. }
  176. }
  177. }
  178. void ScriptAssemblyManager::clearAssemblyInfo()
  179. {
  180. clearScriptObjects();
  181. mAssemblyInfos.clear();
  182. }
  183. SPtr<ManagedSerializableTypeInfo> ScriptAssemblyManager::getTypeInfo(MonoClass* monoClass)
  184. {
  185. if(!mBaseTypesInitialized)
  186. BS_EXCEPT(InvalidStateException, "Calling getTypeInfo without previously initializing base types.");
  187. MonoPrimitiveType monoPrimitiveType = MonoUtil::getPrimitiveType(monoClass->_getInternalClass());
  188. // If enum get the enum base data type
  189. bool isEnum = MonoUtil::isEnum(monoClass->_getInternalClass());
  190. if (isEnum)
  191. monoPrimitiveType = MonoUtil::getEnumPrimitiveType(monoClass->_getInternalClass());
  192. // Determine field type
  193. switch(monoPrimitiveType)
  194. {
  195. case MonoPrimitiveType::Boolean:
  196. {
  197. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  198. typeInfo->mType = ScriptPrimitiveType::Bool;
  199. return typeInfo;
  200. }
  201. case MonoPrimitiveType::Char:
  202. {
  203. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  204. typeInfo->mType = ScriptPrimitiveType::Char;
  205. return typeInfo;
  206. }
  207. case MonoPrimitiveType::I8:
  208. {
  209. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  210. typeInfo->mType = ScriptPrimitiveType::I8;
  211. return typeInfo;
  212. }
  213. case MonoPrimitiveType::U8:
  214. {
  215. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  216. typeInfo->mType = ScriptPrimitiveType::U8;
  217. return typeInfo;
  218. }
  219. case MonoPrimitiveType::I16:
  220. {
  221. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  222. typeInfo->mType = ScriptPrimitiveType::I16;
  223. return typeInfo;
  224. }
  225. case MonoPrimitiveType::U16:
  226. {
  227. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  228. typeInfo->mType = ScriptPrimitiveType::U16;
  229. return typeInfo;
  230. }
  231. case MonoPrimitiveType::I32:
  232. {
  233. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  234. typeInfo->mType = ScriptPrimitiveType::I32;
  235. return typeInfo;
  236. }
  237. case MonoPrimitiveType::U32:
  238. {
  239. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  240. typeInfo->mType = ScriptPrimitiveType::U32;
  241. return typeInfo;
  242. }
  243. case MonoPrimitiveType::I64:
  244. {
  245. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  246. typeInfo->mType = ScriptPrimitiveType::I64;
  247. return typeInfo;
  248. }
  249. case MonoPrimitiveType::U64:
  250. {
  251. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  252. typeInfo->mType = ScriptPrimitiveType::U64;
  253. return typeInfo;
  254. }
  255. case MonoPrimitiveType::String:
  256. {
  257. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  258. typeInfo->mType = ScriptPrimitiveType::String;
  259. return typeInfo;
  260. }
  261. case MonoPrimitiveType::R32:
  262. {
  263. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  264. typeInfo->mType = ScriptPrimitiveType::Float;
  265. return typeInfo;
  266. }
  267. case MonoPrimitiveType::R64:
  268. {
  269. SPtr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
  270. typeInfo->mType = ScriptPrimitiveType::Double;
  271. return typeInfo;
  272. }
  273. case MonoPrimitiveType::Class:
  274. if(monoClass->isSubClassOf(ScriptResource::getMetaData()->scriptClass)) // Resource
  275. {
  276. SPtr<ManagedSerializableTypeInfoRef> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoRef>();
  277. typeInfo->mTypeNamespace = monoClass->getNamespace();
  278. typeInfo->mTypeName = monoClass->getTypeName();
  279. if(monoClass == ScriptResource::getMetaData()->scriptClass)
  280. typeInfo->mType = ScriptReferenceType::Resource;
  281. else if (monoClass->isSubClassOf(ScriptTexture::getMetaData()->scriptClass))
  282. typeInfo->mType = ScriptReferenceType::Texture;
  283. else if (monoClass->isSubClassOf(ScriptSpriteTexture::getMetaData()->scriptClass))
  284. typeInfo->mType = ScriptReferenceType::SpriteTexture;
  285. else if (monoClass->isSubClassOf(ScriptManagedResource::getMetaData()->scriptClass))
  286. typeInfo->mType = ScriptReferenceType::ManagedResource;
  287. else if (monoClass->isSubClassOf(ScriptShader::getMetaData()->scriptClass))
  288. typeInfo->mType = ScriptReferenceType::Shader;
  289. else if (monoClass->isSubClassOf(ScriptShaderInclude::getMetaData()->scriptClass))
  290. typeInfo->mType = ScriptReferenceType::ShaderInclude;
  291. else if (monoClass->isSubClassOf(ScriptMaterial::getMetaData()->scriptClass))
  292. typeInfo->mType = ScriptReferenceType::Material;
  293. else if (monoClass->isSubClassOf(ScriptMesh::getMetaData()->scriptClass))
  294. typeInfo->mType = ScriptReferenceType::Mesh;
  295. else if (monoClass->isSubClassOf(ScriptPlainText::getMetaData()->scriptClass))
  296. typeInfo->mType = ScriptReferenceType::PlainText;
  297. else if (monoClass->isSubClassOf(ScriptScriptCode::getMetaData()->scriptClass))
  298. typeInfo->mType = ScriptReferenceType::ScriptCode;
  299. else if (monoClass->isSubClassOf(ScriptPrefab::getMetaData()->scriptClass))
  300. typeInfo->mType = ScriptReferenceType::Prefab;
  301. else if (monoClass->isSubClassOf(ScriptFont::getMetaData()->scriptClass))
  302. typeInfo->mType = ScriptReferenceType::Font;
  303. else if (monoClass->isSubClassOf(ScriptStringTable::getMetaData()->scriptClass))
  304. typeInfo->mType = ScriptReferenceType::StringTable;
  305. else if (monoClass->isSubClassOf(ScriptGUISkin::getMetaData()->scriptClass))
  306. typeInfo->mType = ScriptReferenceType::GUISkin;
  307. else if (monoClass->isSubClassOf(ScriptPhysicsMaterial::getMetaData()->scriptClass))
  308. typeInfo->mType = ScriptReferenceType::PhysicsMaterial;
  309. else if (monoClass->isSubClassOf(ScriptPhysicsMesh::getMetaData()->scriptClass))
  310. typeInfo->mType = ScriptReferenceType::PhysicsMesh;
  311. else if (monoClass->isSubClassOf(ScriptAudioClip::getMetaData()->scriptClass))
  312. typeInfo->mType = ScriptReferenceType::AudioClip;
  313. else if (monoClass->isSubClassOf(ScriptAnimationClip::getMetaData()->scriptClass))
  314. typeInfo->mType = ScriptReferenceType::AnimationClip;
  315. else
  316. {
  317. assert(false && "Unrecognized resource type");
  318. }
  319. return typeInfo;
  320. }
  321. else if (monoClass->isSubClassOf(mSceneObjectClass) || monoClass->isSubClassOf(mComponentClass)) // Game object
  322. {
  323. SPtr<ManagedSerializableTypeInfoRef> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoRef>();
  324. typeInfo->mTypeNamespace = monoClass->getNamespace();
  325. typeInfo->mTypeName = monoClass->getTypeName();
  326. typeInfo->mRTIITypeId = 0;
  327. if (monoClass == mComponentClass)
  328. typeInfo->mType = ScriptReferenceType::BuiltinComponentBase;
  329. else if (monoClass == mManagedComponentClass)
  330. typeInfo->mType = ScriptReferenceType::ManagedComponentBase;
  331. else if (monoClass->isSubClassOf(mSceneObjectClass))
  332. typeInfo->mType = ScriptReferenceType::SceneObject;
  333. else if (monoClass->isSubClassOf(mManagedComponentClass))
  334. typeInfo->mType = ScriptReferenceType::ManagedComponent;
  335. else if (monoClass->isSubClassOf(mComponentClass))
  336. {
  337. typeInfo->mType = ScriptReferenceType::BuiltinComponent;
  338. ::MonoReflectionType* type = MonoUtil::getType(monoClass->_getInternalClass());
  339. BuiltinComponentInfo* builtinInfo = getBuiltinComponentInfo(type);
  340. if(builtinInfo == nullptr)
  341. {
  342. assert(false && "Unable to find information about a built-in component. Did you update BuiltinComponents list?");
  343. return nullptr;
  344. }
  345. typeInfo->mRTIITypeId = builtinInfo->typeId;
  346. }
  347. return typeInfo;
  348. }
  349. else
  350. {
  351. SPtr<ManagedSerializableObjectInfo> objInfo;
  352. if (getSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName(), objInfo))
  353. return objInfo->mTypeInfo;
  354. }
  355. break;
  356. case MonoPrimitiveType::ValueType:
  357. {
  358. SPtr<ManagedSerializableObjectInfo> objInfo;
  359. if (getSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName(), objInfo))
  360. return objInfo->mTypeInfo;
  361. }
  362. break;
  363. case MonoPrimitiveType::Generic:
  364. if(monoClass->getFullName() == mSystemGenericListClass->getFullName()) // Full name is part of CIL spec, so it is just fine to compare like this
  365. {
  366. SPtr<ManagedSerializableTypeInfoList> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoList>();
  367. MonoProperty* itemProperty = monoClass->getProperty("Item");
  368. MonoClass* itemClass = itemProperty->getReturnType();
  369. if (itemClass != nullptr)
  370. typeInfo->mElementType = getTypeInfo(itemClass);
  371. if (typeInfo->mElementType == nullptr)
  372. return nullptr;
  373. return typeInfo;
  374. }
  375. else if(monoClass->getFullName() == mSystemGenericDictionaryClass->getFullName())
  376. {
  377. SPtr<ManagedSerializableTypeInfoDictionary> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoDictionary>();
  378. MonoMethod* getEnumerator = monoClass->getMethod("GetEnumerator");
  379. MonoClass* enumClass = getEnumerator->getReturnType();
  380. MonoProperty* currentProp = enumClass->getProperty("Current");
  381. MonoClass* keyValuePair = currentProp->getReturnType();
  382. MonoProperty* keyProperty = keyValuePair->getProperty("Key");
  383. MonoProperty* valueProperty = keyValuePair->getProperty("Value");
  384. MonoClass* keyClass = keyProperty->getReturnType();
  385. if(keyClass != nullptr)
  386. typeInfo->mKeyType = getTypeInfo(keyClass);
  387. MonoClass* valueClass = valueProperty->getReturnType();
  388. if(valueClass != nullptr)
  389. typeInfo->mValueType = getTypeInfo(valueClass);
  390. if (typeInfo->mKeyType == nullptr || typeInfo->mValueType == nullptr)
  391. return nullptr;
  392. return typeInfo;
  393. }
  394. break;
  395. case MonoPrimitiveType::Array:
  396. {
  397. SPtr<ManagedSerializableTypeInfoArray> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoArray>();
  398. ::MonoClass* elementClass = ScriptArray::getElementClass(monoClass->_getInternalClass());
  399. if(elementClass != nullptr)
  400. {
  401. MonoClass* monoElementClass = MonoManager::instance().findClass(elementClass);
  402. if(monoElementClass != nullptr)
  403. typeInfo->mElementType = getTypeInfo(monoElementClass);
  404. }
  405. if (typeInfo->mElementType == nullptr)
  406. return nullptr;
  407. typeInfo->mRank = ScriptArray::getRank(monoClass->_getInternalClass());
  408. return typeInfo;
  409. }
  410. default:
  411. break;
  412. }
  413. return nullptr;
  414. }
  415. void ScriptAssemblyManager::clearScriptObjects()
  416. {
  417. mBaseTypesInitialized = false;
  418. mSystemArrayClass = nullptr;
  419. mSystemGenericListClass = nullptr;
  420. mSystemGenericDictionaryClass = nullptr;
  421. mSystemTypeClass = nullptr;
  422. mSerializeObjectAttribute = nullptr;
  423. mDontSerializeFieldAttribute = nullptr;
  424. mComponentClass = nullptr;
  425. mManagedComponentClass = nullptr;
  426. mSceneObjectClass = nullptr;
  427. mMissingComponentClass = nullptr;
  428. mSerializeFieldAttribute = nullptr;
  429. mHideInInspectorAttribute = nullptr;
  430. mShowInInspectorAttribute = nullptr;
  431. mRangeAttribute = nullptr;
  432. mStepAttribute = nullptr;
  433. }
  434. void ScriptAssemblyManager::initializeBaseTypes()
  435. {
  436. // Get necessary classes for detecting needed class & field information
  437. MonoAssembly* corlib = MonoManager::instance().getAssembly("corlib");
  438. if(corlib == nullptr)
  439. BS_EXCEPT(InvalidStateException, "corlib assembly is not loaded.");
  440. MonoAssembly* bansheeEngineAssembly = MonoManager::instance().getAssembly(ENGINE_ASSEMBLY);
  441. if(bansheeEngineAssembly == nullptr)
  442. BS_EXCEPT(InvalidStateException, String(ENGINE_ASSEMBLY) + " assembly is not loaded.");
  443. mSystemArrayClass = corlib->getClass("System", "Array");
  444. if(mSystemArrayClass == nullptr)
  445. BS_EXCEPT(InvalidStateException, "Cannot find System.Array managed class.");
  446. mSystemGenericListClass = corlib->getClass("System.Collections.Generic", "List`1");
  447. if(mSystemGenericListClass == nullptr)
  448. BS_EXCEPT(InvalidStateException, "Cannot find List<T> managed class.");
  449. mSystemGenericDictionaryClass = corlib->getClass("System.Collections.Generic", "Dictionary`2");
  450. if(mSystemGenericDictionaryClass == nullptr)
  451. BS_EXCEPT(InvalidStateException, "Cannot find Dictionary<TKey, TValue> managed class.");
  452. mSystemTypeClass = corlib->getClass("System", "Type");
  453. if (mSystemTypeClass == nullptr)
  454. BS_EXCEPT(InvalidStateException, "Cannot find Type managed class.");
  455. mSerializeObjectAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "SerializeObject");
  456. if(mSerializeObjectAttribute == nullptr)
  457. BS_EXCEPT(InvalidStateException, "Cannot find SerializableObject managed class.");
  458. mDontSerializeFieldAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "DontSerializeField");
  459. if(mDontSerializeFieldAttribute == nullptr)
  460. BS_EXCEPT(InvalidStateException, "Cannot find DontSerializeField managed class.");
  461. mRangeAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "Range");
  462. if (mRangeAttribute == nullptr)
  463. BS_EXCEPT(InvalidStateException, "Cannot find Range managed class.");
  464. mStepAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "Step");
  465. if (mStepAttribute == nullptr)
  466. BS_EXCEPT(InvalidStateException, "Cannot find Step managed class.");
  467. mComponentClass = bansheeEngineAssembly->getClass("BansheeEngine", "Component");
  468. if(mComponentClass == nullptr)
  469. BS_EXCEPT(InvalidStateException, "Cannot find Component managed class.");
  470. mManagedComponentClass = bansheeEngineAssembly->getClass("BansheeEngine", "ManagedComponent");
  471. if (mManagedComponentClass == nullptr)
  472. BS_EXCEPT(InvalidStateException, "Cannot find ManagedComponent managed class.");
  473. mMissingComponentClass = bansheeEngineAssembly->getClass("BansheeEngine", "MissingComponent");
  474. if (mMissingComponentClass == nullptr)
  475. BS_EXCEPT(InvalidStateException, "Cannot find MissingComponent managed class.");
  476. mSceneObjectClass = bansheeEngineAssembly->getClass("BansheeEngine", "SceneObject");
  477. if(mSceneObjectClass == nullptr)
  478. BS_EXCEPT(InvalidStateException, "Cannot find SceneObject managed class.");
  479. mSerializeFieldAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "SerializeField");
  480. if(mSerializeFieldAttribute == nullptr)
  481. BS_EXCEPT(InvalidStateException, "Cannot find SerializeField managed class.");
  482. mHideInInspectorAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "HideInInspector");
  483. if(mHideInInspectorAttribute == nullptr)
  484. BS_EXCEPT(InvalidStateException, "Cannot find HideInInspector managed class.");
  485. mShowInInspectorAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "ShowInInspector");
  486. if (mShowInInspectorAttribute == nullptr)
  487. BS_EXCEPT(InvalidStateException, "Cannot find ShowInInspector managed class.");
  488. mBaseTypesInitialized = true;
  489. }
  490. void ScriptAssemblyManager::initializeBuiltinComponentInfos()
  491. {
  492. mBuiltinComponentInfos.clear();
  493. mBuiltinComponentInfosByTID.clear();
  494. Vector<BuiltinComponentInfo> allComponentsInfos = BuiltinComponents::getEntries();
  495. for(auto& entry : allComponentsInfos)
  496. {
  497. MonoAssembly* assembly = MonoManager::instance().getAssembly(entry.metaData->assembly);
  498. if (assembly == nullptr)
  499. continue;
  500. BuiltinComponentInfo info = entry;
  501. info.monoClass = assembly->getClass(entry.metaData->ns, entry.metaData->name);
  502. ::MonoReflectionType* type = MonoUtil::getType(info.monoClass->_getInternalClass());
  503. mBuiltinComponentInfos[type] = info;
  504. mBuiltinComponentInfosByTID[info.typeId] = info;
  505. }
  506. }
  507. BuiltinComponentInfo* ScriptAssemblyManager::getBuiltinComponentInfo(::MonoReflectionType* type)
  508. {
  509. auto iterFind = mBuiltinComponentInfos.find(type);
  510. if (iterFind == mBuiltinComponentInfos.end())
  511. return nullptr;
  512. return &(iterFind->second);
  513. }
  514. BuiltinComponentInfo* ScriptAssemblyManager::getBuiltinComponentInfo(UINT32 rttiTypeId)
  515. {
  516. auto iterFind = mBuiltinComponentInfosByTID.find(rttiTypeId);
  517. if (iterFind == mBuiltinComponentInfosByTID.end())
  518. return nullptr;
  519. return &(iterFind->second);
  520. }
  521. bool ScriptAssemblyManager::getSerializableObjectInfo(const String& ns, const String& typeName, SPtr<ManagedSerializableObjectInfo>& outInfo)
  522. {
  523. String fullName = ns + "." + typeName;
  524. for(auto& curAssembly : mAssemblyInfos)
  525. {
  526. if (curAssembly.second == nullptr)
  527. continue;
  528. auto iterFind = curAssembly.second->mTypeNameToId.find(fullName);
  529. if(iterFind != curAssembly.second->mTypeNameToId.end())
  530. {
  531. outInfo = curAssembly.second->mObjectInfos[iterFind->second];
  532. return true;
  533. }
  534. }
  535. return false;
  536. }
  537. bool ScriptAssemblyManager::hasSerializableObjectInfo(const String& ns, const String& typeName)
  538. {
  539. String fullName = ns + "." + typeName;
  540. for(auto& curAssembly : mAssemblyInfos)
  541. {
  542. auto iterFind = curAssembly.second->mTypeNameToId.find(fullName);
  543. if(iterFind != curAssembly.second->mTypeNameToId.end())
  544. return true;
  545. }
  546. return false;
  547. }
  548. }