2
0

BsManagedSerializableObject.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #include "BsManagedSerializableObject.h"
  2. #include "BsManagedSerializableObjectRTTI.h"
  3. #include "BsManagedSerializableObjectInfo.h"
  4. #include "BsManagedSerializableField.h"
  5. #include "BsRuntimeScriptObjects.h"
  6. #include "BsMonoField.h"
  7. namespace BansheeEngine
  8. {
  9. ManagedSerializableObject::ManagedSerializableObject(const ConstructPrivately& dummy)
  10. :mManagedInstance(nullptr)
  11. {
  12. }
  13. ManagedSerializableObject::ManagedSerializableObject(const ConstructPrivately& dummy, ManagedSerializableObjectInfoPtr objInfo, MonoObject* managedInstance)
  14. :mObjInfo(objInfo), mManagedInstance(managedInstance)
  15. {
  16. }
  17. ManagedSerializableObjectPtr ManagedSerializableObject::createFromExisting(MonoObject* managedInstance)
  18. {
  19. if(managedInstance == nullptr)
  20. return nullptr;
  21. ::MonoClass* monoClass = mono_object_get_class(managedInstance);
  22. String elementNs = mono_class_get_namespace(monoClass);
  23. String elementTypeName = mono_class_get_name(monoClass);
  24. ManagedSerializableObjectInfoPtr objInfo;
  25. if(!RuntimeScriptObjects::instance().getSerializableObjectInfo(elementNs, elementTypeName, objInfo))
  26. return nullptr;
  27. return bs_shared_ptr<ManagedSerializableObject>(ConstructPrivately(), objInfo, managedInstance);
  28. }
  29. ManagedSerializableObjectPtr ManagedSerializableObject::createFromNew(const ManagedSerializableTypeInfoObjectPtr& type)
  30. {
  31. ManagedSerializableObjectInfoPtr currentObjInfo = nullptr;
  32. // See if this type even still exists
  33. if (!RuntimeScriptObjects::instance().getSerializableObjectInfo(type->mTypeNamespace, type->mTypeName, currentObjInfo))
  34. return nullptr;
  35. return bs_shared_ptr<ManagedSerializableObject>(ConstructPrivately(), currentObjInfo, createManagedInstance(type));
  36. }
  37. MonoObject* ManagedSerializableObject::createManagedInstance(const ManagedSerializableTypeInfoObjectPtr& type)
  38. {
  39. ManagedSerializableObjectInfoPtr currentObjInfo = nullptr;
  40. // See if this type even still exists
  41. if (!RuntimeScriptObjects::instance().getSerializableObjectInfo(type->mTypeNamespace, type->mTypeName, currentObjInfo))
  42. return nullptr;
  43. if (type->mValueType)
  44. return currentObjInfo->mMonoClass->createInstance(false);
  45. else
  46. return currentObjInfo->mMonoClass->createInstance();
  47. }
  48. ManagedSerializableObjectPtr ManagedSerializableObject::createEmpty()
  49. {
  50. return bs_shared_ptr<ManagedSerializableObject>(ConstructPrivately());
  51. }
  52. void ManagedSerializableObject::serializeManagedInstance()
  53. {
  54. ManagedSerializableObjectInfoPtr curType = mObjInfo;
  55. UINT32 numFields = 0;
  56. while(curType != nullptr)
  57. {
  58. for(auto& field : mObjInfo->mFields)
  59. {
  60. if(field.second->isSerializable())
  61. numFields++;
  62. }
  63. curType = curType->mBaseClass;
  64. }
  65. mFieldEntries.resize(numFields);
  66. curType = mObjInfo;
  67. UINT32 curIdx = 0;
  68. while(curType != nullptr)
  69. {
  70. for(auto& field : mObjInfo->mFields)
  71. {
  72. if(!field.second->isSerializable())
  73. continue;
  74. ManagedSerializableFieldKeyPtr fieldKey = ManagedSerializableFieldKey::create(curType->mTypeId, field.second->mFieldId);
  75. ManagedSerializableFieldDataPtr fieldData = getFieldData(field.second);
  76. mFieldEntries[curIdx] = ManagedSerializableFieldDataEntry::create(fieldKey, fieldData);
  77. curIdx++;
  78. }
  79. curType = curType->mBaseClass;
  80. }
  81. }
  82. void ManagedSerializableObject::deserializeManagedInstance()
  83. {
  84. ManagedSerializableObjectInfoPtr storedObjInfo = mObjInfo;
  85. ManagedSerializableObjectInfoPtr currentObjInfo = nullptr;
  86. // See if this type even still exists
  87. if(!RuntimeScriptObjects::instance().getSerializableObjectInfo(storedObjInfo->mTypeInfo->mTypeNamespace, storedObjInfo->mTypeInfo->mTypeName, currentObjInfo))
  88. return;
  89. mManagedInstance = createManagedInstance(storedObjInfo->mTypeInfo);
  90. if (mManagedInstance == nullptr)
  91. return;
  92. auto findFieldInfoFromKey = [&] (UINT16 typeId, UINT16 fieldId, ManagedSerializableObjectInfoPtr objInfo,
  93. ManagedSerializableFieldInfoPtr& outFieldInfo, ManagedSerializableObjectInfoPtr &outObjInfo) -> bool
  94. {
  95. while(objInfo != nullptr)
  96. {
  97. if(objInfo->mTypeId == typeId)
  98. {
  99. auto iterFind = objInfo->mFields.find(fieldId);
  100. if(iterFind != objInfo->mFields.end())
  101. {
  102. outFieldInfo = iterFind->second;
  103. outObjInfo = objInfo;
  104. return true;
  105. }
  106. return false;
  107. }
  108. objInfo = objInfo->mBaseClass;
  109. }
  110. return false;
  111. };
  112. auto findTypeNameMatchingFieldInfo = [&] (const ManagedSerializableFieldInfoPtr& fieldInfo, const ManagedSerializableObjectInfoPtr& fieldObjInfo,
  113. ManagedSerializableObjectInfoPtr objInfo) -> ManagedSerializableFieldInfoPtr
  114. {
  115. while(objInfo != nullptr)
  116. {
  117. if(objInfo->mTypeInfo->matches(fieldObjInfo->mTypeInfo))
  118. {
  119. auto iterFind = objInfo->mFieldNameToId.find(fieldInfo->mName);
  120. if(iterFind != objInfo->mFieldNameToId.end())
  121. {
  122. auto iterFind2 = objInfo->mFields.find(iterFind->second);
  123. if(iterFind2 != objInfo->mFields.end())
  124. {
  125. ManagedSerializableFieldInfoPtr foundField = iterFind2->second;
  126. if(foundField->isSerializable())
  127. {
  128. if(fieldInfo->mTypeInfo->matches(foundField->mTypeInfo))
  129. return foundField;
  130. }
  131. }
  132. }
  133. return nullptr;
  134. }
  135. objInfo = objInfo->mBaseClass;
  136. }
  137. return nullptr;
  138. };
  139. // Scan all fields and ensure the fields still exist
  140. for(auto& fieldEntry : mFieldEntries)
  141. {
  142. ManagedSerializableFieldInfoPtr storedFieldEntry;
  143. ManagedSerializableObjectInfoPtr storedFieldObjEntry;
  144. if(!findFieldInfoFromKey(fieldEntry->mKey->mTypeId, fieldEntry->mKey->mFieldId, storedObjInfo, storedFieldEntry, storedFieldObjEntry))
  145. continue;
  146. ManagedSerializableFieldInfoPtr matchingFieldInfo = findTypeNameMatchingFieldInfo(storedFieldEntry, storedFieldObjEntry, currentObjInfo);
  147. if(matchingFieldInfo != nullptr)
  148. setFieldData(matchingFieldInfo, fieldEntry->mValue);
  149. }
  150. }
  151. void ManagedSerializableObject::setFieldData(const ManagedSerializableFieldInfoPtr& fieldInfo, const ManagedSerializableFieldDataPtr& val)
  152. {
  153. fieldInfo->mMonoField->setValue(mManagedInstance, val->getValue(fieldInfo->mTypeInfo));
  154. }
  155. ManagedSerializableFieldDataPtr ManagedSerializableObject::getFieldData(const ManagedSerializableFieldInfoPtr& fieldInfo)
  156. {
  157. MonoObject* fieldValue = fieldInfo->mMonoField->getValueBoxed(mManagedInstance);
  158. return ManagedSerializableFieldData::create(fieldInfo->mTypeInfo, fieldValue);
  159. }
  160. RTTITypeBase* ManagedSerializableObject::getRTTIStatic()
  161. {
  162. return ManagedSerializableObjectRTTI::instance();
  163. }
  164. RTTITypeBase* ManagedSerializableObject::getRTTI() const
  165. {
  166. return ManagedSerializableObject::getRTTIStatic();
  167. }
  168. }