ElementInformationSerializer.inl 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <AzCore/Memory/Memory.h>
  10. #include <AzCore/Serialization/AZStdAnyDataContainer.inl>
  11. #include <AzCore/Serialization/Json/BaseJsonSerializer.h>
  12. #include <AzCore/Serialization/Json/JsonSerialization.h>
  13. #include <AzCore/Serialization/SerializeContext.h>
  14. #include <ExpressionEvaluation/ExpressionEngine/ExpressionTypes.h>
  15. namespace AZ
  16. {
  17. class ElementInformationSerializer
  18. : public BaseJsonSerializer
  19. {
  20. public:
  21. AZ_RTTI(ElementInformationSerializer, "{B33E6AA9-C700-4E3D-857C-55F362AFE57A}", BaseJsonSerializer);
  22. AZ_CLASS_ALLOCATOR_DECL;
  23. private:
  24. using ElementInformation = ExpressionEvaluation::ElementInformation;
  25. static constexpr AZStd::string_view EmptyAnyIdentifier = "Empty AZStd::any";
  26. static bool IsEmptyAny(const rapidjson::Value& typeId)
  27. {
  28. if (typeId.IsString())
  29. {
  30. AZStd::string_view typeName(typeId.GetString(), typeId.GetStringLength());
  31. return typeName == EmptyAnyIdentifier;
  32. }
  33. return false;
  34. }
  35. JsonSerializationResult::Result Load
  36. ( void* outputValue
  37. , [[maybe_unused]] const Uuid& outputValueTypeId
  38. , const rapidjson::Value& inputValue
  39. , JsonDeserializerContext& context) override
  40. {
  41. namespace JSR = JsonSerializationResult;
  42. AZ_Assert(outputValueTypeId == azrtti_typeid<ElementInformation>(), "ElementInformationSerializer Load against "
  43. "output typeID that was not ElementInformation");
  44. AZ_Assert(outputValue, "ElementInformationSerializer Load against null output");
  45. JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField);
  46. auto outputDatum = reinterpret_cast<ElementInformation*>(outputValue);
  47. result.Combine(ContinueLoadingFromJsonObjectField
  48. ( &outputDatum->m_id
  49. , azrtti_typeid<decltype(outputDatum->m_id)>()
  50. , inputValue
  51. , "Id"
  52. , context));
  53. // any storage begin
  54. {
  55. AZ::Uuid typeId = AZ::Uuid::CreateNull();
  56. auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier);
  57. if (typeIdMember == inputValue.MemberEnd())
  58. {
  59. return context.Report
  60. ( JSR::Tasks::ReadField
  61. , JSR::Outcomes::Missing
  62. , AZStd::string::format("ElementInformationSerializer::Load failed to load the %s member"
  63. , JsonSerialization::TypeIdFieldIdentifier));
  64. }
  65. if (!IsEmptyAny(typeIdMember->value))
  66. {
  67. result.Combine(LoadTypeId(typeId, typeIdMember->value, context));
  68. if (typeId.IsNull())
  69. {
  70. return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic
  71. , "ElementInformationSerializer::Load failed to load the AZ TypeId of the value");
  72. }
  73. AZStd::any storage = context.GetSerializeContext()->CreateAny(typeId);
  74. if (storage.empty() || storage.type() != typeId)
  75. {
  76. return context.Report(result, "ElementInformationSerializer::Load failed to load a value matched the "
  77. "reported AZ TypeId. The C++ declaration may have been deleted or changed.");
  78. }
  79. result.Combine
  80. ( ContinueLoadingFromJsonObjectField(AZStd::any_cast<void>(&storage), typeId, inputValue, "Value", context));
  81. outputDatum->m_extraStore = storage;
  82. }
  83. }
  84. // any storage end
  85. return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
  86. ? "ElementInformationSerializer Load finished loading ElementInformation"
  87. : "ElementInformationSerializer Load failed to load ElementInformation");
  88. }
  89. JsonSerializationResult::Result Store
  90. ( rapidjson::Value& outputValue
  91. , const void* inputValue
  92. , const void* defaultValue
  93. , [[maybe_unused]] const Uuid& valueTypeId
  94. , JsonSerializerContext& context) override
  95. {
  96. namespace JSR = JsonSerializationResult;
  97. AZ_Assert(valueTypeId == azrtti_typeid<ElementInformation>(), "ElementInformation Store against value typeID that "
  98. "was not ElementInformation");
  99. AZ_Assert(inputValue, "ElementInformation Store against null inputValue pointer ");
  100. auto inputScriptDataPtr = reinterpret_cast<const ElementInformation*>(inputValue);
  101. auto defaultScriptDataPtr = reinterpret_cast<const ElementInformation*>(defaultValue);
  102. if (defaultScriptDataPtr)
  103. {
  104. if (inputScriptDataPtr->m_id == defaultScriptDataPtr->m_id
  105. && AZ::Helpers::CompareAnyValue(inputScriptDataPtr->m_extraStore, defaultScriptDataPtr->m_extraStore))
  106. {
  107. return context.Report
  108. ( JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "ElementInformation Store used defaults for "
  109. "ElementInformation");
  110. }
  111. }
  112. JSR::ResultCode result(JSR::Tasks::WriteValue);
  113. outputValue.SetObject();
  114. result.Combine(ContinueStoringToJsonObjectField
  115. ( outputValue
  116. , "Id"
  117. , &inputScriptDataPtr->m_id
  118. , defaultScriptDataPtr ? &defaultScriptDataPtr->m_id : nullptr
  119. , azrtti_typeid<decltype(inputScriptDataPtr->m_id)>()
  120. , context));
  121. if (!inputScriptDataPtr->m_extraStore.empty())
  122. {
  123. rapidjson::Value typeValue;
  124. result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->m_extraStore.type(), context));
  125. outputValue.AddMember
  126. ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier)
  127. , AZStd::move(typeValue)
  128. , context.GetJsonAllocator());
  129. result.Combine(ContinueStoringToJsonObjectField
  130. ( outputValue
  131. , "Value"
  132. , AZStd::any_cast<void>(const_cast<AZStd::any*>(&inputScriptDataPtr->m_extraStore))
  133. , defaultScriptDataPtr ? AZStd::any_cast<void>(const_cast<AZStd::any*>(&defaultScriptDataPtr->m_extraStore)) : nullptr
  134. , inputScriptDataPtr->m_extraStore.type()
  135. , context));
  136. }
  137. else
  138. {
  139. rapidjson::Value emptyAny;
  140. emptyAny.SetString(EmptyAnyIdentifier.data(), aznumeric_caster(EmptyAnyIdentifier.size()), context.GetJsonAllocator());
  141. outputValue.AddMember
  142. ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier)
  143. , AZStd::move(emptyAny)
  144. , context.GetJsonAllocator());
  145. }
  146. return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
  147. ? "ElementInformation Store finished saving ElementInformation"
  148. : "ElementInformation Store failed to save ElementInformation");
  149. }
  150. };
  151. AZ_CLASS_ALLOCATOR_IMPL(ElementInformationSerializer, SystemAllocator);
  152. }