BsScriptSerializableUtility.cpp 3.3 KB

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