diff --git a/.gitignore b/.gitignore index 1b63c7698a..b73c89b1d9 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ TestResults/** *.swatches /imgui.ini /scripts/project_manager/logs/ +/AutomatedTesting/Gem/PythonTests/scripting/TestResults diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptProperty.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptProperty.cpp index 8664842893..dbccda4de2 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptProperty.cpp +++ b/Code/Framework/AzCore/AzCore/Script/ScriptProperty.cpp @@ -31,7 +31,6 @@ namespace AZ ScriptPropertyGenericClassArray::Reflect(reflection); ScriptPropertyAsset::Reflect(reflection); - ScriptPropertyEntityRef::Reflect(reflection); } template @@ -1358,53 +1357,4 @@ namespace AZ m_value = assetProperty->m_value; } } - - //////////////////////////// - // ScriptPropertyEntityRef - //////////////////////////// - void ScriptPropertyEntityRef::Reflect(AZ::ReflectContext* reflection) - { - AZ::SerializeContext* serializeContext = azrtti_cast(reflection); - - if (serializeContext) - { - serializeContext->Class()-> - Version(1)-> - Field("value", &AZ::ScriptPropertyEntityRef::m_value); - } - } - - const AZ::Uuid& ScriptPropertyEntityRef::GetDataTypeUuid() const - { - return AZ::SerializeTypeInfo::GetUuid(); - } - - bool ScriptPropertyEntityRef::DoesTypeMatch(AZ::ScriptDataContext& context, int valueIndex) const - { - return context.IsRegisteredClass(valueIndex); - } - - AZ::ScriptPropertyEntityRef* ScriptPropertyEntityRef::Clone(const char* name) const - { - AZ::ScriptPropertyEntityRef* clonedValue = aznew AZ::ScriptPropertyEntityRef(name ? name : m_name.c_str()); - clonedValue->m_value = m_value; - return clonedValue; - } - - bool ScriptPropertyEntityRef::Write(AZ::ScriptContext& context) - { - AZ::ScriptValue::StackPush(context.NativeContext(), m_value); - return true; - } - - void ScriptPropertyEntityRef::CloneDataFrom(const AZ::ScriptProperty* scriptProperty) - { - const AZ::ScriptPropertyEntityRef* entityProperty = azrtti_cast(scriptProperty); - - AZ_Error("ScriptPropertyEntityRef", entityProperty, "Invalid call to CloneData. Types must match before clone attempt is made.\n"); - if (entityProperty) - { - m_value = entityProperty->m_value; - } } -} diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptProperty.h b/Code/Framework/AzCore/AzCore/Script/ScriptProperty.h index c12fa3e8f1..f38931127d 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptProperty.h +++ b/Code/Framework/AzCore/AzCore/Script/ScriptProperty.h @@ -488,34 +488,6 @@ namespace AZ protected: void CloneDataFrom(const AZ::ScriptProperty* scriptProperty) override; }; - - class ScriptPropertyEntityRef - : public ScriptProperty - { - public: - AZ_CLASS_ALLOCATOR(ScriptPropertyEntityRef, AZ::SystemAllocator, 0); - AZ_RTTI(AZ::ScriptPropertyEntityRef, "{68EDE6C3-0A89-4C50-A86E-06C058C9F862}", ScriptProperty); - - static void Reflect(AZ::ReflectContext* reflection); - - ScriptPropertyEntityRef() {} - ScriptPropertyEntityRef(const char* name) - : ScriptProperty(name) {} - virtual ~ScriptPropertyEntityRef() = default; - const void* GetDataAddress() const override { return &m_value; } - const AZ::Uuid& GetDataTypeUuid() const override; - - bool DoesTypeMatch(AZ::ScriptDataContext& context, int valueIndex) const override; - - ScriptPropertyEntityRef* Clone(const char* name = nullptr) const override; - - bool Write(AZ::ScriptContext& context) override; - - AZ::EntityId m_value; - - protected: - void CloneDataFrom(const AZ::ScriptProperty* scriptProperty) override; - }; } #endif diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptPropertySerializer.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptPropertySerializer.cpp new file mode 100644 index 0000000000..ff889be116 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/Script/ScriptPropertySerializer.cpp @@ -0,0 +1,99 @@ +/* + * 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 + +namespace AZ +{ + AZ_CLASS_ALLOCATOR_IMPL(ScriptPropertySerializer, SystemAllocator, 0); + + JsonSerializationResult::Result ScriptPropertySerializer::Load + ( void* outputValue + , [[maybe_unused]] const Uuid& outputValueTypeId + , const rapidjson::Value& inputValue + , JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(outputValueTypeId == azrtti_typeid(), "ScriptPropertySerializer Load against output typeID that was not DynamicSerializableField"); + AZ_Assert(outputValue, "ScriptPropertySerializer Load against null output"); + + auto outputVariable = reinterpret_cast(outputValue); + JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField); + 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("ScriptPropertySerializer::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, "ScriptPropertySerializer::Load failed to load the AZ TypeId of the value"); + } + + AZStd::any storage = context.GetSerializeContext()->CreateAny(typeId); + if (storage.empty() || storage.type() != typeId) + { + return context.Report(result, "ScriptPropertySerializer::Load failed to load a value matched the reported AZ TypeId. The C++ declaration may have been deleted or changed."); + } + + DynamicSerializableField storageField; + storageField.m_data = AZStd::any_cast(&storage); + storageField.m_typeId = typeId; + outputVariable->CopyDataFrom(storageField, context.GetSerializeContext()); + + result.Combine(ContinueLoadingFromJsonObjectField(outputVariable->m_data, typeId, inputValue, "value", context)); + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "ScriptPropertySerializer Load finished loading DynamicSerializableField" + : "ScriptPropertySerializer Load failed to load DynamicSerializableField"); + } + + JsonSerializationResult::Result ScriptPropertySerializer::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(), "DynamicSerializableField Store against value typeID that was not DynamicSerializableField"); + AZ_Assert(inputValue, "DynamicSerializableField Store against null inputValue pointer "); + + auto inputScriptDataPtr = reinterpret_cast(inputValue); + auto inputFieldPtr = inputScriptDataPtr->m_data; + auto defaultScriptDataPtr = reinterpret_cast(defaultValue); + auto defaultFieldPtr = defaultScriptDataPtr ? &defaultScriptDataPtr->m_data : nullptr; + + if (defaultScriptDataPtr && inputScriptDataPtr->IsEqualTo(*defaultScriptDataPtr, context.GetSerializeContext())) + { + return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "ScriptPropertySerializer Store used defaults for DynamicSerializableField"); + } + + JSR::ResultCode result(JSR::Tasks::WriteValue); + outputValue.SetObject(); + + { + rapidjson::Value typeValue; + result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->m_typeId, context)); + outputValue.AddMember(rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier), AZStd::move(typeValue), context.GetJsonAllocator()); + } + + result.Combine(ContinueStoringToJsonObjectField(outputValue, "value", inputFieldPtr, defaultFieldPtr, inputScriptDataPtr->m_typeId, context)); + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "ScriptPropertySerializer Store finished saving DynamicSerializableField" + : "ScriptPropertySerializer Store failed to save DynamicSerializableField"); + } + +} diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptPropertySerializer.h b/Code/Framework/AzCore/AzCore/Script/ScriptPropertySerializer.h new file mode 100644 index 0000000000..a3de3e761d --- /dev/null +++ b/Code/Framework/AzCore/AzCore/Script/ScriptPropertySerializer.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 ScriptPropertySerializer + : public BaseJsonSerializer + { + public: + AZ_RTTI(ScriptPropertySerializer, "{C7BECA49-84EF-45E6-A89D-052D61766197}", 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/Code/Framework/AzCore/AzCore/Script/ScriptSystemComponent.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptSystemComponent.cpp index 6706d4f8d8..fa61a225c8 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptSystemComponent.cpp +++ b/Code/Framework/AzCore/AzCore/Script/ScriptSystemComponent.cpp @@ -8,10 +8,8 @@ #if !defined(AZCORE_EXCLUDE_LUA) -#include - -#include #include +#include #include #include #include @@ -21,13 +19,16 @@ #include #include #include -#include #include #include #include - -#include +#include +#include #include +#include +#include +#include +#include using namespace AZ; @@ -921,6 +922,12 @@ void ScriptSystemComponent::Reflect(ReflectContext* reflection) } } + if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast(reflection)) + { + jsonContext->Serializer() + ->HandlesType(); + } + if (BehaviorContext* behaviorContext = azrtti_cast(reflection)) { // reflect default entity diff --git a/Code/Framework/AzCore/AzCore/Serialization/DynamicSerializableField.cpp b/Code/Framework/AzCore/AzCore/Serialization/DynamicSerializableField.cpp index 16b6a2c48b..036c2df297 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/DynamicSerializableField.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/DynamicSerializableField.cpp @@ -98,14 +98,14 @@ namespace AZ return nullptr; } //------------------------------------------------------------------------- - void DynamicSerializableField::CopyDataFrom(const DynamicSerializableField& other) + void DynamicSerializableField::CopyDataFrom(const DynamicSerializableField& other, SerializeContext* useContext) { DestroyData(); m_typeId = other.m_typeId; - m_data = other.CloneData(); + m_data = other.CloneData(useContext); } //------------------------------------------------------------------------- - bool DynamicSerializableField::IsEqualTo(const DynamicSerializableField& other, SerializeContext* useContext) + bool DynamicSerializableField::IsEqualTo(const DynamicSerializableField& other, SerializeContext* useContext) const { if (other.m_typeId != m_typeId) { diff --git a/Code/Framework/AzCore/AzCore/Serialization/DynamicSerializableField.h b/Code/Framework/AzCore/AzCore/Serialization/DynamicSerializableField.h index 70a8924265..4b5a963b26 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/DynamicSerializableField.h +++ b/Code/Framework/AzCore/AzCore/Serialization/DynamicSerializableField.h @@ -9,6 +9,8 @@ #define AZCORE_DYNAMIC_SERIALIZABLE_FIELD_H #include +#include +#include namespace AZ { @@ -24,6 +26,7 @@ namespace AZ { public: AZ_TYPE_INFO(DynamicSerializableField, "{D761E0C2-A098-497C-B8EB-EA62F5ED896B}") + AZ_CLASS_ALLOCATOR(DynamicSerializableField, AZ::SystemAllocator, 0); DynamicSerializableField(); DynamicSerializableField(const DynamicSerializableField& serializableField); @@ -33,8 +36,8 @@ namespace AZ void DestroyData(SerializeContext* useContext = nullptr); void* CloneData(SerializeContext* useContext = nullptr) const; - void CopyDataFrom(const DynamicSerializableField& other); - bool IsEqualTo(const DynamicSerializableField& other, SerializeContext* useContext = nullptr); + void CopyDataFrom(const DynamicSerializableField& other, SerializeContext* useContext = nullptr); + bool IsEqualTo(const DynamicSerializableField& other, SerializeContext* useContext = nullptr) const; template void Set(T* object) diff --git a/Code/Framework/AzCore/AzCore/Slice/SliceComponent.h b/Code/Framework/AzCore/AzCore/Slice/SliceComponent.h index 86f41c6548..7a66167a96 100644 --- a/Code/Framework/AzCore/AzCore/Slice/SliceComponent.h +++ b/Code/Framework/AzCore/AzCore/Slice/SliceComponent.h @@ -13,7 +13,6 @@ #include #include #include -#include #include namespace AZ diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index 1e2a0b98a0..c33d678730 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -462,6 +462,8 @@ set(FILES Script/ScriptTimePoint.h Script/ScriptProperty.h Script/ScriptProperty.cpp + Script/ScriptPropertySerializer.h + Script/ScriptPropertySerializer.cpp Script/ScriptPropertyTable.h Script/ScriptPropertyTable.cpp Script/ScriptPropertyWatcherBus.h diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/ScriptEditorComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/ScriptEditorComponent.cpp index 1ae1a3605a..da12a4bd7a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/ScriptEditorComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/ScriptEditorComponent.cpp @@ -1107,17 +1107,7 @@ namespace AzToolsFramework ElementAttribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)-> Attribute(AZ::Edit::Attributes::NameLabelOverride, &AZ::ScriptProperty::m_name); - ec->Class("Script Property Asset(asset)", "A script asset property")-> - ClassElement(AZ::Edit::ClassElements::EditorData, "ScriptPropertyEditorAsset's class attributes.")-> - Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)-> - DataElement("Asset", &AZ::ScriptPropertyAsset::m_value, "m_value", "An object")-> - Attribute(AZ::Edit::Attributes::NameLabelOverride, &AZ::ScriptProperty::m_name); - ec->Class("Script Property Entity(EntityRef)", "A script entity reference property")-> - ClassElement(AZ::Edit::ClassElements::EditorData, "ScriptPropertyEditorEntityRef's class attributes.")-> - Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)-> - DataElement("EntityRef", &AZ::ScriptPropertyEntityRef::m_value, "m_entity", "An entity reference")-> - Attribute(AZ::Edit::Attributes::NameLabelOverride, &AZ::ScriptProperty::m_name); } } } diff --git a/Gems/ScriptEvents/Code/Include/ScriptEvents/Internal/VersionedProperty.cpp b/Gems/ScriptEvents/Code/Include/ScriptEvents/Internal/VersionedProperty.cpp index 59f2ffe58c..e09bdc94a9 100644 --- a/Gems/ScriptEvents/Code/Include/ScriptEvents/Internal/VersionedProperty.cpp +++ b/Gems/ScriptEvents/Code/Include/ScriptEvents/Internal/VersionedProperty.cpp @@ -9,7 +9,6 @@ #include "VersionedProperty.h" #include -#include #include #include #include