3
0

ExpressionPrimitivesSerializers.inl 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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/ExpressionTree.h>
  15. namespace AZ
  16. {
  17. class ExpressionTreeVariableDescriptorSerializer
  18. : public BaseJsonSerializer
  19. {
  20. public:
  21. AZ_RTTI(ExpressionTreeVariableDescriptorSerializer, "{5EFF37D6-BD54-45C6-9FC6-B1E0D3A8204C}", BaseJsonSerializer);
  22. AZ_CLASS_ALLOCATOR_DECL;
  23. private:
  24. using VariableDescriptor = ExpressionEvaluation::ExpressionTree::VariableDescriptor;
  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<VariableDescriptor>(), "ExpressionTreeVariableDescriptorSerializer Load against "
  43. "output typeID that was not VariableDescriptor");
  44. AZ_Assert(outputValue, "ExpressionTreeVariableDescriptorSerializer Load against null output");
  45. JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField);
  46. auto outputDatum = reinterpret_cast<VariableDescriptor*>(outputValue);
  47. result.Combine(ContinueLoadingFromJsonObjectField
  48. ( &outputDatum->m_supportedTypes
  49. , azrtti_typeid<decltype(outputDatum->m_supportedTypes)>()
  50. , inputValue
  51. , "SupportedTypes"
  52. , context));
  53. // any storage begin
  54. AZ::Uuid typeId = AZ::Uuid::CreateNull();
  55. auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier);
  56. if (typeIdMember == inputValue.MemberEnd())
  57. {
  58. return context.Report
  59. ( JSR::Tasks::ReadField
  60. , JSR::Outcomes::Missing
  61. , AZStd::string::format("ExpressionTreeVariableDescriptorSerializer::Load failed to load the %s member"
  62. , JsonSerialization::TypeIdFieldIdentifier));
  63. }
  64. if (!IsEmptyAny(typeIdMember->value))
  65. {
  66. result.Combine(LoadTypeId(typeId, typeIdMember->value, context));
  67. if (typeId.IsNull())
  68. {
  69. return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic
  70. , "ExpressionTreeVariableDescriptorSerializer::Load failed to load the AZ TypeId of the value");
  71. }
  72. AZStd::any storage = context.GetSerializeContext()->CreateAny(typeId);
  73. if (storage.empty() || storage.type() != typeId)
  74. {
  75. return context.Report(result, "ExpressionTreeVariableDescriptorSerializer::Load failed to load a value matched the "
  76. "reported AZ TypeId. The C++ declaration may have been deleted or changed.");
  77. }
  78. result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast<void>(&storage), typeId, inputValue, "Value", context));
  79. outputDatum->m_value = storage;
  80. }
  81. // any storage end
  82. return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
  83. ? "ExpressionTreeVariableDescriptorSerializer Load finished loading VariableDescriptor"
  84. : "ExpressionTreeVariableDescriptorSerializer Load failed to load VariableDescriptor");
  85. }
  86. JsonSerializationResult::Result Store
  87. ( rapidjson::Value& outputValue
  88. , const void* inputValue
  89. , const void* defaultValue
  90. , [[maybe_unused]] const Uuid& valueTypeId
  91. , JsonSerializerContext& context) override
  92. {
  93. namespace JSR = JsonSerializationResult;
  94. AZ_Assert(valueTypeId == azrtti_typeid<VariableDescriptor>(), "VariableDescriptor Store against value typeID that "
  95. "was not VariableDescriptor");
  96. AZ_Assert(inputValue, "VariableDescriptor Store against null inputValue pointer ");
  97. auto inputScriptDataPtr = reinterpret_cast<const VariableDescriptor*>(inputValue);
  98. auto defaultScriptDataPtr = reinterpret_cast<const VariableDescriptor*>(defaultValue);
  99. if (defaultScriptDataPtr)
  100. {
  101. if (inputScriptDataPtr->m_supportedTypes == defaultScriptDataPtr->m_supportedTypes
  102. && AZ::Helpers::CompareAnyValue(inputScriptDataPtr->m_value, defaultScriptDataPtr->m_value))
  103. {
  104. return context.Report
  105. ( JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "VariableDescriptor Store used defaults for "
  106. "VariableDescriptor");
  107. }
  108. }
  109. JSR::ResultCode result(JSR::Tasks::WriteValue);
  110. outputValue.SetObject();
  111. result.Combine(ContinueStoringToJsonObjectField
  112. ( outputValue
  113. , "SupportedTypes"
  114. , &inputScriptDataPtr->m_supportedTypes
  115. , defaultScriptDataPtr ? &defaultScriptDataPtr->m_supportedTypes : nullptr
  116. , azrtti_typeid<decltype(inputScriptDataPtr->m_supportedTypes)>()
  117. , context));
  118. if (!inputScriptDataPtr->m_value.empty())
  119. {
  120. rapidjson::Value typeValue;
  121. result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->m_value.type(), context));
  122. outputValue.AddMember
  123. ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier)
  124. , AZStd::move(typeValue)
  125. , context.GetJsonAllocator());
  126. result.Combine(ContinueStoringToJsonObjectField
  127. ( outputValue
  128. , "Value"
  129. , AZStd::any_cast<void>(const_cast<AZStd::any*>(&inputScriptDataPtr->m_value))
  130. , defaultScriptDataPtr ? AZStd::any_cast<void>(const_cast<AZStd::any*>(&defaultScriptDataPtr->m_value)) : nullptr
  131. , inputScriptDataPtr->m_value.type()
  132. , context));
  133. }
  134. else
  135. {
  136. rapidjson::Value emptyAny;
  137. emptyAny.SetString(EmptyAnyIdentifier.data(), aznumeric_caster(EmptyAnyIdentifier.size()), context.GetJsonAllocator());
  138. outputValue.AddMember
  139. ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier)
  140. , AZStd::move(emptyAny)
  141. , context.GetJsonAllocator());
  142. }
  143. return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
  144. ? "VariableDescriptor Store finished saving VariableDescriptor"
  145. : "VariableDescriptor Store failed to save VariableDescriptor");
  146. }
  147. };
  148. AZ_CLASS_ALLOCATOR_IMPL(ExpressionTreeVariableDescriptorSerializer, SystemAllocator);
  149. }