BsScriptSerializableObject.cpp 3.9 KB

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