[LYN-3412] Updated LandscapeCanvas component to properly serialize with prefabs. (#1224)

* [LYN-3412] Updated LandscapeCanvas component to properly serialize with prefabs.

* [LYN-3412] Updated PR with feedback.

* [LYN-3412] Reverted unintentional changes.

* [LYN-3412] Removed one more comment.

* [LYN-3412] Additional PR feedback fixed.
This commit is contained in:
cgalvan
2021-06-21 16:03:49 -05:00
committed by GitHub
parent a963cd3ac8
commit 46f8c7c1ba
9 changed files with 248 additions and 21 deletions
+159 -3
View File
@@ -11,9 +11,14 @@
*/
// AZ
#include <AzCore/Math/Color.h>
#include <AzCore/Math/Vector2.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Vector4.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/Json/RegistrationContext.h>
#include <AzCore/Serialization/SerializeContext.h>
// Graph Model
@@ -294,13 +299,164 @@ namespace GraphModel
/////////////////////////////////////////////////////////
// Slot
AZ::JsonSerializationResult::Result JsonSlotSerializer::Load(
void* outputValue, const AZ::Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
AZ::JsonDeserializerContext& context)
{
namespace JSR = AZ::JsonSerializationResult;
AZ_Assert(
azrtti_typeid<Slot>() == outputValueTypeId,
"Unable to deserialize Slot from json because the provided type is %s.",
outputValueTypeId.ToString<AZStd::string>().c_str());
Slot* slot = reinterpret_cast<Slot*>(outputValue);
AZ_Assert(slot, "Output value for JsonSlotSerializer can't be null.");
JSR::ResultCode result(JSR::Tasks::ReadField);
auto serializedSlotValue = inputValue.FindMember("m_value");
if (serializedSlotValue != inputValue.MemberEnd())
{
AZStd::any slotValue;
if (LoadAny<bool>(slotValue, serializedSlotValue->value, context, result) ||
LoadAny<int>(slotValue, serializedSlotValue->value, context, result) ||
LoadAny<float>(slotValue, serializedSlotValue->value, context, result) ||
LoadAny<AZStd::string>(slotValue, serializedSlotValue->value, context, result) ||
LoadAny<AZ::Vector2>(slotValue, serializedSlotValue->value, context, result) ||
LoadAny<AZ::Vector3>(slotValue, serializedSlotValue->value, context, result) ||
LoadAny<AZ::Vector4>(slotValue, serializedSlotValue->value, context, result) ||
LoadAny<AZ::EntityId>(slotValue, serializedSlotValue->value, context, result))
{
slot->m_value = slotValue;
}
}
// Load m_subId normally because it's just an int
{
SlotSubId slotSubId = 0;
result.Combine(ContinueLoadingFromJsonObjectField(
&slotSubId, azrtti_typeid<SlotSubId>(), inputValue,
"m_subId", context));
slot->m_subId = slotSubId;
}
return context.Report(
result,
result.GetProcessing() != JSR::Processing::Halted ? "Succesfully loaded Slot information."
: "Failed to load Slot information.");
}
AZ::JsonSerializationResult::Result JsonSlotSerializer::Store(
rapidjson::Value& outputValue, const void* inputValue, [[maybe_unused]] const void* defaultValue, const AZ::Uuid& valueTypeId,
AZ::JsonSerializerContext& context)
{
namespace JSR = AZ::JsonSerializationResult;
AZ_Assert(
azrtti_typeid<Slot>() == valueTypeId,
"Unable to Serialize Slot because the provided type is %s.", valueTypeId.ToString<AZStd::string>().c_str());
const Slot* slot = reinterpret_cast<const Slot*>(inputValue);
AZ_Assert(slot, "Input value for JsonSlotSerializer can't be null.");
outputValue.SetObject();
JSR::ResultCode result(JSR::Tasks::WriteValue);
{
AZ::ScopedContextPath subPathPropertyOverrides(context, "m_value");
if (!slot->m_value.empty())
{
rapidjson::Value outputPropertyValue;
if (StoreAny<bool>(slot->m_value, outputPropertyValue, context, result) ||
StoreAny<int>(slot->m_value, outputPropertyValue, context, result) ||
StoreAny<float>(slot->m_value, outputPropertyValue, context, result) ||
StoreAny<AZStd::string>(slot->m_value, outputPropertyValue, context, result) ||
StoreAny<AZ::Vector2>(slot->m_value, outputPropertyValue, context, result) ||
StoreAny<AZ::Vector3>(slot->m_value, outputPropertyValue, context, result) ||
StoreAny<AZ::Vector4>(slot->m_value, outputPropertyValue, context, result) ||
StoreAny<AZ::EntityId>(slot->m_value, outputPropertyValue, context, result))
{
outputValue.AddMember("m_value", outputPropertyValue, context.GetJsonAllocator());
}
}
}
{
AZ::ScopedContextPath subSlotId(context, "m_subId");
SlotSubId defaultSubId = 0;
result.Combine(ContinueStoringToJsonObjectField(
outputValue, "m_subId", &slot->m_subId, &defaultSubId,
azrtti_typeid<SlotSubId>(), context));
}
return context.Report(
result,
result.GetProcessing() != JSR::Processing::Halted ? "Successfully stored MaterialAssignment information."
: "Failed to store MaterialAssignment information.");
}
template<typename T>
bool JsonSlotSerializer::LoadAny(
AZStd::any& propertyValue, const rapidjson::Value& inputPropertyValue, AZ::JsonDeserializerContext& context,
AZ::JsonSerializationResult::ResultCode& result)
{
auto valueItr = inputPropertyValue.FindMember("Value");
auto typeItr = inputPropertyValue.FindMember("$type");
if ((valueItr != inputPropertyValue.MemberEnd()) && (typeItr != inputPropertyValue.MemberEnd()))
{
// Requiring explicit type info to differentiate between colors versus vectors and numeric types
const AZ::Uuid baseTypeId = azrtti_typeid<T>();
AZ::Uuid typeId = AZ::Uuid::CreateNull();
result.Combine(LoadTypeId(typeId, inputPropertyValue, context, &baseTypeId));
if (typeId == azrtti_typeid<T>())
{
T value;
result.Combine(ContinueLoadingFromJsonObjectField(&value, azrtti_typeid<T>(), inputPropertyValue, "Value", context));
propertyValue = value;
return true;
}
}
return false;
}
template<typename T>
bool JsonSlotSerializer::StoreAny(
const AZStd::any& propertyValue, rapidjson::Value& outputPropertyValue, AZ::JsonSerializerContext& context,
AZ::JsonSerializationResult::ResultCode& result)
{
if (propertyValue.is<T>())
{
outputPropertyValue.SetObject();
// Storing explicit type info to differentiate between colors versus vectors and numeric types
rapidjson::Value typeValue;
result.Combine(StoreTypeId(typeValue, azrtti_typeid<T>(), context));
outputPropertyValue.AddMember("$type", typeValue, context.GetJsonAllocator());
T value = AZStd::any_cast<T>(propertyValue);
result.Combine(
ContinueStoringToJsonObjectField(outputPropertyValue, "Value", &value, nullptr, azrtti_typeid<T>(), context));
return true;
}
return false;
}
void Slot::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
if (auto jsonContext = azrtti_cast<AZ::JsonRegistrationContext*>(context))
{
jsonContext->Serializer<JsonSlotSerializer>()->HandlesType<Slot>();
}
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<Slot>()
->Version(0)
->Version(1)
->Field("m_value", &Slot::m_value)
->Field("m_subId", &Slot::m_subId)
// m_slotDescription is not reflected because that data is populated procedurally by each node