diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h index 83db8fc242..4cbc25b500 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h @@ -20,6 +20,7 @@ namespace AZ { class ReflectContext; + class DatumSerializer; } namespace ScriptCanvas @@ -33,6 +34,8 @@ namespace ScriptCanvas /// in the editor, regardless of their actual ScriptCanvas or BehaviorContext type. class Datum final { + friend class AZ::DatumSerializer; + public: AZ_TYPE_INFO(Datum, "{8B836FC0-98A8-4A81-8651-35C7CA125451}"); AZ_CLASS_ALLOCATOR(Datum, AZ::SystemAllocator, 0); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp new file mode 100644 index 0000000000..207eb842fd --- /dev/null +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include + +using namespace ScriptCanvas; + +namespace AZ +{ + AZ_CLASS_ALLOCATOR_IMPL(DatumSerializer, SystemAllocator, 0); + + JsonSerializationResult::Result DatumSerializer::Load + ( void* outputValue + , [[maybe_unused]] const Uuid& outputValueTypeId + , const rapidjson::Value& inputValue + , JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(outputValueTypeId == azrtti_typeid(), "DatumSerializer Load against output typeID that was not Datum"); + AZ_Assert(outputValue, "DatumSerializer Load against null output"); + + JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField); + auto outputDatum = reinterpret_cast(outputValue); + + bool isOverloadedStorage = false; + AZ_Assert(azrtti_typeidm_isOverloadedStorage)>() == azrtti_typeid() + , "overloaded storage type changed and won't load properly"); + result.Combine(ContinueLoadingFromJsonObjectField + ( &isOverloadedStorage + , azrtti_typeidm_isOverloadedStorage)>() + , inputValue + , "isOverloadedStorage" + , context)); + + ScriptCanvas::Data::Type scType; + AZ_Assert(azrtti_typeidm_type)>() == azrtti_typeid() + , "ScriptCanvas::Data::Type type changed and won't load properly"); + result.Combine(ContinueLoadingFromJsonObjectField + ( &scType + , azrtti_typeidm_type)>() + , inputValue + , "scriptCanvasType" + , context)); + + ScriptCanvas::Datum::eOriginality originality; + AZ_Assert(azrtti_typeidm_originality)>() == azrtti_typeid() + , "m_originality type changed and won't load properly"); + result.Combine(ContinueLoadingFromJsonObjectField + ( &originality + , azrtti_typeidm_originality)>() + , inputValue + , "originality" + , context)); + + AZStd::any storage; + { // datum storage begin + AZ::Uuid typeId = AZ::Uuid::CreateNull(); + + auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier); + if (typeIdMember == inputValue.MemberEnd()) + { + return context.Report + ( JSR::Tasks::ReadField + , JSR::Outcomes::Missing + , AZStd::string::format("DatumSerializer::Load failed to load the %s member" + , JsonSerialization::TypeIdFieldIdentifier)); + } + + result.Combine(LoadTypeId(typeId, typeIdMember->value, context)); + if (typeId.IsNull()) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic + , "DatumSerializer::Load failed to load the AZ TypeId of the value"); + } + + storage = context.GetSerializeContext()->CreateAny(typeId); + if (storage.empty() || storage.type() != typeId) + { + return context.Report(result, "DatumSerializer::Load failed to load a value matched the reported AZ TypeId. " + "The C++ declaration may have been deleted or changed."); + } + + result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&storage), typeId, inputValue, "value", context)); + } // datum storage end + + AZStd::string label; + AZ_Assert(azrtti_typeidm_datumLabel)>() == azrtti_typeid() + , "m_datumLabel type changed and won't load properly"); + result.Combine(ContinueLoadingFromJsonObjectField + ( &label + , azrtti_typeidm_datumLabel)>() + , inputValue + , "originality" + , context)); + + Datum copy(scType, originality, AZStd::any_cast(&storage), scType.GetAZType()); + copy.SetLabel(label); + *outputDatum = copy; + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "DatumSerializer Load finished loading Datum" + : "DatumSerializer Load failed to load Datum"); + } + + JsonSerializationResult::Result DatumSerializer::Store + ( rapidjson::Value& outputValue + , const void* inputValue + , const void* defaultValue + , [[maybe_unused]] const Uuid& valueTypeId + , JsonSerializerContext& context) + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(valueTypeId == azrtti_typeid(), "DatumSerializer Store against value typeID that was not Datum"); + AZ_Assert(inputValue, "DatumSerializer Store against null inputValue pointer "); + + auto inputScriptDataPtr = reinterpret_cast(inputValue); + auto defaultScriptDataPtr = reinterpret_cast(defaultValue); + + if (defaultScriptDataPtr) + { + if (*inputScriptDataPtr == *defaultScriptDataPtr) + { + return context.Report + ( JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "DatumSerializer Store used defaults for Datum"); + } + } + + JSR::ResultCode result(JSR::Tasks::WriteValue); + outputValue.SetObject(); + + result.Combine(ContinueStoringToJsonObjectField + ( outputValue + , "isOverloadedStorage" + , &inputScriptDataPtr->m_isOverloadedStorage + , defaultScriptDataPtr ? &defaultScriptDataPtr->m_isOverloadedStorage : nullptr + , azrtti_typeidm_isOverloadedStorage)>() + , context)); + + result.Combine(ContinueStoringToJsonObjectField + ( outputValue + , "scriptCanvasType" + , &inputScriptDataPtr->GetType() + , defaultScriptDataPtr ? &defaultScriptDataPtr->GetType() : nullptr + , azrtti_typeidGetType())>() + , context)); + + result.Combine(ContinueStoringToJsonObjectField + ( outputValue + , "originality" + , &inputScriptDataPtr->m_originality + , defaultScriptDataPtr ? &defaultScriptDataPtr->m_originality : nullptr + , azrtti_typeidm_originality)>() + , context)); + + { // datum storage begin + { + rapidjson::Value typeValue; + result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->GetType().GetAZType(), context)); + outputValue.AddMember + ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier) + , AZStd::move(typeValue) + , context.GetJsonAllocator()); + } + + result.Combine(ContinueStoringToJsonObjectField + ( outputValue + , "value" + , inputScriptDataPtr->GetAsDanger() + , defaultScriptDataPtr ? defaultScriptDataPtr->GetAsDanger() : nullptr + , inputScriptDataPtr->GetType().GetAZType() + , context)); + } // datum storage end + + result.Combine(ContinueStoringToJsonObjectField + ( outputValue + , "label" + , &inputScriptDataPtr->m_datumLabel + , defaultScriptDataPtr ? &defaultScriptDataPtr->m_datumLabel : nullptr + , azrtti_typeidm_datumLabel)>() + , context)); + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "DatumSerializer Store finished saving Datum" + : "DatumSerializer Store failed to save Datum"); + } + +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.h new file mode 100644 index 0000000000..003c5c0383 --- /dev/null +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +namespace AZ +{ + class DatumSerializer + : public BaseJsonSerializer + { + public: + AZ_RTTI(DatumSerializer, "{FBEBF833-465F-49F4-AFB1-CC9D3B25C16C}", BaseJsonSerializer); + AZ_CLASS_ALLOCATOR_DECL; + + private: + JsonSerializationResult::Result Load + ( void* outputValue + , const Uuid& outputValueTypeId + , const rapidjson::Value& inputValue + , JsonDeserializerContext& context) override; + + JsonSerializationResult::Result Store + ( rapidjson::Value& outputValue + , const void* inputValue + , const void* defaultValue + , const Uuid& valueTypeId, JsonSerializerContext& context) override; + }; +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp index 64cf665305..763206df38 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp @@ -8,15 +8,15 @@ #include #include -#include +#include using namespace ScriptCanvas; namespace AZ { - AZ_CLASS_ALLOCATOR_IMPL(ScriptUserDataSerializer, SystemAllocator, 0); + AZ_CLASS_ALLOCATOR_IMPL(RuntimeVariableSerializer, SystemAllocator, 0); - JsonSerializationResult::Result ScriptUserDataSerializer::Load + JsonSerializationResult::Result RuntimeVariableSerializer::Load ( void* outputValue , [[maybe_unused]] const Uuid& outputValueTypeId , const rapidjson::Value& inputValue @@ -24,8 +24,8 @@ namespace AZ { namespace JSR = JsonSerializationResult; - AZ_Assert(outputValueTypeId == azrtti_typeid(), "ScriptUserDataSerializer Load against output typeID that was not RuntimeVariable"); - AZ_Assert(outputValue, "ScriptUserDataSerializer Load against null output"); + AZ_Assert(outputValueTypeId == azrtti_typeid(), "RuntimeVariableSerializer Load against output typeID that was not RuntimeVariable"); + AZ_Assert(outputValue, "RuntimeVariableSerializer Load against null output"); auto outputVariable = reinterpret_cast(outputValue); JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField); @@ -34,28 +34,28 @@ namespace AZ auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier); if (typeIdMember == inputValue.MemberEnd()) { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Missing, AZStd::string::format("ScriptUserDataSerializer::Load failed to load the %s member", JsonSerialization::TypeIdFieldIdentifier)); + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Missing, AZStd::string::format("RuntimeVariableSerializer::Load failed to load the %s member", JsonSerialization::TypeIdFieldIdentifier)); } result.Combine(LoadTypeId(typeId, typeIdMember->value, context)); if (typeId.IsNull()) { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "ScriptUserDataSerializer::Load failed to load the AZ TypeId of the value"); + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "RuntimeVariableSerializer::Load failed to load the AZ TypeId of the value"); } outputVariable->value = context.GetSerializeContext()->CreateAny(typeId); if (outputVariable->value.empty() || outputVariable->value.type() != typeId) { - return context.Report(result, "ScriptUserDataSerializer::Load failed to load a value matched the reported AZ TypeId. The C++ declaration may have been deleted or changed."); + return context.Report(result, "RuntimeVariableSerializer::Load failed to load a value matched the reported AZ TypeId. The C++ declaration may have been deleted or changed."); } result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&outputVariable->value), typeId, inputValue, "value", context)); return context.Report(result, result.GetProcessing() != JSR::Processing::Halted - ? "ScriptUserDataSerializer Load finished loading RuntimeVariable" - : "ScriptUserDataSerializer Load failed to load RuntimeVariable"); + ? "RuntimeVariableSerializer Load finished loading RuntimeVariable" + : "RuntimeVariableSerializer Load failed to load RuntimeVariable"); } - JsonSerializationResult::Result ScriptUserDataSerializer::Store + JsonSerializationResult::Result RuntimeVariableSerializer::Store ( rapidjson::Value& outputValue , const void* inputValue , const void* defaultValue @@ -79,7 +79,7 @@ namespace AZ if (inputDatum == defaultDatum) { - return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "ScriptUserDataSerializer Store used defaults for RuntimeVariable"); + return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "RuntimeVariableSerializer Store used defaults for RuntimeVariable"); } } @@ -95,8 +95,8 @@ namespace AZ result.Combine(ContinueStoringToJsonObjectField(outputValue, "value", AZStd::any_cast(inputAnyPtr), AZStd::any_cast(defaultAnyPtr), inputAnyPtr->type(), context)); return context.Report(result, result.GetProcessing() != JSR::Processing::Halted - ? "ScriptUserDataSerializer Store finished saving RuntimeVariable" - : "ScriptUserDataSerializer Store failed to save RuntimeVariable"); + ? "RuntimeVariableSerializer Store finished saving RuntimeVariable" + : "RuntimeVariableSerializer Store failed to save RuntimeVariable"); } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h index 720f9481f3..a55770c79f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h @@ -14,11 +14,11 @@ namespace AZ { - class ScriptUserDataSerializer + class RuntimeVariableSerializer : public BaseJsonSerializer { public: - AZ_RTTI(ScriptUserDataSerializer, "{7E5FC193-8CDB-4251-A68B-F337027381DF}", BaseJsonSerializer); + AZ_RTTI(RuntimeVariableSerializer, "{7E5FC193-8CDB-4251-A68B-F337027381DF}", BaseJsonSerializer); AZ_CLASS_ALLOCATOR_DECL; private: diff --git a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp index 9efbb13639..0a82b8cf2a 100644 --- a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp @@ -23,7 +23,8 @@ #include #include #include -#include +#include +#include #include #include @@ -87,8 +88,13 @@ namespace ScriptCanvas if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast(context)) { - jsonContext->Serializer() - ->HandlesType(); + jsonContext->Serializer() + ->HandlesType() + ; + + jsonContext->Serializer() + ->HandlesType() + ; } #if defined(SC_EXECUTION_TRACE_ENABLED) diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index 84ba39cc72..f1215dd580 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -539,8 +539,10 @@ set(FILES Include/ScriptCanvas/Profiler/Aggregator.cpp Include/ScriptCanvas/Profiler/DrillerEvents.h Include/ScriptCanvas/Profiler/DrillerEvents.cpp - Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h - Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp + Include/ScriptCanvas/Serialization/DatumSerializer.h + Include/ScriptCanvas/Serialization/DatumSerializer.cpp + Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h + Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp Include/ScriptCanvas/Data/DataTrait.cpp Include/ScriptCanvas/Data/DataTrait.h Include/ScriptCanvas/Data/PropertyTraits.cpp