BsScriptSerializableObject.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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 SPtr<ManagedSerializableTypeInfo>& 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. MonoReflectionType* internalElementType = MonoUtil::getType(property->getTypeInfo()->getMonoClass());
  27. void* params[2] = { internalElementType, property->getManagedInstance() };
  28. MonoObject* managedInstance = metaData.scriptClass->createInstance(params, 2);
  29. // Managed constructor will call back to native which will create ScriptSerializableObject instance,
  30. // and we can now just retrieve it.
  31. return ScriptSerializableObject::toNative(managedInstance);
  32. }
  33. void ScriptSerializableObject::internal_createInstance(MonoObject* instance, MonoReflectionType* type)
  34. {
  35. ::MonoClass* monoClass = MonoUtil::getClass(type);
  36. String elementNs;
  37. String elementTypeName;
  38. MonoUtil::getClassName(monoClass, elementNs, elementTypeName);
  39. SPtr<ManagedSerializableObjectInfo> objInfo;
  40. ScriptAssemblyManager::instance().getSerializableObjectInfo(elementNs, elementTypeName, objInfo);
  41. createInternal(instance, objInfo);
  42. }
  43. ScriptSerializableObject* ScriptSerializableObject::createInternal(MonoObject* instance, const SPtr<ManagedSerializableObjectInfo>& objInfo)
  44. {
  45. SPtr<ManagedSerializableTypeInfo> typeInfo;
  46. if(objInfo != nullptr)
  47. typeInfo = objInfo->mTypeInfo;
  48. ScriptSerializableObject* nativeInstance = new (bs_alloc<ScriptSerializableObject>()) ScriptSerializableObject(instance, typeInfo);
  49. Vector<SPtr<ManagedSerializableMemberInfo>> sortedFields;
  50. if(objInfo != nullptr)
  51. {
  52. sortedFields.resize(objInfo->mFields.size());
  53. UINT32 i = 0;
  54. for (auto& fieldPair : objInfo->mFields)
  55. {
  56. sortedFields[i] = fieldPair.second;
  57. i++;
  58. }
  59. }
  60. std::sort(sortedFields.begin(), sortedFields.end(),
  61. [&](const SPtr<ManagedSerializableMemberInfo>& x, const SPtr<ManagedSerializableMemberInfo>& y)
  62. {
  63. return x->mFieldId < y->mFieldId;
  64. });
  65. ::MonoClass* serializableFieldClass = ScriptSerializableField::getMetaData()->scriptClass->_getInternalClass();
  66. ScriptArray scriptArray(serializableFieldClass, (UINT32)sortedFields.size());
  67. UINT32 i = 0;
  68. for (auto& field : sortedFields)
  69. {
  70. ScriptSerializableField* serializableField = ScriptSerializableField::create(instance, field);
  71. MonoObject* fieldManagedInstance = serializableField->getManagedInstance();
  72. scriptArray.set(i, fieldManagedInstance);
  73. i++;
  74. }
  75. FieldsField->setValue(instance, scriptArray.getInternal());
  76. return nativeInstance;
  77. }
  78. }