BsScriptSerializableUtility.cpp 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include "BsScriptSerializableUtility.h"
  2. #include "BsMonoManager.h"
  3. #include "BsMonoClass.h"
  4. #include "BsMonoMethod.h"
  5. #include "BsMonoUtil.h"
  6. #include "BsScriptAssemblyManager.h"
  7. #include "BsManagedSerializableField.h"
  8. #include "BsMemorySerializer.h"
  9. namespace BansheeEngine
  10. {
  11. ScriptSerializableUtility::ScriptSerializableUtility(MonoObject* instance)
  12. :ScriptObject(instance)
  13. { }
  14. void ScriptSerializableUtility::initRuntimeData()
  15. {
  16. metaData.scriptClass->addInternalCall("Internal_Clone", &ScriptSerializableUtility::internal_Clone);
  17. metaData.scriptClass->addInternalCall("Internal_Create", &ScriptSerializableUtility::internal_Create);
  18. }
  19. MonoObject* ScriptSerializableUtility::internal_Clone(MonoObject* original)
  20. {
  21. if (original == nullptr)
  22. return nullptr;
  23. ::MonoClass* monoClass = mono_object_get_class(original);
  24. MonoClass* engineClass = MonoManager::instance().findClass(monoClass);
  25. ManagedSerializableTypeInfoPtr typeInfo = ScriptAssemblyManager::instance().getTypeInfo(engineClass);
  26. if (typeInfo == nullptr)
  27. {
  28. LOGWRN("Cannot clone an instance of type \"" +
  29. engineClass->getFullName() + "\", it is not marked as serializable.");
  30. return nullptr;
  31. }
  32. ManagedSerializableFieldDataPtr data = ManagedSerializableFieldData::create(typeInfo, original);
  33. MemorySerializer ms;
  34. // Note: This code unnecessarily encodes to binary and decodes from it. I could have added a specialized clone method that does it directly,
  35. // but didn't feel the extra code was justified.
  36. UINT32 size = 0;
  37. UINT8* encodedData = ms.encode(data.get(), size);
  38. ManagedSerializableFieldDataPtr clonedData = std::static_pointer_cast<ManagedSerializableFieldData>(ms.decode(encodedData, size));
  39. clonedData->deserialize();
  40. return clonedData->getValueBoxed(typeInfo);
  41. }
  42. MonoObject* ScriptSerializableUtility::internal_Create(MonoReflectionType* reflType)
  43. {
  44. if (reflType == nullptr)
  45. return nullptr;
  46. MonoType* type = mono_reflection_type_get_type(reflType);
  47. ::MonoClass* monoClass = mono_type_get_class(type);
  48. MonoClass* engineClass = MonoManager::instance().findClass(monoClass);
  49. ManagedSerializableTypeInfoPtr typeInfo = ScriptAssemblyManager::instance().getTypeInfo(engineClass);
  50. if (typeInfo == nullptr)
  51. {
  52. LOGWRN("Cannot create an instance of type \"" +
  53. engineClass->getFullName() + "\", it is not marked as serializable.");
  54. return nullptr;
  55. }
  56. ManagedSerializableFieldDataPtr data = ManagedSerializableFieldData::createDefault(typeInfo);
  57. MemorySerializer ms;
  58. // Note: This code unnecessarily encodes to binary and decodes from it. I could have added a specialized create method that does it directly,
  59. // but didn't feel the extra code was justified.
  60. UINT32 size = 0;
  61. UINT8* encodedData = ms.encode(data.get(), size);
  62. ManagedSerializableFieldDataPtr createdData = std::static_pointer_cast<ManagedSerializableFieldData>(ms.decode(encodedData, size));
  63. createdData->deserialize();
  64. return createdData->getValueBoxed(typeInfo);
  65. }
  66. }