BsScriptSerializableObject.cpp 3.5 KB

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