3
0

MaterialFunctorSourceDataSerializer.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. #include <Atom/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.h>
  9. #include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
  10. #include <Atom/RPI.Edit/Common/AssetUtils.h>
  11. #include <Atom/RPI.Edit/Material/MaterialFunctorSourceDataRegistration.h>
  12. #include <AzCore/Serialization/Json/JsonUtils.h>
  13. #include <AzCore/Serialization/Json/BaseJsonSerializer.h>
  14. #include <AzCore/Serialization/Json/JsonSerializationResult.h>
  15. #include <AzCore/Serialization/Json/JsonSerialization.h>
  16. #include <AzCore/Serialization/Json/StackedString.h>
  17. namespace AZ
  18. {
  19. namespace RPI
  20. {
  21. namespace
  22. {
  23. constexpr const char TypeField[] = "type";
  24. constexpr const char ArgsField[] = "args";
  25. }
  26. AZ_CLASS_ALLOCATOR_IMPL(JsonMaterialFunctorSourceDataSerializer, SystemAllocator);
  27. JsonSerializationResult::Result JsonMaterialFunctorSourceDataSerializer::Load(void* outputValue, const Uuid& outputValueTypeId,
  28. const rapidjson::Value& inputValue, JsonDeserializerContext& context)
  29. {
  30. namespace JSR = JsonSerializationResult;
  31. AZ_Assert(azrtti_typeid<MaterialFunctorSourceDataHolder>() == outputValueTypeId,
  32. "Unable to deserialize material functor to json because the provided type is %s",
  33. outputValueTypeId.ToString<AZStd::string>().c_str());
  34. AZ_UNUSED(outputValueTypeId);
  35. MaterialFunctorSourceDataHolder* functorHolder = reinterpret_cast<MaterialFunctorSourceDataHolder*>(outputValue);
  36. AZ_Assert(functorHolder, "Output value for JsonMaterialFunctorSourceDataSerializer can't be null.");
  37. JSR::ResultCode result(JSR::Tasks::ReadField);
  38. if (!inputValue.IsObject())
  39. {
  40. return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Material functor data must be a JSON object.");
  41. }
  42. Uuid functorTypeId;
  43. if (!inputValue.HasMember(TypeField))
  44. {
  45. return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Missing, "Functor type name is not specified.");
  46. }
  47. // Load the name first and find the type.
  48. AZStd::string functorName;
  49. result.Combine(ContinueLoadingFromJsonObjectField(&functorName, azrtti_typeid<AZStd::string>(), inputValue, TypeField, context));
  50. functorTypeId = MaterialFunctorSourceDataRegistration::Get()->FindMaterialFunctorTypeIdByName(functorName);
  51. if (functorTypeId.IsNull())
  52. {
  53. return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Functor type name is not registered.");
  54. }
  55. // Create the actual source data of the functor.
  56. const SerializeContext::ClassData* actualClassData = context.GetSerializeContext()->FindClassData(functorTypeId);
  57. if (actualClassData)
  58. {
  59. void* instance = actualClassData->m_factory->Create(actualClassData->m_name);
  60. if (inputValue.HasMember(ArgsField))
  61. {
  62. result.Combine(ContinueLoading(instance, functorTypeId, inputValue[ArgsField], context));
  63. }
  64. else
  65. {
  66. result.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed));
  67. }
  68. functorHolder->m_actualSourceData = reinterpret_cast<MaterialFunctorSourceData*>(instance);
  69. }
  70. else
  71. {
  72. return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Class data is not registered in the SerializeContext.");
  73. }
  74. return context.Report(result, "Successfully processed MaterialFunctorSourceData.");
  75. }
  76. JsonSerializationResult::Result JsonMaterialFunctorSourceDataSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
  77. [[maybe_unused]] const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context)
  78. {
  79. namespace JSR = JsonSerializationResult;
  80. AZ_Assert(azrtti_typeid<MaterialFunctorSourceDataHolder>() == valueTypeId,
  81. "Unable to serialize material functor to json because the provided type is %s",
  82. valueTypeId.ToString<AZStd::string>().c_str());
  83. AZ_UNUSED(valueTypeId);
  84. JSR::ResultCode result(JSR::Tasks::WriteValue);
  85. outputValue.SetObject();
  86. const MaterialFunctorSourceDataHolder* functorHolder = reinterpret_cast<const MaterialFunctorSourceDataHolder*>(inputValue);
  87. if (!functorHolder->m_actualSourceData)
  88. {
  89. return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Unsupported, "No actual functor source data lives in this holder.");
  90. }
  91. Uuid functorTypeId = functorHolder->m_actualSourceData->RTTI_GetType();
  92. AZStd::string functorName = MaterialFunctorSourceDataRegistration::Get()->FindMaterialFunctorNameByTypeId(functorTypeId);
  93. if (functorName.empty())
  94. {
  95. return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Unsupported, "Functor name is not registered.");
  96. }
  97. const AZStd::string emptyString;
  98. result.Combine(ContinueStoringToJsonObjectField(outputValue, TypeField, &functorName, &emptyString, azrtti_typeid<AZStd::string>(), context));
  99. result.Combine(ContinueStoringToJsonObjectField(outputValue, ArgsField, functorHolder->m_actualSourceData.get(), nullptr, functorTypeId, context));
  100. return context.Report(result, "Successfully processed MaterialFunctorSourceData.");
  101. }
  102. BaseJsonSerializer::OperationFlags JsonMaterialFunctorSourceDataSerializer::GetOperationsFlags() const
  103. {
  104. return OperationFlags::ManualDefault;
  105. }
  106. } // namespace RPI
  107. } // namespace AZ