BsScriptSerializableObject.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include "BsScriptSerializableObject.h"
  2. #include "BsScriptSerializableField.h"
  3. #include "BsScriptAssemblyManager.h"
  4. #include "BsScriptMeta.h"
  5. #include "BsMonoField.h"
  6. #include "BsMonoClass.h"
  7. #include "BsMonoManager.h"
  8. #include "BsMonoUtil.h"
  9. namespace BansheeEngine
  10. {
  11. MonoField* ScriptSerializableObject::FieldsField = nullptr;
  12. ScriptSerializableObject::ScriptSerializableObject(MonoObject* instance, const ManagedSerializableTypeInfoPtr& typeInfo)
  13. :ScriptObject(instance), mTypeInfo(typeInfo)
  14. {
  15. }
  16. void ScriptSerializableObject::initRuntimeData()
  17. {
  18. metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptSerializableObject::internal_createInstance);
  19. FieldsField = metaData.scriptClass->getField("_fields");
  20. }
  21. ScriptSerializableObject* ScriptSerializableObject::create(const ManagedSerializableTypeInfoPtr& typeInfo, MonoObject* object)
  22. {
  23. MonoType* monoInternalElementType = mono_class_get_type(typeInfo->getMonoClass());
  24. MonoReflectionType* internalElementType = mono_type_get_object(MonoManager::instance().getDomain(), monoInternalElementType);
  25. void* params[2] = { internalElementType, object };
  26. MonoObject* managedInstance = metaData.scriptClass->createInstance(params, 2);
  27. // Managed constructor will call back to native which will create ScriptSerializableObject instance,
  28. // and we can now just retrieve it.
  29. return ScriptSerializableObject::toNative(managedInstance);
  30. }
  31. void ScriptSerializableObject::internal_createInstance(MonoObject* instance, MonoReflectionType* type, MonoObject* object)
  32. {
  33. MonoType* internalType = mono_reflection_type_get_type(type);
  34. ::MonoClass* monoClass = mono_type_get_class(internalType);
  35. String elementNs;
  36. String elementTypeName;
  37. MonoUtil::getClassName(monoClass, elementNs, elementTypeName);
  38. ManagedSerializableObjectInfoPtr objInfo;
  39. ScriptAssemblyManager::instance().getSerializableObjectInfo(elementNs, elementTypeName, objInfo);
  40. createInternal(instance, objInfo);
  41. }
  42. ScriptSerializableObject* ScriptSerializableObject::createInternal(MonoObject* instance, const ManagedSerializableObjectInfoPtr& objInfo)
  43. {
  44. ManagedSerializableTypeInfoPtr typeInfo;
  45. if(objInfo != nullptr)
  46. typeInfo = objInfo->mTypeInfo;
  47. ScriptSerializableObject* nativeInstance = new (bs_alloc<ScriptSerializableObject>()) ScriptSerializableObject(instance, typeInfo);
  48. if(objInfo != nullptr)
  49. {
  50. ::MonoClass* serializableFieldClass = ScriptSerializableField::getMetaData()->scriptClass->_getInternalClass();
  51. MonoArray* serializableFieldArray = mono_array_new(MonoManager::instance().getDomain(),
  52. serializableFieldClass, (UINT32)objInfo->mFields.size());
  53. Vector<ManagedSerializableFieldInfoPtr> sortedFields((UINT32)objInfo->mFields.size());
  54. UINT32 i = 0;
  55. for (auto& fieldPair : objInfo->mFields)
  56. {
  57. sortedFields[i] = fieldPair.second;
  58. i++;
  59. }
  60. std::sort(sortedFields.begin(), sortedFields.end(),
  61. [&](const ManagedSerializableFieldInfoPtr& x, const ManagedSerializableFieldInfoPtr& y)
  62. {
  63. return x->mFieldId < y->mFieldId;
  64. });
  65. i = 0;
  66. for (auto& field : sortedFields)
  67. {
  68. ScriptSerializableField* serializableField = ScriptSerializableField::create(instance, field);
  69. MonoObject* fieldManagedInstance = serializableField->getManagedInstance();
  70. void* elemAddr = mono_array_addr_with_size(serializableFieldArray, sizeof(MonoObject*), i);
  71. memcpy(elemAddr, &fieldManagedInstance, sizeof(MonoObject*));
  72. i++;
  73. }
  74. FieldsField->setValue(instance, serializableFieldArray);
  75. }
  76. return nativeInstance;
  77. }
  78. }