diff --git a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.cpp index 3bcd940a01..c1b557c9c4 100644 --- a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.cpp @@ -408,7 +408,7 @@ namespace ScriptCanvasEditor::Nodes AZ::BehaviorAzEventDescription behaviorAzEventDesc; AZ::AttributeReader azEventDescAttributeReader(nullptr, azEventDescAttribute); azEventDescAttributeReader.Read(behaviorAzEventDesc); - if(behaviorAzEventDesc.m_eventName.empty()) + if (behaviorAzEventDesc.m_eventName.empty()) { AZ_Error("NodeUtils", false, "Cannot create an AzEvent node with empty event name") return {}; diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp index 38def487e6..390dbaf0fb 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp @@ -140,21 +140,10 @@ namespace // If the reflected method returns an AZ::Event, reflect it to the SerializeContext if (AZ::MethodReturnsAzEventByReferenceOrPointer(method)) { - AZ::SerializeContext* serializeContext{}; - AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext); const AZ::BehaviorParameter* resultParameter = method.GetResult(); - AZ::SerializeContext::ClassData classData; - classData.m_name = resultParameter->m_name; - classData.m_typeId = resultParameter->m_typeId; - classData.m_azRtti = resultParameter->m_azRtti; - - auto EventPlaceholderAnyCreator = [](AZ::SerializeContext*) -> AZStd::any - { - return AZStd::make_any(); - }; - serializeContext->RegisterType(resultParameter->m_typeId, AZStd::move(classData), EventPlaceholderAnyCreator); - + ScriptCanvas::ReflectEventTypeOnDemand(resultParameter->m_typeId, resultParameter->m_name, resultParameter->m_azRtti); } + nodePaletteModel.RegisterClassNode(categoryPath, behaviorClass ? behaviorClass->m_name : "", name, &method, &behaviorContext, propertyStatus, isOverloaded); } @@ -177,19 +166,8 @@ namespace // If the reflected method returns an AZ::Event, reflect it to the SerializeContext if (AZ::MethodReturnsAzEventByReferenceOrPointer(behaviorMethod)) { - AZ::SerializeContext* serializeContext{}; - AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext); const AZ::BehaviorParameter* resultParameter = behaviorMethod.GetResult(); - AZ::SerializeContext::ClassData classData; - classData.m_name = resultParameter->m_name; - classData.m_typeId = resultParameter->m_typeId; - classData.m_azRtti = resultParameter->m_azRtti; - - auto EventPlaceholderAnyCreator = [](AZ::SerializeContext*) -> AZStd::any - { - return AZStd::make_any(); - }; - serializeContext->RegisterType(resultParameter->m_typeId, AZStd::move(classData), EventPlaceholderAnyCreator); + ScriptCanvas::ReflectEventTypeOnDemand(resultParameter->m_typeId, resultParameter->m_name, resultParameter->m_azRtti); } nodePaletteModel.RegisterMethodNode(behaviorContext, behaviorMethod); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp index c45dc01c35..1986eb653e 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp @@ -153,4 +153,22 @@ namespace ScriptCanvas grammarVersion = GrammarVersion::Current; runtimeVersion = RuntimeVersion::Current; } + + void ReflectEventTypeOnDemand(const AZ::TypeId& typeId, AZStd::string_view name, AZ::IRttiHelper* rttiHelper) + { + AZ::SerializeContext* serializeContext{}; + AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext); + AZ::SerializeContext::ClassData classData; + classData.m_name = name.data(); + classData.m_typeId = typeId; + classData.m_azRtti = rttiHelper; + + auto EventPlaceholderAnyCreator = [](AZ::SerializeContext*) -> AZStd::any + { + return AZStd::make_any(); + }; + + serializeContext->RegisterType(typeId, AZStd::move(classData), EventPlaceholderAnyCreator); + } + } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h index 76542d6097..170e4c5acb 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h @@ -279,6 +279,8 @@ namespace ScriptCanvas bool m_wasAdded = false; AZ::Entity* m_buildEntity = nullptr; }; + + void ReflectEventTypeOnDemand(const AZ::TypeId& typeId, AZStd::string_view name, AZ::IRttiHelper* rttiHelper = nullptr); } namespace AZStd diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp index 5bfb69b11e..37d6e2c35f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp @@ -6,12 +6,27 @@ * */ +#include #include #include #include using namespace ScriptCanvas; +namespace DatumSerializerCpp +{ + bool IsEventInput(const AZ::Uuid& inputType) + { + AZ::BehaviorContext* behaviorContext = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(behaviorContext, &AZ::ComponentApplicationRequests::GetBehaviorContext); + AZ_Assert(behaviorContext, "Can't serialize data properly without checking the type, for which we need behavior context!"); + auto bcClassIter = behaviorContext->m_typeToClassMap.find(inputType); + return bcClassIter != behaviorContext->m_typeToClassMap.end() + && bcClassIter->second->m_azRtti + && bcClassIter->second->m_azRtti->GetGenericTypeId() == azrtti_typeid(); + } +} + namespace AZ { AZ_CLASS_ALLOCATOR_IMPL(DatumSerializer, SystemAllocator, 0); @@ -57,7 +72,7 @@ namespace AZ return context.Report ( JSR::Tasks::ReadField , JSR::Outcomes::Missing - , "DatumSerializer::Load failed to load the 'isNullPointer'' member"); + , "DatumSerializer::Load failed to load the 'isNullPointer' member"); } if (isNullPointerMember->value.GetBool()) @@ -159,11 +174,13 @@ namespace AZ , azrtti_typeidGetType())>() , context)); + // datum storage begin auto inputObjectSource = inputScriptDataPtr->GetAsDanger(); - outputValue.AddMember("isNullPointer", rapidjson::Value(inputObjectSource == nullptr), context.GetJsonAllocator()); + const bool isNullPointer = inputObjectSource == nullptr || DatumSerializerCpp::IsEventInput(inputScriptDataPtr->GetType().GetAZType()); + outputValue.AddMember("isNullPointer", rapidjson::Value(isNullPointer), context.GetJsonAllocator()); - if (inputObjectSource) + if (!isNullPointer) { rapidjson::Value typeValue; result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->GetType().GetAZType(), context));