Merge pull request #3028 from aws-lumberyard-dev/carlitosan/development

Addes JSON serialization support for properties stored in the EditorScriptCanvasComponent. Add tool tips to explain repeater node behavior, remove empty "User Functions" and "Script Event" headings from Editor.
This commit is contained in:
carlitosan
2021-08-12 12:38:40 -07:00
committed by GitHub
14 changed files with 261 additions and 38 deletions
@@ -322,11 +322,9 @@ namespace ScriptCanvasEditor
return;
}
auto& variableOverrides = parseOutcome.GetValue();
if (!m_variableOverrides.IsEmpty())
{
variableOverrides.CopyPreviousOverriddenValues(m_variableOverrides);
parseOutcome.GetValue().CopyPreviousOverriddenValues(m_variableOverrides);
}
m_variableOverrides = parseOutcome.TakeValue();
@@ -351,8 +349,7 @@ namespace ScriptCanvasEditor
}
auto runtimeComponent = gameEntity->CreateComponent<ScriptCanvas::RuntimeComponent>();
auto runtimeOverrides = ConvertToRuntime(m_variableOverrides);
runtimeComponent->SetRuntimeDataOverrides(runtimeOverrides);
runtimeComponent->TakeRuntimeDataOverrides(ConvertToRuntime(m_variableOverrides));
}
void EditorScriptCanvasComponent::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
@@ -518,8 +515,8 @@ namespace ScriptCanvasEditor
[[maybe_unused]] AZ::Entity* scriptCanvasEntity = assetData->GetScriptCanvasEntity();
AZ_Assert(scriptCanvasEntity, "This graph must have a valid entity");
BuildGameEntityData();
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
UpdateName();
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
}
}
@@ -283,7 +283,7 @@ namespace ScriptCanvasEditor
loadResult.m_runtimeAsset.Get()->GetData().m_debugMap = luaAssetResult.m_debugMap;
loadResult.m_runtimeComponent = loadResult.m_entity->CreateComponent<ScriptCanvas::RuntimeComponent>();
CopyAssetEntityIdsToOverrides(runtimeDataOverrides);
loadResult.m_runtimeComponent->SetRuntimeDataOverrides(runtimeDataOverrides);
loadResult.m_runtimeComponent->TakeRuntimeDataOverrides(AZStd::move(runtimeDataOverrides));
Execution::Context::InitializeActivationData(loadResult.m_runtimeAsset->GetData());
Execution::InitializeInterpretedStatics(loadResult.m_runtimeAsset->GetData());
}
@@ -80,12 +80,11 @@ namespace ScriptCanvasEditor
GraphCanvas::NodePaletteTreeItem* variablesRoot = root->CreateChildNode<LocalVariablesListNodePaletteTreeItem>("Variables");
root->RegisterCategoryNode(variablesRoot, "Variables");
// We always want to keep these around as place holders
GraphCanvas::NodePaletteTreeItem* customEventRoot = root->GetCategoryNode("Script Events");
customEventRoot->SetAllowPruneOnEmpty(false);
customEventRoot->SetAllowPruneOnEmpty(true);
GraphCanvas::NodePaletteTreeItem* globalFunctionRoot = root->GetCategoryNode("User Functions");
globalFunctionRoot->SetAllowPruneOnEmpty(false);
globalFunctionRoot->SetAllowPruneOnEmpty(true);
}
@@ -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);
@@ -509,7 +509,8 @@ namespace ScriptCanvas
bool SubgraphInterface::HasAnyFunctionality() const
{
return IsActiveDefaultObject() || HasPublicFunctionality();
// \todo restore default object addition when ndoes can define an variable, as well
return /*IsActiveDefaultObject() || */ HasPublicFunctionality();
}
bool SubgraphInterface::HasBranches() const
@@ -93,9 +93,9 @@ namespace ScriptCanvas
return m_runtimeOverrides;
}
void RuntimeComponent::SetRuntimeDataOverrides(const RuntimeDataOverrides& overrideData)
void RuntimeComponent::TakeRuntimeDataOverrides(RuntimeDataOverrides&& overrideData)
{
m_runtimeOverrides = overrideData;
m_runtimeOverrides = AZStd::move(overrideData);
m_runtimeOverrides.EnforcePreloadBehavior();
}
@@ -54,7 +54,7 @@ namespace ScriptCanvas
const RuntimeDataOverrides& GetRuntimeDataOverrides() const;
void SetRuntimeDataOverrides(const RuntimeDataOverrides& overrideData);
void TakeRuntimeDataOverrides(RuntimeDataOverrides&& overrideData);
protected:
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
@@ -10,17 +10,17 @@
Category="Nodeables"
GeneratePropertyFriend="True"
Namespace="ScriptCanvas"
Description="Repeats the output signal the given number of times using the specified delay to space the signals out">
Description="Repeats the output signal the given number of times using the specified delay to space the signals out.">
<!-- Input tag is for an execution input that has optional data (parameters) -->
<Input Name="Start" Description="">
<Parameter Name="Repetitions" Type="Data::NumberType" DefaultValue="0.0" Description="How many times to repeat."/>
<Parameter Name="Interval" Type="Data::NumberType" DefaultValue="0.0" Description="The Interval between repetitions."/>
<Parameter Name="Interval" Type="Data::NumberType" DefaultValue="0.0" Description="The Interval between repetitions. If zero, all repititions execute immediately, before On Start"/>
</Input>
<Output Name="Complete" Description="Signaled upon node exit"/>
<Output Name="Action" Description="Signaled every repeition"/>
<Output Name="Action" Description="Signaled every repetition"/>
<PropertyInterface Property="m_timeUnitsInterface" Name="Units" Type="Input" Description="Units to represent the time in."/>
@@ -0,0 +1,178 @@
/*
* 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 <AzCore/Serialization/Json/JsonSerialization.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Serialization/DatumSerializer.h>
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<Datum>(), "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<Datum*>(outputValue);
bool isOverloadedStorage = false;
AZ_Assert(azrtti_typeid<decltype(outputDatum->m_isOverloadedStorage)>() == azrtti_typeid<decltype(isOverloadedStorage)>()
, "overloaded storage type changed and won't load properly");
result.Combine(ContinueLoadingFromJsonObjectField
( &isOverloadedStorage
, azrtti_typeid<decltype(outputDatum->m_isOverloadedStorage)>()
, inputValue
, "isOverloadedStorage"
, context));
ScriptCanvas::Data::Type scType;
AZ_Assert(azrtti_typeid<decltype(outputDatum->m_type)>() == azrtti_typeid<decltype(scType)>()
, "ScriptCanvas::Data::Type type changed and won't load properly");
result.Combine(ContinueLoadingFromJsonObjectField
( &scType
, azrtti_typeid<decltype(outputDatum->m_type)>()
, inputValue
, "scriptCanvasType"
, 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<void>(&storage), typeId, inputValue, "value", context));
} // datum storage end
AZStd::string label;
AZ_Assert(azrtti_typeid<decltype(outputDatum->m_datumLabel)>() == azrtti_typeid<decltype(label)>()
, "m_datumLabel type changed and won't load properly");
result.Combine(ContinueLoadingFromJsonObjectField
( &label
, azrtti_typeid<decltype(outputDatum->m_datumLabel)>()
, inputValue
, "label"
, context));
Datum copy(scType, Datum::eOriginality::Original, AZStd::any_cast<void>(&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<Datum>(), "DatumSerializer Store against value typeID that was not Datum");
AZ_Assert(inputValue, "DatumSerializer Store against null inputValue pointer ");
auto inputScriptDataPtr = reinterpret_cast<const Datum*>(inputValue);
auto defaultScriptDataPtr = reinterpret_cast<const Datum*>(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_typeid<decltype(inputScriptDataPtr->m_isOverloadedStorage)>()
, context));
result.Combine(ContinueStoringToJsonObjectField
( outputValue
, "scriptCanvasType"
, &inputScriptDataPtr->GetType()
, defaultScriptDataPtr ? &defaultScriptDataPtr->GetType() : nullptr
, azrtti_typeid<decltype(inputScriptDataPtr->GetType())>()
, 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_typeid<decltype(inputScriptDataPtr->m_datumLabel)>()
, context));
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
? "DatumSerializer Store finished saving Datum"
: "DatumSerializer Store failed to save Datum");
}
}
@@ -14,11 +14,11 @@
namespace AZ
{
class ScriptUserDataSerializer
class DatumSerializer
: public BaseJsonSerializer
{
public:
AZ_RTTI(ScriptUserDataSerializer, "{7E5FC193-8CDB-4251-A68B-F337027381DF}", BaseJsonSerializer);
AZ_RTTI(DatumSerializer, "{FBEBF833-465F-49F4-AFB1-CC9D3B25C16C}", BaseJsonSerializer);
AZ_CLASS_ALLOCATOR_DECL;
private:
@@ -8,15 +8,15 @@
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Serialization/ScriptUserDataSerializer.h>
#include <ScriptCanvas/Serialization/RuntimeVariableSerializer.h>
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<RuntimeVariable>(), "ScriptUserDataSerializer Load against output typeID that was not RuntimeVariable");
AZ_Assert(outputValue, "ScriptUserDataSerializer Load against null output");
AZ_Assert(outputValueTypeId == azrtti_typeid<RuntimeVariable>(), "RuntimeVariableSerializer Load against output typeID that was not RuntimeVariable");
AZ_Assert(outputValue, "RuntimeVariableSerializer Load against null output");
auto outputVariable = reinterpret_cast<RuntimeVariable*>(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<void>(&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<void>(inputAnyPtr), AZStd::any_cast<void>(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");
}
}
@@ -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 <AzCore/Memory/Memory.h>
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
#include <AzCore/Serialization/SerializeContext.h>
namespace AZ
{
class RuntimeVariableSerializer
: public BaseJsonSerializer
{
public:
AZ_RTTI(RuntimeVariableSerializer, "{7E5FC193-8CDB-4251-A68B-F337027381DF}", 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;
};
}
@@ -23,7 +23,8 @@
#include <ScriptCanvas/Execution/ExecutionPerformanceTimer.h>
#include <ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h>
#include <ScriptCanvas/Execution/RuntimeComponent.h>
#include <ScriptCanvas/Serialization/ScriptUserDataSerializer.h>
#include <ScriptCanvas/Serialization/RuntimeVariableSerializer.h>
#include <ScriptCanvas/Serialization/DatumSerializer.h>
#include <ScriptCanvas/SystemComponent.h>
#include <ScriptCanvas/Variable/GraphVariableManagerComponent.h>
@@ -87,8 +88,13 @@ namespace ScriptCanvas
if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast<AZ::JsonRegistrationContext*>(context))
{
jsonContext->Serializer<AZ::ScriptUserDataSerializer>()
->HandlesType<RuntimeVariable>();
jsonContext->Serializer<AZ::RuntimeVariableSerializer>()
->HandlesType<RuntimeVariable>()
;
jsonContext->Serializer<AZ::DatumSerializer>()
->HandlesType<Datum>()
;
}
#if defined(SC_EXECUTION_TRACE_ENABLED)
@@ -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