BsRuntimeScriptObjects.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. #include "BsRuntimeScriptObjects.h"
  2. #include "BsScriptResourceManager.h"
  3. #include "BsScriptGameObjectManager.h"
  4. #include "BsMonoManager.h"
  5. #include "BsMonoAssembly.h"
  6. #include "BsMonoClass.h"
  7. #include "BsMonoField.h"
  8. #include "BsMonoUtil.h"
  9. #include "BsScriptTexture2D.h"
  10. #include "BsScriptSpriteTexture.h"
  11. using namespace CamelotFramework;
  12. namespace BansheeEngine
  13. {
  14. SerializableObjectInfo::SerializableObjectInfo()
  15. :mMonoClass(nullptr), mTypeId(0)
  16. {
  17. }
  18. SerializableObjectInfo::~SerializableObjectInfo()
  19. {
  20. for(auto& field : mFields)
  21. {
  22. cm_delete(field.second);
  23. }
  24. }
  25. SerializableFieldInfo::SerializableFieldInfo()
  26. :mMonoField(nullptr), mType(ScriptFieldType::Other), mFlags((ScriptFieldFlags)0), mFieldId(0)
  27. {
  28. }
  29. SerializableFieldInfo::~SerializableFieldInfo()
  30. {
  31. }
  32. bool SerializableFieldInfo::isArray()
  33. {
  34. return ((UINT32)mFlags & (UINT32)ScriptFieldFlags::Array) != 0;
  35. }
  36. bool SerializableFieldInfo::isReferenceType()
  37. {
  38. return (isArray() || mType == ScriptFieldType::TextureRef || mType == ScriptFieldType::SpriteTextureRef ||
  39. mType == ScriptFieldType::SceneObjectRef || mType == ScriptFieldType::ComponentRef || mType == ScriptFieldType::SerializableObjectRef);
  40. }
  41. bool SerializableFieldInfo::isNull(MonoObject* obj)
  42. {
  43. assert(isReferenceType());
  44. void* val = mMonoField->getValue(obj);
  45. return val == nullptr;
  46. }
  47. void SerializableFieldInfo::setNull(MonoObject* obj)
  48. {
  49. assert(isReferenceType());
  50. mMonoField->setValue(obj, nullptr);
  51. }
  52. UINT32 SerializableFieldInfo::getNumArrayElements(MonoObject* obj)
  53. {
  54. assert(((UINT32)mFlags & (UINT32)ScriptFieldFlags::Array) != 0);
  55. MonoArray* array = reinterpret_cast<MonoArray*>(mMonoField->getValue(obj));
  56. return (UINT32)mono_array_length(array);
  57. }
  58. void SerializableFieldInfo::setNumArrayElements(MonoObject* obj, UINT32 numElements, bool discardExisting)
  59. {
  60. assert(((UINT32)mFlags & (UINT32)ScriptFieldFlags::Array) != 0);
  61. uint32_t lengths[1] = { numElements };
  62. MonoArray* newArray = mono_array_new_full(MonoManager::instance().getDomain(),
  63. mMonoField->getType()->_getInternalClass(), (uintptr_t*)lengths, nullptr);
  64. if(!discardExisting)
  65. {
  66. MonoArray* existingArray = reinterpret_cast<MonoArray*>(mMonoField->getValue(obj));
  67. UINT32 existingArrayLength = (UINT32)mono_array_length(existingArray);
  68. UINT32 elemsToCopy = std::min(existingArrayLength, numElements);
  69. int32_t elemSize = mono_array_element_size(mMonoField->getType()->_getInternalClass());
  70. for(UINT32 i = 0; i < elemsToCopy; i++)
  71. {
  72. void* existingValAddr = (void*)mono_array_addr_with_size(existingArray, elemSize, (uintptr_t)i);
  73. void* newValAddr = (void*)mono_array_addr_with_size(newArray, elemSize, (uintptr_t)i);
  74. memcpy(newValAddr, existingValAddr, elemSize);
  75. }
  76. }
  77. mMonoField->setValue(obj, newArray);
  78. }
  79. void SerializableFieldInfo::setU8(MonoObject* obj, UINT8 val, UINT32 arrayIdx)
  80. {
  81. assert(mType == ScriptFieldType::U8);
  82. setValue(obj, &val, arrayIdx);
  83. }
  84. UINT8 SerializableFieldInfo::getU8(MonoObject* obj, UINT32 arrayIdx)
  85. {
  86. assert(mType == ScriptFieldType::U8);
  87. return *(UINT8*)getValue(obj, arrayIdx);
  88. }
  89. void SerializableFieldInfo::setI8(MonoObject* obj, INT8 val, UINT32 arrayIdx)
  90. {
  91. assert(mType == ScriptFieldType::I8);
  92. setValue(obj, &val, arrayIdx);
  93. }
  94. INT8 SerializableFieldInfo::getI8(MonoObject* obj, UINT32 arrayIdx)
  95. {
  96. assert(mType == ScriptFieldType::I8);
  97. return *(INT8*)getValue(obj, arrayIdx);
  98. }
  99. void SerializableFieldInfo::setU16(MonoObject* obj, UINT16 val, UINT32 arrayIdx)
  100. {
  101. assert(mType == ScriptFieldType::U16);
  102. setValue(obj, &val, arrayIdx);
  103. }
  104. UINT16 SerializableFieldInfo::getU16(MonoObject* obj, UINT32 arrayIdx)
  105. {
  106. assert(mType == ScriptFieldType::U16);
  107. return *(UINT16*)getValue(obj, arrayIdx);
  108. }
  109. void SerializableFieldInfo::setI16(MonoObject* obj, INT16 val, UINT32 arrayIdx)
  110. {
  111. assert(mType == ScriptFieldType::I16);
  112. setValue(obj, &val, arrayIdx);
  113. }
  114. INT16 SerializableFieldInfo::getI16(MonoObject* obj, UINT32 arrayIdx)
  115. {
  116. assert(mType == ScriptFieldType::I16);
  117. return *(INT16*)getValue(obj, arrayIdx);
  118. }
  119. void SerializableFieldInfo::setU32(MonoObject* obj, UINT32 val, UINT32 arrayIdx)
  120. {
  121. assert(mType == ScriptFieldType::U32);
  122. setValue(obj, &val, arrayIdx);
  123. }
  124. UINT32 SerializableFieldInfo::getU32(MonoObject* obj, UINT32 arrayIdx)
  125. {
  126. assert(mType == ScriptFieldType::U32);
  127. return *(UINT32*)getValue(obj, arrayIdx);
  128. }
  129. void SerializableFieldInfo::setI32(MonoObject* obj, INT32 val, UINT32 arrayIdx)
  130. {
  131. assert(mType == ScriptFieldType::I32);
  132. setValue(obj, &val, arrayIdx);
  133. }
  134. INT32 SerializableFieldInfo::getI32(MonoObject* obj, UINT32 arrayIdx)
  135. {
  136. assert(mType == ScriptFieldType::I32);
  137. return *(INT32*)getValue(obj, arrayIdx);
  138. }
  139. void SerializableFieldInfo::setU64(MonoObject* obj, UINT64 val, UINT32 arrayIdx)
  140. {
  141. assert(mType == ScriptFieldType::U64);
  142. setValue(obj, &val, arrayIdx);
  143. }
  144. UINT64 SerializableFieldInfo::getU64(MonoObject* obj, UINT32 arrayIdx)
  145. {
  146. assert(mType == ScriptFieldType::U64);
  147. return *(UINT64*)getValue(obj, arrayIdx);
  148. }
  149. void SerializableFieldInfo::setI64(MonoObject* obj, INT64 val, UINT32 arrayIdx)
  150. {
  151. assert(mType == ScriptFieldType::I64);
  152. setValue(obj, &val, arrayIdx);
  153. }
  154. INT64 SerializableFieldInfo::getI64(MonoObject* obj, UINT32 arrayIdx)
  155. {
  156. assert(mType == ScriptFieldType::I64);
  157. return *(INT64*)getValue(obj, arrayIdx);
  158. }
  159. void SerializableFieldInfo::setBool(MonoObject* obj, bool val, UINT32 arrayIdx)
  160. {
  161. assert(mType == ScriptFieldType::Bool);
  162. setValue(obj, &val, arrayIdx);
  163. }
  164. bool SerializableFieldInfo::getBool(MonoObject* obj, UINT32 arrayIdx)
  165. {
  166. assert(mType == ScriptFieldType::Bool);
  167. return *(bool*)getValue(obj, arrayIdx);
  168. }
  169. void SerializableFieldInfo::setChar(MonoObject* obj, wchar_t val, UINT32 arrayIdx)
  170. {
  171. assert(mType == ScriptFieldType::Char);
  172. setValue(obj, &val, arrayIdx);
  173. }
  174. wchar_t SerializableFieldInfo::getChar(MonoObject* obj, UINT32 arrayIdx)
  175. {
  176. assert(mType == ScriptFieldType::Char);
  177. return *(wchar_t*)getValue(obj, arrayIdx);
  178. }
  179. void SerializableFieldInfo::setFloat(MonoObject* obj, float val, UINT32 arrayIdx)
  180. {
  181. assert(mType == ScriptFieldType::Float);
  182. setValue(obj, &val, arrayIdx);
  183. }
  184. float SerializableFieldInfo::getFloat(MonoObject* obj, UINT32 arrayIdx)
  185. {
  186. assert(mType == ScriptFieldType::Float);
  187. return *(float*)getValue(obj, arrayIdx);
  188. }
  189. void SerializableFieldInfo::setDouble(MonoObject* obj, double val, UINT32 arrayIdx)
  190. {
  191. assert(mType == ScriptFieldType::Double);
  192. setValue(obj, &val, arrayIdx);
  193. }
  194. double SerializableFieldInfo::getDouble(MonoObject* obj, UINT32 arrayIdx)
  195. {
  196. assert(mType == ScriptFieldType::Double);
  197. return *(double*)getValue(obj, arrayIdx);
  198. }
  199. void SerializableFieldInfo::setString(MonoObject* obj, const WString& val, UINT32 arrayIdx)
  200. {
  201. assert(mType == ScriptFieldType::String);
  202. MonoString* str = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), val);
  203. setValue(obj, str, arrayIdx);
  204. }
  205. WString SerializableFieldInfo::getString(MonoObject* obj, UINT32 arrayIdx)
  206. {
  207. assert(mType == ScriptFieldType::String);
  208. MonoString* str = (MonoString*)getValue(obj, arrayIdx);
  209. if(str == nullptr)
  210. return L"";
  211. return MonoUtil::monoToWString(str);
  212. }
  213. void SerializableFieldInfo::setTexture(MonoObject* obj, const HTexture& resource, UINT32 arrayIdx)
  214. {
  215. assert(mType == ScriptFieldType::TextureRef);
  216. if(resource == nullptr)
  217. {
  218. setValue(obj, nullptr, arrayIdx);
  219. }
  220. else
  221. {
  222. ScriptTexture2D* scriptResource = ScriptResourceManager::instance().getScriptTexture(resource);
  223. if(scriptResource == nullptr)
  224. scriptResource = ScriptResourceManager::instance().createScriptTexture(resource);
  225. MonoObject* managedInstance = scriptResource->getManagedInstance();
  226. setValue(obj, (void*)managedInstance, arrayIdx);
  227. }
  228. }
  229. CM::HTexture SerializableFieldInfo::getTexture(MonoObject* obj, UINT32 arrayIdx)
  230. {
  231. assert(mType == ScriptFieldType::TextureRef);
  232. MonoObject* managedInstance = (MonoObject*)getValue(obj, arrayIdx);
  233. if(managedInstance == nullptr)
  234. return HTexture();
  235. ScriptTexture2D* scriptResource = ScriptTexture2D::toNative(managedInstance);
  236. return static_resource_cast<Texture>(scriptResource->getNativeHandle());
  237. }
  238. void SerializableFieldInfo::setSpriteTexture(MonoObject* obj, const HSpriteTexture& resource, UINT32 arrayIdx)
  239. {
  240. if(resource == nullptr)
  241. {
  242. setValue(obj, nullptr, arrayIdx);
  243. }
  244. else
  245. {
  246. assert(mType == ScriptFieldType::SpriteTextureRef);
  247. ScriptSpriteTexture* scriptResource = ScriptResourceManager::instance().getScriptSpriteTexture(resource);
  248. if(scriptResource == nullptr)
  249. scriptResource = ScriptResourceManager::instance().createScriptSpriteTexture(resource);
  250. MonoObject* managedInstance = scriptResource->getManagedInstance();
  251. setValue(obj, (void*)managedInstance, arrayIdx);
  252. }
  253. }
  254. HSpriteTexture SerializableFieldInfo::getSpriteTexture(MonoObject* obj, UINT32 arrayIdx)
  255. {
  256. assert(mType == ScriptFieldType::SpriteTextureRef);
  257. MonoObject* managedInstance = (MonoObject*)getValue(obj, arrayIdx);
  258. if(managedInstance == nullptr)
  259. return HTexture();
  260. ScriptSpriteTexture* scriptResource = ScriptSpriteTexture::toNative(managedInstance);
  261. return static_resource_cast<SpriteTexture>(scriptResource->getNativeHandle());
  262. }
  263. void SerializableFieldInfo::setSceneObject(MonoObject* obj, const HSceneObject& sceneObject, UINT32 arrayIdx)
  264. {
  265. assert(mType == ScriptFieldType::SceneObjectRef);
  266. // TODO
  267. }
  268. HSceneObject SerializableFieldInfo::getSceneObject(MonoObject* obj, UINT32 arrayIdx)
  269. {
  270. assert(mType == ScriptFieldType::SceneObjectRef);
  271. // TODO
  272. return HSceneObject();
  273. }
  274. void SerializableFieldInfo::setComponent(MonoObject* obj, const HComponent& component, UINT32 arrayIdx)
  275. {
  276. assert(mType == ScriptFieldType::ComponentRef);
  277. // TODO
  278. }
  279. HComponent SerializableFieldInfo::getComponent(MonoObject* obj, UINT32 arrayIdx)
  280. {
  281. assert(mType == ScriptFieldType::ComponentRef);
  282. // TODO
  283. return HComponent();
  284. }
  285. void SerializableFieldInfo::setSerializableObject(MonoObject* obj, const MonoObject* value, UINT32 arrayIdx)
  286. {
  287. assert(mType == ScriptFieldType::SerializableObjectRef || mType == ScriptFieldType::SerializableObjectValue);
  288. setValue(obj, (void*)value, arrayIdx);
  289. }
  290. MonoObject* SerializableFieldInfo::getSerializableObject(MonoObject* obj, UINT32 arrayIdx)
  291. {
  292. assert(mType == ScriptFieldType::SerializableObjectRef || mType == ScriptFieldType::SerializableObjectValue);
  293. return (MonoObject*)getValue(obj, arrayIdx);
  294. }
  295. void SerializableFieldInfo::setValue(MonoObject* obj, void* val, CM::UINT32 arrayIdx)
  296. {
  297. if(isArray())
  298. {
  299. MonoArray* array = (MonoArray*)mMonoField->getValue(obj);
  300. UINT32 elemSize = mono_array_element_size(mMonoField->getType()->_getInternalClass());
  301. UINT32 numElems = (UINT32)mono_array_length(array);
  302. assert(arrayIdx < numElems);
  303. void* elemAddr = mono_array_addr_with_size(array, elemSize, arrayIdx);
  304. memcpy(elemAddr, val, elemSize);
  305. }
  306. else
  307. {
  308. assert(arrayIdx == 0);
  309. mMonoField->setValue(obj, val);
  310. }
  311. }
  312. void* SerializableFieldInfo::getValue(MonoObject* obj, CM::UINT32 arrayIdx)
  313. {
  314. if(isArray())
  315. {
  316. MonoArray* array = (MonoArray*)mMonoField->getValue(obj);
  317. UINT32 elemSize = mono_array_element_size(mMonoField->getType()->_getInternalClass());
  318. UINT32 numElems = (UINT32)mono_array_length(array);
  319. assert(arrayIdx < numElems);
  320. return mono_array_addr_with_size(array, elemSize, arrayIdx);
  321. }
  322. else
  323. {
  324. assert(arrayIdx == 0);
  325. return mMonoField->getValue(obj);
  326. }
  327. }
  328. RuntimeScriptObjects::~RuntimeScriptObjects()
  329. {
  330. }
  331. void RuntimeScriptObjects::refreshScriptObjects(const String& assemblyName)
  332. {
  333. clearScriptObjects(assemblyName);
  334. // Get necessary classes for detecting needed class & field information
  335. MonoAssembly* mscorlib = MonoManager::instance().getAssembly("mscorlib");
  336. if(mscorlib == nullptr)
  337. CM_EXCEPT(InvalidStateException, "mscorlib assembly is not loaded.");
  338. MonoAssembly* bansheeEngineAssembly = MonoManager::instance().getAssembly(BansheeEngineAssemblyName);
  339. if(bansheeEngineAssembly == nullptr)
  340. CM_EXCEPT(InvalidStateException, String(BansheeEngineAssemblyName) + " assembly is not loaded.");
  341. MonoClass* serializableAttribute = mscorlib->getClass("System", "SerializableAttribute");
  342. if(serializableAttribute == nullptr)
  343. CM_EXCEPT(InvalidStateException, "Cannot find SerializableAttribute managed class.");
  344. MonoClass* nonSerializedAttribute = mscorlib->getClass("System", "NonSerializedAttribute");
  345. if(nonSerializedAttribute == nullptr)
  346. CM_EXCEPT(InvalidStateException, "Cannot find NonSerializedAttribute managed class.");
  347. MonoClass* genericListClass = mscorlib->getClass("System", "List`1");
  348. if(genericListClass == nullptr)
  349. CM_EXCEPT(InvalidStateException, "Cannot find List<T> managed class.");
  350. MonoClass* componentClass = bansheeEngineAssembly->getClass("BansheeEngine", "Component");
  351. if(componentClass == nullptr)
  352. CM_EXCEPT(InvalidStateException, "Cannot find Component managed class.");
  353. MonoClass* sceneObjectClass = bansheeEngineAssembly->getClass("BansheeEngine", "SceneObject");
  354. if(sceneObjectClass == nullptr)
  355. CM_EXCEPT(InvalidStateException, "Cannot find SceneObject managed class.");
  356. MonoClass* textureClass = bansheeEngineAssembly->getClass("BansheeEngine", "Texture2D");
  357. if(textureClass == nullptr)
  358. CM_EXCEPT(InvalidStateException, "Cannot find Texture2D managed class.");
  359. MonoClass* spriteTextureClass = bansheeEngineAssembly->getClass("BansheeEngine", "SpriteTexture");
  360. if(spriteTextureClass == nullptr)
  361. CM_EXCEPT(InvalidStateException, "Cannot find SpriteTexture managed class.");
  362. MonoClass* serializeFieldAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "SerializeField");
  363. if(serializeFieldAttribute == nullptr)
  364. CM_EXCEPT(InvalidStateException, "Cannot find SerializeField managed class.");
  365. MonoClass* hideInInspectorAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "HideInInspector");
  366. if(hideInInspectorAttribute == nullptr)
  367. CM_EXCEPT(InvalidStateException, "Cannot find HideInInspector managed class.");
  368. // Process all classes and fields
  369. CM::UINT32 mUniqueTypeId = 1;
  370. MonoAssembly* curAssembly = MonoManager::instance().getAssembly(assemblyName);
  371. if(curAssembly == nullptr)
  372. return;
  373. std::shared_ptr<SerializableAssemblyInfo> assemblyInfo = cm_shared_ptr<SerializableAssemblyInfo>();
  374. mAssemblyInfos[assemblyName] = assemblyInfo;
  375. // Populate class data
  376. const Vector<MonoClass*>::type& allClasses = curAssembly->getAllClasses();
  377. for(auto& curClass : allClasses)
  378. {
  379. if((curClass->isSubClassOf(componentClass) || curClass->hasAttribute(serializableAttribute)) && curClass != componentClass)
  380. {
  381. std::shared_ptr<SerializableObjectInfo> objInfo = cm_shared_ptr<SerializableObjectInfo>();
  382. objInfo->mTypeId = mUniqueTypeId++;
  383. objInfo->mTypeName = curClass->getTypeName();
  384. objInfo->mNamespace = curClass->getNamespace();
  385. objInfo->mMonoClass = curClass;
  386. String fullTypeName = objInfo->mNamespace + "." + objInfo->mTypeName;
  387. assemblyInfo->mTypeNameToId[fullTypeName] = objInfo->mTypeId;
  388. assemblyInfo->mObjectInfos[objInfo->mTypeId] = objInfo;
  389. }
  390. }
  391. // Populate field data
  392. for(auto& curClassInfo : assemblyInfo->mObjectInfos)
  393. {
  394. std::shared_ptr<SerializableObjectInfo> objInfo = curClassInfo.second;
  395. String fullTypeName = objInfo->mNamespace + "." + objInfo->mTypeName;
  396. assemblyInfo->mTypeNameToId[fullTypeName] = objInfo->mTypeId;
  397. assemblyInfo->mObjectInfos[objInfo->mTypeId] = objInfo;
  398. CM::UINT32 mUniqueFieldId = 1;
  399. const CM::Vector<MonoField*>::type& fields = objInfo->mMonoClass->getAllFields();
  400. for(auto& field : fields)
  401. {
  402. if(field->isStatic())
  403. continue;
  404. SerializableFieldInfo* fieldInfo = cm_new<SerializableFieldInfo>();
  405. fieldInfo->mFieldId = mUniqueFieldId++;
  406. fieldInfo->mMonoField = field;
  407. fieldInfo->mName = field->getName();
  408. MonoClass* fieldType = field->getType();
  409. fieldInfo->mTypeNamespace = fieldType->getNamespace();
  410. fieldInfo->mTypeName = fieldType->getTypeName();
  411. MonoClass* fieldElementClass = fieldType;
  412. MonoType* monoType = mono_class_get_type(fieldType->_getInternalClass());
  413. int monoPrimitiveType = mono_type_get_type(monoType);
  414. // TODO - We don't support nested arrays or multi-dimensional arrays
  415. bool isSupportedType = true;
  416. if(monoPrimitiveType == MONO_TYPE_ARRAY)
  417. {
  418. ::MonoClass* elementClass = mono_class_get_element_class(fieldType->_getInternalClass());
  419. if(elementClass != nullptr)
  420. {
  421. monoType = mono_class_get_type(elementClass);
  422. monoPrimitiveType = mono_type_get_type(monoType);
  423. ::MonoClass* elementClass = mono_type_get_class(monoType);
  424. String elementNs = mono_class_get_namespace(elementClass);
  425. String elementTypeName = mono_class_get_name(elementClass);
  426. fieldElementClass = MonoManager::instance().findClass(elementNs, elementTypeName);
  427. }
  428. fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Array);
  429. }
  430. // TODO - Also check for List and get its generic primitive
  431. // Determine field type
  432. switch(monoPrimitiveType) // TODO - If array I need to get underlying type
  433. {
  434. case MONO_TYPE_BOOLEAN:
  435. fieldInfo->mType = ScriptFieldType::Bool;
  436. break;
  437. case MONO_TYPE_CHAR:
  438. fieldInfo->mType = ScriptFieldType::Char;
  439. break;
  440. case MONO_TYPE_I1:
  441. fieldInfo->mType = ScriptFieldType::I8;
  442. break;
  443. case MONO_TYPE_U1:
  444. fieldInfo->mType = ScriptFieldType::U8;
  445. break;
  446. case MONO_TYPE_I2:
  447. fieldInfo->mType = ScriptFieldType::I16;
  448. break;
  449. case MONO_TYPE_U2:
  450. fieldInfo->mType = ScriptFieldType::U16;
  451. break;
  452. case MONO_TYPE_I4:
  453. fieldInfo->mType = ScriptFieldType::I32;
  454. break;
  455. case MONO_TYPE_U4:
  456. fieldInfo->mType = ScriptFieldType::U32;
  457. break;
  458. case MONO_TYPE_I8:
  459. fieldInfo->mType = ScriptFieldType::U64;
  460. break;
  461. case MONO_TYPE_U8:
  462. fieldInfo->mType = ScriptFieldType::U64;
  463. break;
  464. case MONO_TYPE_STRING:
  465. fieldInfo->mType = ScriptFieldType::String;
  466. break;
  467. case MONO_TYPE_R4:
  468. fieldInfo->mType = ScriptFieldType::Float;
  469. break;
  470. case MONO_TYPE_R8:
  471. fieldInfo->mType = ScriptFieldType::Double;
  472. break;
  473. case MONO_TYPE_CLASS:
  474. if(fieldElementClass->isSubClassOf(textureClass))
  475. fieldInfo->mType = ScriptFieldType::TextureRef;
  476. else if(fieldElementClass->isSubClassOf(spriteTextureClass))
  477. fieldInfo->mType = ScriptFieldType::SpriteTextureRef;
  478. else if(fieldElementClass->isSubClassOf(sceneObjectClass))
  479. fieldInfo->mType = ScriptFieldType::SceneObjectRef;
  480. else if(fieldElementClass->isSubClassOf(componentClass))
  481. fieldInfo->mType = ScriptFieldType::ComponentRef;
  482. else
  483. {
  484. if(hasSerializableObjectInfo(fieldElementClass->getNamespace(), fieldElementClass->getTypeName()))
  485. fieldInfo->mType = ScriptFieldType::SerializableObjectRef;
  486. }
  487. break;
  488. case MONO_TYPE_VALUETYPE:
  489. if(hasSerializableObjectInfo(fieldElementClass->getNamespace(), fieldElementClass->getTypeName()))
  490. fieldInfo->mType = ScriptFieldType::SerializableObjectValue;
  491. break;
  492. }
  493. if(fieldInfo->mType != ScriptFieldType::Other)
  494. {
  495. MonoFieldVisibility visibility = field->getVisibility();
  496. if(visibility == MonoFieldVisibility::Public)
  497. {
  498. if(!field->hasAttribute(nonSerializedAttribute))
  499. fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
  500. if(!field->hasAttribute(hideInInspectorAttribute))
  501. fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Inspectable);
  502. }
  503. else
  504. {
  505. if(field->hasAttribute(serializeFieldAttribute))
  506. fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
  507. }
  508. }
  509. objInfo->mFieldNameToId[fieldInfo->mName] = fieldInfo->mFieldId;
  510. objInfo->mFields[fieldInfo->mFieldId] = fieldInfo;
  511. }
  512. }
  513. // Form parent/child connections
  514. for(auto& curClass : assemblyInfo->mObjectInfos)
  515. {
  516. MonoClass* base = curClass.second->mMonoClass->getBaseClass();
  517. while(base != nullptr)
  518. {
  519. std::shared_ptr<SerializableObjectInfo> baseObjInfo;
  520. if(getSerializableObjectInfo(base->getNamespace(), base->getTypeName(), baseObjInfo))
  521. {
  522. curClass.second->mBaseClass = baseObjInfo;
  523. baseObjInfo->mDerivedClasses.push_back(curClass.second);
  524. break;
  525. }
  526. base = base->getBaseClass();
  527. }
  528. }
  529. }
  530. void RuntimeScriptObjects::clearScriptObjects(const CM::String& assemblyName)
  531. {
  532. mAssemblyInfos.erase(assemblyName);
  533. }
  534. bool RuntimeScriptObjects::getSerializableObjectInfo(const CM::String& ns, const CM::String& typeName, std::shared_ptr<SerializableObjectInfo>& outInfo)
  535. {
  536. String fullName = ns + "." + typeName;
  537. for(auto& curAssembly : mAssemblyInfos)
  538. {
  539. auto iterFind = curAssembly.second->mTypeNameToId.find(fullName);
  540. if(iterFind != curAssembly.second->mTypeNameToId.end())
  541. {
  542. outInfo = curAssembly.second->mObjectInfos[iterFind->second];
  543. return true;
  544. }
  545. }
  546. return false;
  547. }
  548. bool RuntimeScriptObjects::hasSerializableObjectInfo(const CM::String& ns, const CM::String& typeName)
  549. {
  550. String fullName = ns + "." + typeName;
  551. for(auto& curAssembly : mAssemblyInfos)
  552. {
  553. auto iterFind = curAssembly.second->mTypeNameToId.find(fullName);
  554. if(iterFind != curAssembly.second->mTypeNameToId.end())
  555. return true;
  556. }
  557. return false;
  558. }
  559. }