diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp index e4596b5334..92aa1dddc7 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp @@ -58,7 +58,7 @@ namespace ScriptCanvasEditor } else { - resultHash = ScriptCanvas::NodeUtils::ConstructMethodNodeIdentifier(classMethodTreeItem->GetClassMethodName(), classMethodTreeItem->GetMethodName()); + resultHash = ScriptCanvas::NodeUtils::ConstructMethodNodeIdentifier(classMethodTreeItem->GetClassMethodName(), classMethodTreeItem->GetMethodName(), classMethodTreeItem->GetPropertyStatus()); } } else if (auto globalMethodTreeItem = azrtti_cast(treeItem); globalMethodTreeItem != nullptr) diff --git a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.cpp index 62905947a8..07c96aba82 100644 --- a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.cpp @@ -167,7 +167,7 @@ namespace ScriptCanvasEditor::Nodes return nodeIdPair; } - NodeIdPair CreateObjectMethodNode(AZStd::string_view className, AZStd::string_view methodName, const ScriptCanvas::ScriptCanvasId& scriptCanvasId) + NodeIdPair CreateObjectMethodNode(AZStd::string_view className, AZStd::string_view methodName, const ScriptCanvas::ScriptCanvasId& scriptCanvasId, ScriptCanvas::PropertyStatus propertyStatus) { AZ_PROFILE_TIMER("ScriptCanvas", __FUNCTION__); NodeIdPair nodeIds; @@ -181,7 +181,7 @@ namespace ScriptCanvasEditor::Nodes auto* methodNode = azrtti_cast(node); ScriptCanvas::NamespacePath emptyNamespacePath; - methodNode->InitializeBehaviorMethod(emptyNamespacePath, className, methodName); + methodNode->InitializeBehaviorMethod(emptyNamespacePath, className, methodName, propertyStatus); AZStd::string_view displayName = methodNode->GetName(); scriptCanvasEntity->SetName(AZStd::string::format("SC-Node(%.*s)", aznumeric_cast(displayName.size()), displayName.data())); @@ -208,7 +208,7 @@ namespace ScriptCanvasEditor::Nodes auto* methodNode = azrtti_cast(node); ScriptCanvas::NamespacePath emptyNamespacePath; - methodNode->InitializeBehaviorMethod(emptyNamespacePath, className, methodName); + methodNode->InitializeBehaviorMethod(emptyNamespacePath, className, methodName, ScriptCanvas::PropertyStatus::None); AZStd::string_view displayName = methodNode->GetName(); scriptCanvasEntity->SetName(AZStd::string::format("SC-Node(%.*s)", aznumeric_cast(displayName.size()), displayName.data())); diff --git a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.h b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.h index fa81ccfe8e..f4f0378333 100644 --- a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.h +++ b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeCreateUtils.h @@ -34,7 +34,7 @@ namespace ScriptCanvasEditor::Nodes AZStd::pair CreateAndGetNode(const AZ::Uuid& classData, const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const StyleConfiguration& styleConfiguration, AZStd::function = nullptr); NodeIdPair CreateNode(const AZ::Uuid& classData, const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const StyleConfiguration& styleConfiguration); NodeIdPair CreateEntityNode(const AZ::EntityId& sourceId, const ScriptCanvas::ScriptCanvasId& scriptCanvasId); - NodeIdPair CreateObjectMethodNode(AZStd::string_view className, AZStd::string_view methodName, const ScriptCanvas::ScriptCanvasId& scriptCanvasId); + NodeIdPair CreateObjectMethodNode(AZStd::string_view className, AZStd::string_view methodName, const ScriptCanvas::ScriptCanvasId& scriptCanvasId, ScriptCanvas::PropertyStatus propertyStatus); NodeIdPair CreateObjectMethodOverloadNode(AZStd::string_view className, AZStd::string_view methodName, const ScriptCanvas::ScriptCanvasId& scriptCanvasGraphId); NodeIdPair CreateGlobalMethodNode(AZStd::string_view methodName, const ScriptCanvas::ScriptCanvasId& scriptCanvasId); NodeIdPair CreateEbusWrapperNode(AZStd::string_view busName, const ScriptCanvas::ScriptCanvasId& scriptCanvasId); diff --git a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp index a903c9f885..c3929e6bc4 100644 --- a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp @@ -327,12 +327,14 @@ namespace ScriptCanvasEditor::Nodes contextGroup = TranslationContextGroup::EbusSender; break; case ScriptCanvas::MethodType::Member: + case ScriptCanvas::MethodType::Getter: + case ScriptCanvas::MethodType::Setter: case ScriptCanvas::MethodType::Free: graphCanvasEntity->CreateComponent(); contextGroup = TranslationContextGroup::ClassMethod; break; default: - AZ_Error("ScriptCanvas", false, "Invalid method node type, node creation failed. This node nodes to be deleted."); + AZ_Error("ScriptCanvas", false, "Invalid method node type, node creation failed. This node needs to be deleted."); break; } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.cpp index 4ae7d94560..474af058d3 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.cpp @@ -52,14 +52,16 @@ namespace ScriptCanvasEditor ->Field("BusName", &CreateEBusSenderMimeEvent::m_busName) ->Field("EventName", &CreateEBusSenderMimeEvent::m_eventName) ->Field("IsOverload", &CreateEBusSenderMimeEvent::m_isOverload) + ->Field("propertyStatus", &CreateEBusSenderMimeEvent::m_propertyStatus) ; } } - CreateEBusSenderMimeEvent::CreateEBusSenderMimeEvent(AZStd::string_view busName, AZStd::string_view eventName, bool isOverload) + CreateEBusSenderMimeEvent::CreateEBusSenderMimeEvent(AZStd::string_view busName, AZStd::string_view eventName, bool isOverload, ScriptCanvas::PropertyStatus propertyStatus) : m_busName(busName.data()) , m_eventName(eventName.data()) , m_isOverload(isOverload) + , m_propertyStatus(propertyStatus) { } @@ -71,7 +73,7 @@ namespace ScriptCanvasEditor } else { - return Nodes::CreateObjectMethodNode(m_busName, m_eventName, scriptCanvasId); + return Nodes::CreateObjectMethodNode(m_busName, m_eventName, scriptCanvasId, m_propertyStatus); } } @@ -91,13 +93,14 @@ namespace ScriptCanvasEditor return defaultIcon; } - EBusSendEventPaletteTreeItem::EBusSendEventPaletteTreeItem(AZStd::string_view busName, AZStd::string_view eventName, const ScriptCanvas::EBusBusId& busIdentifier, const ScriptCanvas::EBusEventId& eventIdentifier, bool isOverload) + EBusSendEventPaletteTreeItem::EBusSendEventPaletteTreeItem(AZStd::string_view busName, AZStd::string_view eventName, const ScriptCanvas::EBusBusId& busIdentifier, const ScriptCanvas::EBusEventId& eventIdentifier, bool isOverload, ScriptCanvas::PropertyStatus propertyStatus) : DraggableNodePaletteTreeItem(eventName, ScriptCanvasEditor::AssetEditorId) , m_busName(busName.data()) , m_eventName(eventName.data()) , m_busId(busIdentifier) , m_eventId(eventIdentifier) , m_isOverload(isOverload) + , m_propertyStatus(propertyStatus) { AZStd::string displayEventName = TranslationHelper::GetKeyTranslation(TranslationContextGroup::EbusSender, m_busName.toUtf8().data(), m_eventName.toUtf8().data(), TranslationItemType::Node, TranslationKeyId::Name); @@ -122,7 +125,7 @@ namespace ScriptCanvasEditor GraphCanvas::GraphCanvasMimeEvent* EBusSendEventPaletteTreeItem::CreateMimeEvent() const { - return aznew CreateEBusSenderMimeEvent(m_busName.toUtf8().data(), m_eventName.toUtf8().data(), m_isOverload); + return aznew CreateEBusSenderMimeEvent(m_busName.toUtf8().data(), m_eventName.toUtf8().data(), m_isOverload, ScriptCanvas::PropertyStatus::None); } AZStd::string EBusSendEventPaletteTreeItem::GetBusName() const @@ -145,6 +148,11 @@ namespace ScriptCanvasEditor return m_eventId; } + ScriptCanvas::PropertyStatus EBusSendEventPaletteTreeItem::GetPropertyStatus() const + { + return m_propertyStatus; + } + bool EBusSendEventPaletteTreeItem::IsOverload() const { return m_isOverload; diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.h b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.h index b5181754c4..b3bd771109 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.h @@ -28,7 +28,7 @@ namespace ScriptCanvasEditor static void Reflect(AZ::ReflectContext* reflectContext); CreateEBusSenderMimeEvent() = default; - CreateEBusSenderMimeEvent(AZStd::string_view busName, AZStd::string_view eventName, bool isOverload); + CreateEBusSenderMimeEvent(AZStd::string_view busName, AZStd::string_view eventName, bool isOverload, ScriptCanvas::PropertyStatus propertyStatus); ~CreateEBusSenderMimeEvent() = default; protected: @@ -36,6 +36,7 @@ namespace ScriptCanvasEditor private: bool m_isOverload; + ScriptCanvas::PropertyStatus m_propertyStatus = ScriptCanvas::PropertyStatus::None; AZStd::string m_busName; AZStd::string m_eventName; }; @@ -50,7 +51,7 @@ namespace ScriptCanvasEditor AZ_CLASS_ALLOCATOR(EBusSendEventPaletteTreeItem, AZ::SystemAllocator, 0); AZ_RTTI(EBusSendEventPaletteTreeItem, "{26258B0A-8E2C-434D-ACAD-3DE85E64A4F8}", GraphCanvas::DraggableNodePaletteTreeItem); - EBusSendEventPaletteTreeItem(AZStd::string_view busName, AZStd::string_view eventName, const ScriptCanvas::EBusBusId& busId, const ScriptCanvas::EBusEventId& eventIdentifier, bool isOverload); + EBusSendEventPaletteTreeItem(AZStd::string_view busName, AZStd::string_view eventName, const ScriptCanvas::EBusBusId& busId, const ScriptCanvas::EBusEventId& eventIdentifier, bool isOverload, ScriptCanvas::PropertyStatus propertyStatus); ~EBusSendEventPaletteTreeItem() = default; GraphCanvas::GraphCanvasMimeEvent* CreateMimeEvent() const override; @@ -63,6 +64,8 @@ namespace ScriptCanvasEditor bool IsOverload() const; + ScriptCanvas::PropertyStatus GetPropertyStatus() const; + private: bool m_isOverload; QString m_busName; @@ -70,6 +73,7 @@ namespace ScriptCanvasEditor ScriptCanvas::EBusBusId m_busId; ScriptCanvas::EBusEventId m_eventId; + ScriptCanvas::PropertyStatus m_propertyStatus = ScriptCanvas::PropertyStatus::None; }; // diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.cpp index 912a76df22..8341303ff4 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.cpp @@ -51,14 +51,16 @@ namespace ScriptCanvasEditor ->Field("ClassName", &CreateClassMethodMimeEvent::m_className) ->Field("MethodName", &CreateClassMethodMimeEvent::m_methodName) ->Field("IsOverload", &CreateClassMethodMimeEvent::m_isOverload) + ->Field("propertyStatus", &CreateClassMethodMimeEvent::m_propertyStatus) ; } } - CreateClassMethodMimeEvent::CreateClassMethodMimeEvent(const QString& className, const QString& methodName, bool isOverload) + CreateClassMethodMimeEvent::CreateClassMethodMimeEvent(const QString& className, const QString& methodName, bool isOverload, ScriptCanvas::PropertyStatus propertyStatus) : m_className(className.toUtf8().data()) , m_methodName(methodName.toUtf8().data()) , m_isOverload(isOverload) + , m_propertyStatus(propertyStatus) { } @@ -70,7 +72,7 @@ namespace ScriptCanvasEditor } else { - return Nodes::CreateObjectMethodNode(m_className, m_methodName, scriptCanvasId); + return Nodes::CreateObjectMethodNode(m_className, m_methodName, scriptCanvasId, m_propertyStatus); } } @@ -78,11 +80,12 @@ namespace ScriptCanvasEditor // ClassMethodEventPaletteTreeItem //////////////////////////////////// - ClassMethodEventPaletteTreeItem::ClassMethodEventPaletteTreeItem(AZStd::string_view className, AZStd::string_view methodName, bool isOverload) + ClassMethodEventPaletteTreeItem::ClassMethodEventPaletteTreeItem(AZStd::string_view className, AZStd::string_view methodName, bool isOverload, ScriptCanvas::PropertyStatus propertyStatus) : DraggableNodePaletteTreeItem(methodName, ScriptCanvasEditor::AssetEditorId) , m_className(className.data()) , m_methodName(methodName.data()) , m_isOverload(isOverload) + , m_propertyStatus(propertyStatus) { AZStd::string displayMethodName = TranslationHelper::GetKeyTranslation(TranslationContextGroup::ClassMethod, m_className.toUtf8().data(), m_methodName.toUtf8().data(), TranslationItemType::Node, TranslationKeyId::Name); @@ -95,6 +98,15 @@ namespace ScriptCanvasEditor SetName(displayMethodName.c_str()); } + if (propertyStatus == ScriptCanvas::PropertyStatus::Getter) + { + SetName(AZStd::string::format("Get %s", GetName().toUtf8().data()).data()); + } + else if (propertyStatus == ScriptCanvas::PropertyStatus::Setter) + { + SetName(AZStd::string::format("Set %s", GetName().toUtf8().data()).data()); + } + AZStd::string displayEventTooltip = TranslationHelper::GetKeyTranslation(TranslationContextGroup::ClassMethod, m_className.toUtf8().data(), m_methodName.toUtf8().data(), TranslationItemType::Node, TranslationKeyId::Tooltip); if (!displayEventTooltip.empty()) @@ -107,7 +119,7 @@ namespace ScriptCanvasEditor GraphCanvas::GraphCanvasMimeEvent* ClassMethodEventPaletteTreeItem::CreateMimeEvent() const { - return aznew CreateClassMethodMimeEvent(m_className, m_methodName, m_isOverload); + return aznew CreateClassMethodMimeEvent(m_className, m_methodName, m_isOverload, m_propertyStatus); } AZStd::string ClassMethodEventPaletteTreeItem::GetClassMethodName() const @@ -125,6 +137,11 @@ namespace ScriptCanvasEditor return m_isOverload; } + ScriptCanvas::PropertyStatus ClassMethodEventPaletteTreeItem::GetPropertyStatus() const + { + return m_propertyStatus; + } + //! Implementation of the CreateGlobalMethod Mime Event void CreateGlobalMethodMimeEvent::Reflect(AZ::ReflectContext* reflectContext) { diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.h b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.h index 38a2be88f5..66b29ef3b9 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.h @@ -30,7 +30,7 @@ namespace ScriptCanvasEditor static void Reflect(AZ::ReflectContext* reflectContext); CreateClassMethodMimeEvent() = default; - CreateClassMethodMimeEvent(const QString& className, const QString& methodName, bool isOverload); + CreateClassMethodMimeEvent(const QString& className, const QString& methodName, bool isOverload, ScriptCanvas::PropertyStatus); ~CreateClassMethodMimeEvent() = default; protected: @@ -40,6 +40,7 @@ namespace ScriptCanvasEditor bool m_isOverload = false; AZStd::string m_className; AZStd::string m_methodName; + ScriptCanvas::PropertyStatus m_propertyStatus = ScriptCanvas::PropertyStatus::None; }; class ClassMethodEventPaletteTreeItem @@ -49,7 +50,7 @@ namespace ScriptCanvasEditor AZ_CLASS_ALLOCATOR(ClassMethodEventPaletteTreeItem, AZ::SystemAllocator, 0); AZ_RTTI(ClassMethodEventPaletteTreeItem, "{96F93970-F38A-4F08-8DC5-D52FCCE34E25}", GraphCanvas::DraggableNodePaletteTreeItem); - ClassMethodEventPaletteTreeItem(AZStd::string_view className, AZStd::string_view methodName, bool isOverload); + ClassMethodEventPaletteTreeItem(AZStd::string_view className, AZStd::string_view methodName, bool isOverload, ScriptCanvas::PropertyStatus propertyStatus); ~ClassMethodEventPaletteTreeItem() = default; GraphCanvas::GraphCanvasMimeEvent* CreateMimeEvent() const override; @@ -57,11 +58,13 @@ namespace ScriptCanvasEditor AZStd::string GetClassMethodName() const; AZStd::string GetMethodName() const; bool IsOverload() const; + ScriptCanvas::PropertyStatus GetPropertyStatus() const; private: bool m_isOverload = false; QString m_className; QString m_methodName; + ScriptCanvas::PropertyStatus m_propertyStatus = ScriptCanvas::PropertyStatus::None; }; // diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp index 73b6551e85..8b00b5b71b 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp @@ -129,6 +129,7 @@ namespace , const AZ::BehaviorClass* behaviorClass , const AZStd::string& name , const AZ::BehaviorMethod& method + , ScriptCanvas::PropertyStatus propertyStatus , bool isOverloaded) { if (IsDeprecated(method.m_attributes)) @@ -170,7 +171,7 @@ namespace serializeContext->RegisterType(resultParameter->m_typeId, AZStd::move(classData), EventPlaceholderAnyCreator); } - nodePaletteModel.RegisterClassNode(categoryPath, behaviorClass ? behaviorClass->m_name : "", name, &method, &behaviorContext, isOverloaded); + nodePaletteModel.RegisterClassNode(categoryPath, behaviorClass ? behaviorClass->m_name : "", name, &method, &behaviorContext, propertyStatus, isOverloaded); } void RegisterGlobalMethod(ScriptCanvasEditor::NodePaletteModel& nodePaletteModel, const AZ::BehaviorContext& behaviorContext, @@ -556,6 +557,19 @@ namespace categoryPath.append(displayName.c_str()); } + for (auto property : behaviorClass->m_properties) + { + if (property.second->m_getter) + { + RegisterMethod(nodePaletteModel, behaviorContext, categoryPath, behaviorClass, property.first, *property.second->m_getter, ScriptCanvas::PropertyStatus::Getter, behaviorClass->IsMethodOverloaded(property.first)); + } + + if (property.second->m_setter) + { + RegisterMethod(nodePaletteModel, behaviorContext, categoryPath, behaviorClass, property.first, *property.second->m_setter, ScriptCanvas::PropertyStatus::Setter, behaviorClass->IsMethodOverloaded(property.first)); + } + } + for (auto methodIter : behaviorClass->m_methods) { if (!IsExplicitOverload(*methodIter.second)) @@ -567,7 +581,7 @@ namespace continue; } - RegisterMethod(nodePaletteModel, behaviorContext, categoryPath, behaviorClass, methodIter.first, *methodIter.second, behaviorClass->IsMethodOverloaded(methodIter.first)); + RegisterMethod(nodePaletteModel, behaviorContext, categoryPath, behaviorClass, methodIter.first, *methodIter.second, ScriptCanvas::PropertyStatus::None, behaviorClass->IsMethodOverloaded(methodIter.first)); } } } @@ -579,7 +593,7 @@ namespace { for (const AZ::ExplicitOverloadInfo& explicitOverload : behaviorContext.m_explicitOverloads) { - RegisterMethod(nodePaletteModel, behaviorContext, explicitOverload.m_categoryPath, nullptr, explicitOverload.m_name, *explicitOverload.m_overloads.begin()->first, true); + RegisterMethod(nodePaletteModel, behaviorContext, explicitOverload.m_categoryPath, nullptr, explicitOverload.m_name, *explicitOverload.m_overloads.begin()->first, ScriptCanvas::PropertyStatus::None, true); } } @@ -717,7 +731,7 @@ namespace } const bool isOverload{ false }; // overloaded events are not trivially supported - nodePaletteModel.RegisterEBusSenderNodeModelInformation(categoryPath, behaviorEbus.m_name, event.first, ScriptCanvas::EBusBusId(behaviorEbus.m_name.c_str()), ScriptCanvas::EBusEventId(event.first.c_str()), event.second, isOverload); + nodePaletteModel.RegisterEBusSenderNodeModelInformation(categoryPath, behaviorEbus.m_name, event.first, ScriptCanvas::EBusBusId(behaviorEbus.m_name.c_str()), ScriptCanvas::EBusEventId(event.first.c_str()), event.second, ScriptCanvas::PropertyStatus::None, isOverload); } } } @@ -1024,11 +1038,16 @@ namespace ScriptCanvasEditor } } - void NodePaletteModel::RegisterClassNode(const AZStd::string& categoryPath, const AZStd::string& methodClass, - const AZStd::string& methodName, const AZ::BehaviorMethod* behaviorMethod, const AZ::BehaviorContext* behaviorContext, - bool isOverload) + void NodePaletteModel::RegisterClassNode + ( const AZStd::string& categoryPath + , const AZStd::string& methodClass + , const AZStd::string& methodName + , const AZ::BehaviorMethod* behaviorMethod + , const AZ::BehaviorContext* behaviorContext + , ScriptCanvas::PropertyStatus propertyStatus + , bool isOverload) { - ScriptCanvas::NodeTypeIdentifier nodeIdentifier = isOverload ? ScriptCanvas::NodeUtils::ConstructMethodOverloadedNodeIdentifier(methodName) : ScriptCanvas::NodeUtils::ConstructMethodNodeIdentifier(methodClass, methodName); + ScriptCanvas::NodeTypeIdentifier nodeIdentifier = isOverload ? ScriptCanvas::NodeUtils::ConstructMethodOverloadedNodeIdentifier(methodName) : ScriptCanvas::NodeUtils::ConstructMethodNodeIdentifier(methodClass, methodName, propertyStatus); auto registerIter = m_registeredNodes.find(nodeIdentifier); @@ -1039,7 +1058,7 @@ namespace ScriptCanvasEditor methodModelInformation->m_nodeIdentifier = nodeIdentifier; methodModelInformation->m_classMethod = methodClass; methodModelInformation->m_methodName = methodName; - + methodModelInformation->m_propertyStatus = propertyStatus; methodModelInformation->m_titlePaletteOverride = "MethodNodeTitlePalette"; methodModelInformation->m_displayName = TranslationHelper::GetKeyTranslation(TranslationContextGroup::ClassMethod, methodClass.c_str(), methodName.c_str(), TranslationItemType::Node, TranslationKeyId::Name); @@ -1198,7 +1217,15 @@ namespace ScriptCanvasEditor } } - void NodePaletteModel::RegisterEBusSenderNodeModelInformation(AZStd::string_view categoryPath, AZStd::string_view busName, AZStd::string_view eventName, const ScriptCanvas::EBusBusId& busId, const ScriptCanvas::EBusEventId& eventId, const AZ::BehaviorEBusEventSender&, bool isOverload) + void NodePaletteModel::RegisterEBusSenderNodeModelInformation + ( AZStd::string_view categoryPath + , AZStd::string_view busName + , AZStd::string_view eventName + , const ScriptCanvas::EBusBusId& busId + , const ScriptCanvas::EBusEventId& eventId + , const AZ::BehaviorEBusEventSender& + , ScriptCanvas::PropertyStatus propertyStatus + , bool isOverload) { ScriptCanvas::NodeTypeIdentifier nodeIdentifier = isOverload ? ScriptCanvas::NodeUtils::ConstructEBusEventSenderOverloadedIdentifier(busId, eventId) : ScriptCanvas::NodeUtils::ConstructEBusEventSenderIdentifier(busId, eventId); @@ -1212,6 +1239,7 @@ namespace ScriptCanvasEditor senderInformation->m_titlePaletteOverride = "MethodNodeTitlePalette"; senderInformation->m_categoryPath = categoryPath; senderInformation->m_nodeIdentifier = nodeIdentifier; + senderInformation->m_propertyStatus = propertyStatus; senderInformation->m_busName = busName; senderInformation->m_eventName = eventName; diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.h b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.h index 5ed0ff670b..3bc81c07a0 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.h @@ -83,12 +83,12 @@ namespace ScriptCanvasEditor void RepopulateModel(); void RegisterCustomNode(AZStd::string_view categoryPath, const AZ::Uuid& uuid, AZStd::string_view name, const AZ::SerializeContext::ClassData* classData); - void RegisterClassNode(const AZStd::string& categoryPath, const AZStd::string& methodClass, const AZStd::string& methodName, const AZ::BehaviorMethod* behaviorMethod, const AZ::BehaviorContext* behaviorContext, bool isOverload); + void RegisterClassNode(const AZStd::string& categoryPath, const AZStd::string& methodClass, const AZStd::string& methodName, const AZ::BehaviorMethod* behaviorMethod, const AZ::BehaviorContext* behaviorContext, ScriptCanvas::PropertyStatus propertyStatus, bool isOverload); void RegisterMethodNode(const AZ::BehaviorContext& behaviorContext, const AZ::BehaviorMethod& behaviorMethod); void RegisterGlobalConstant(const AZ::BehaviorContext& behaviorContext, const AZ::BehaviorMethod& behaviorMethod); void RegisterEBusHandlerNodeModelInformation(AZStd::string_view categoryPath, AZStd::string_view busName, AZStd::string_view eventName, const ScriptCanvas::EBusBusId& busId, const AZ::BehaviorEBusHandler::BusForwarderEvent& forwardEvent); - void RegisterEBusSenderNodeModelInformation(AZStd::string_view categoryPath, AZStd::string_view busName, AZStd::string_view eventName, const ScriptCanvas::EBusBusId& busId, const ScriptCanvas::EBusEventId& eventId, const AZ::BehaviorEBusEventSender& eventSender, bool isOverload); + void RegisterEBusSenderNodeModelInformation(AZStd::string_view categoryPath, AZStd::string_view busName, AZStd::string_view eventName, const ScriptCanvas::EBusBusId& busId, const ScriptCanvas::EBusEventId& eventId, const AZ::BehaviorEBusEventSender& eventSender, ScriptCanvas::PropertyStatus propertyStatus, bool isOverload); // Asset Based Registrations AZStd::vector RegisterScriptEvent(ScriptEvents::ScriptEventsAsset* scriptEventAsset); @@ -164,6 +164,7 @@ namespace ScriptCanvasEditor bool m_isOverload{}; AZStd::string m_classMethod; AZStd::string m_methodName; + ScriptCanvas::PropertyStatus m_propertyStatus = ScriptCanvas::PropertyStatus::None; }; struct GlobalMethodNodeModelInformation @@ -202,6 +203,7 @@ namespace ScriptCanvasEditor ScriptCanvas::EBusBusId m_busId; ScriptCanvas::EBusEventId m_eventId; + ScriptCanvas::PropertyStatus m_propertyStatus = ScriptCanvas::PropertyStatus::None; }; struct ScriptEventHandlerNodeModelInformation diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp index 5d377fe241..062db5e315 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp @@ -111,7 +111,7 @@ namespace ScriptCanvasEditor } else if (auto methodNodeModelInformation = azrtti_cast(modelInformation)) { - createdItem = parentItem->CreateChildNode(methodNodeModelInformation->m_classMethod, methodNodeModelInformation->m_methodName, methodNodeModelInformation->m_isOverload); + createdItem = parentItem->CreateChildNode(methodNodeModelInformation->m_classMethod, methodNodeModelInformation->m_methodName, methodNodeModelInformation->m_isOverload, methodNodeModelInformation->m_propertyStatus); } else if (auto globalMethodNodeModelInformation = azrtti_cast(modelInformation); globalMethodNodeModelInformation != nullptr) @@ -130,7 +130,7 @@ namespace ScriptCanvasEditor { if (!azrtti_istypeof(ebusSenderNodeModelInformation)) { - createdItem = parentItem->CreateChildNode(ebusSenderNodeModelInformation->m_busName, ebusSenderNodeModelInformation->m_eventName, ebusSenderNodeModelInformation->m_busId, ebusSenderNodeModelInformation->m_eventId, ebusSenderNodeModelInformation->m_isOverload); + createdItem = parentItem->CreateChildNode(ebusSenderNodeModelInformation->m_busName, ebusSenderNodeModelInformation->m_eventName, ebusSenderNodeModelInformation->m_busId, ebusSenderNodeModelInformation->m_eventId, ebusSenderNodeModelInformation->m_isOverload, ebusSenderNodeModelInformation->m_propertyStatus); } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h index d6ac7e5482..5b1e5eee76 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h @@ -88,6 +88,13 @@ namespace ScriptCanvas Current, }; + enum class PropertyStatus : AZ::u8 + { + Getter, + None, + Setter, + }; + struct VersionData { AZ_TYPE_INFO(VersionData, "{14C629F6-467B-46FE-8B63-48FDFCA42175}"); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/MethodConfiguration.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/MethodConfiguration.h index be1f4b39b8..049404ee6e 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/MethodConfiguration.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/MethodConfiguration.h @@ -33,6 +33,8 @@ namespace ScriptCanvas Event, Free, Member, + Getter, + Setter, Count, }; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h index d3d36ae71b..a2d06686e9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h @@ -394,6 +394,7 @@ namespace ScriptCanvas AZ::Uuid m_type = AZ::Uuid::CreateNull(); AZStd::string m_className; AZStd::string m_methodName; + PropertyStatus m_propertyStatus = PropertyStatus::None; bool IsValid() { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp index b642ef3889..83680aa7de 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp @@ -104,8 +104,7 @@ namespace ScriptCanvas const FunctorOut& Nodeable::GetExecutionOutChecked(size_t index) const { - - if (index >= m_outs.size() && m_outs[index]) + if (index >= m_outs.size() || !m_outs[index]) { return m_noOpFunctor; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp index a5a98b5444..e16a3bc815 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp @@ -537,6 +537,20 @@ namespace ScriptCanvas return azrtti_istypeof(execution->GetId().m_node); } + bool IsClassPropertyRead(ExecutionTreeConstPtr execution) + { + return execution->GetSymbol() == Symbol::FunctionCall + && azrtti_istypeof(execution->GetId().m_node) + && azrtti_cast(execution->GetId().m_node)->GetPropertyStatus() == PropertyStatus::Getter; + } + + bool IsClassPropertyWrite(ExecutionTreeConstPtr execution) + { + return execution->GetSymbol() == Symbol::FunctionCall + && azrtti_istypeof(execution->GetId().m_node) + && azrtti_cast(execution->GetId().m_node)->GetPropertyStatus() == PropertyStatus::Setter; + } + bool IsCodeConstructable(Grammar::VariableConstPtr value) { return Data::IsValueType(value->m_datum.GetType()) @@ -1280,7 +1294,6 @@ namespace ScriptCanvas return identifier; } - ExecutionTraversalResult TraverseExecutionConnectionsRecurse(const EndpointsResolved& nextEndpoints, AZStd::unordered_set& previousIns, GraphExecutionPathTraversalListener& listener); ExecutionTraversalResult TraverseExecutionConnectionsRecurse(const EndpointResolved& in, AZStd::unordered_set& previousIns, GraphExecutionPathTraversalListener& listener); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h index 1e2d102d2d..b5fd606fba 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h @@ -79,6 +79,10 @@ namespace ScriptCanvas bool IsBreak(const ExecutionTreeConstPtr& execution); + bool IsClassPropertyRead(ExecutionTreeConstPtr execution); + + bool IsClassPropertyWrite(ExecutionTreeConstPtr execution); + bool IsCodeConstructable(VariableConstPtr value); bool IsCycle(const Node& node); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp index 836c3facab..b6f7bc2972 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp @@ -193,6 +193,22 @@ namespace ScriptCanvas return DynamicDataType::Any; } + PropertyStatus Method::GetPropertyStatus() const + { + switch (m_methodType) + { + case MethodType::Getter: + return PropertyStatus::Getter; + + case MethodType::Setter: + return PropertyStatus::Setter; + + default: + return PropertyStatus::None; + } + } + + void Method::InitializeMethod(const MethodConfiguration& config) { m_namespaces = config.m_namespaces ? *config.m_namespaces : m_namespaces; @@ -239,7 +255,7 @@ namespace ScriptCanvas OnInitializeOutputPost(outputConfig); } - void Method::InitializeBehaviorMethod(const NamespacePath& namespaces, AZStd::string_view className, AZStd::string_view methodName) + void Method::InitializeBehaviorMethod(const NamespacePath& namespaces, AZStd::string_view className, AZStd::string_view methodName, PropertyStatus propertyStatus) { AZ::BehaviorContext* behaviorContext = nullptr; AZ::ComponentApplicationBus::BroadcastResult(behaviorContext, &AZ::ComponentApplicationRequests::GetBehaviorContext); @@ -255,13 +271,13 @@ namespace ScriptCanvas { InitializeFree(namespaces, methodName); } - else if (auto ebusIterator = behaviorContext->m_ebuses.find(className); ebusIterator == behaviorContext->m_ebuses.end()) + else if (auto ebusIterator = behaviorContext->m_ebuses.find(className); ebusIterator != behaviorContext->m_ebuses.end()) { - InitializeClass(namespaces, className, methodName); + InitializeEvent(namespaces, className, methodName); } else { - InitializeEvent(namespaces, className, methodName); + InitializeClass(namespaces, className, methodName, propertyStatus); } } @@ -291,7 +307,7 @@ namespace ScriptCanvas } } - void Method::InitializeClass(const NamespacePath&, AZStd::string_view className, AZStd::string_view methodName) + void Method::InitializeClass(const NamespacePath&, AZStd::string_view className, AZStd::string_view methodName, PropertyStatus propertyStatus) { AZStd::lock_guard lock(m_mutex); @@ -299,9 +315,11 @@ namespace ScriptCanvas const AZ::BehaviorClass* bcClass{}; AZStd::string prettyClassName; - if (BehaviorContextUtils::FindClass(method, bcClass, className, methodName, &prettyClassName)) + if (BehaviorContextUtils::FindClass(method, bcClass, className, methodName, propertyStatus, &prettyClassName)) { - MethodConfiguration config(*method, MethodType::Member); + const auto methodType = propertyStatus == PropertyStatus::None ? MethodType::Member : propertyStatus == PropertyStatus::Getter ? MethodType::Getter : MethodType::Setter; + + MethodConfiguration config(*method, methodType); config.m_class = bcClass; config.m_namespaces = &m_namespaces; config.m_className = &className; @@ -647,8 +665,12 @@ namespace ScriptCanvas break; case MethodType::Member: + case MethodType::Getter: + case MethodType::Setter: { - if (BehaviorContextUtils::FindClass(method, bcClass, m_className, methodName, nullptr, m_warnOnMissingFunction)) + PropertyStatus status = m_methodType == MethodType::Getter ? PropertyStatus::Getter : m_methodType == MethodType::Setter ? PropertyStatus::Setter : PropertyStatus::None; + + if (BehaviorContextUtils::FindClass(method, bcClass, m_className, methodName, status, nullptr, m_warnOnMissingFunction)) { outClass = bcClass; outMethod = method; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h index b03e3aefd8..6a53054ddf 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h @@ -87,14 +87,13 @@ namespace ScriptCanvas bool IsObjectClass(AZStd::string_view objectClass) const { return objectClass.compare(m_className) == 0; } //! Attempts to initialize node with a BehaviorContext BehaviorMethod - //! If the className is empty, then the methodName is searched on the BehaviorContext - //! If className is not empty the className is used to look for a registered BehaviorEBus in the BehaviorContext - //! and if found, the methodName is searched among the BehaviorEBus events - //! Otherwise the className is used to look for a registered BehaviorClass in the BehaviorContext - //! and if found, the methodName is searched among the BehaviorClass methods - void InitializeBehaviorMethod(const NamespacePath& namespaces, AZStd::string_view className, AZStd::string_view methodName); + //! 1) If the names match an overloaded method, including one using ExplicitOverloadInfo, then that method is used. Else: + //! 2) If the class name is empty, then search for a free method is searched for in the BehaviorContext and there is a warning if not found. + //! 3) If the class name matches an ebus, methodName is searched among the BehaviorEBus events, and there is a warning if not found. + //! 4) if the class name does NOT match an ebus, className and methodName are used to look for a registered BehaviorClass in the BehaviorContext, and there is a warning if not found. + void InitializeBehaviorMethod(const NamespacePath& namespaces, AZStd::string_view className, AZStd::string_view methodName, PropertyStatus propertyStatus); - void InitializeClass(const NamespacePath& namespaces, AZStd::string_view className, AZStd::string_view methodName); + void InitializeClass(const NamespacePath& namespaces, AZStd::string_view className, AZStd::string_view methodName, PropertyStatus propertyStatus); void InitializeEvent(const NamespacePath& namespaces, AZStd::string_view busName, AZStd::string_view eventName); @@ -126,6 +125,8 @@ namespace ScriptCanvas virtual DynamicDataType GetOverloadedOutputType(size_t resultIndex) const; + PropertyStatus GetPropertyStatus() const; + protected: void ConfigureMethod(const AZ::BehaviorMethod& method, const AZ::BehaviorClass* bcClass); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp index 128ef95b63..905f68604a 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp @@ -637,6 +637,16 @@ namespace ScriptCanvas { WriteGlobalPropertyRead(execution); } + else if (Grammar::IsClassPropertyRead(execution)) + { + WriteClassPropertyRead(execution); + m_dotLua.WriteNewLine(); + } + else if (Grammar::IsClassPropertyWrite(execution)) + { + WriteClassPropertyWrite(execution); + m_dotLua.WriteNewLine(); + } else { const bool isNullCheckRequired = Grammar::IsFunctionCallNullCheckRequired(execution); @@ -1208,6 +1218,19 @@ namespace ScriptCanvas TranslateNodeableParse(); } + void GraphToLua::WriteClassPropertyRead(Grammar::ExecutionTreeConstPtr execution) + { + WriteFunctionCallInput(execution, 0, IsFormatStringInput::No); + m_dotLua.Write(".%s", Grammar::ToIdentifier(execution->GetName()).c_str()); + } + + void GraphToLua::WriteClassPropertyWrite(Grammar::ExecutionTreeConstPtr execution) + { + WriteClassPropertyRead(execution); + m_dotLua.Write(" = "); + WriteFunctionCallInput(execution, 1, IsFormatStringInput::No); + } + void GraphToLua::WriteConditionalCaseSwitch(Grammar::ExecutionTreeConstPtr execution, Grammar::Symbol symbol, const Grammar::ExecutionChild& child, size_t index) { if (symbol == Grammar::Symbol::RandomSwitch) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h index 3d4379d98d..82c865da8c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h @@ -116,6 +116,8 @@ namespace ScriptCanvas void TranslateNodeableParse(); void TranslateStaticInitialization(); void TranslateVariableInitialization(AZStd::string_view leftValue); + void WriteClassPropertyRead(Grammar::ExecutionTreeConstPtr); + void WriteClassPropertyWrite(Grammar::ExecutionTreeConstPtr); void WriteConditionalCaseSwitch(Grammar::ExecutionTreeConstPtr execution, Grammar::Symbol symbol, const Grammar::ExecutionChild& child, size_t index); enum class IsLeadingCommaRequired { No, Yes }; void WriteConstructionArgs(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.cpp index ff38b74d47..3689729338 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.cpp @@ -61,7 +61,7 @@ namespace ScriptCanvas return { typeID }; } - bool BehaviorContextUtils::FindClass(const AZ::BehaviorMethod*& outMethod, const AZ::BehaviorClass*& outClass, [[maybe_unused]] AZStd::string_view className, [[maybe_unused]] AZStd::string_view methodName, [[maybe_unused]] AZStd::string* outPrettyClassName, [[maybe_unused]] bool warnOnMissing) + bool BehaviorContextUtils::FindClass(const AZ::BehaviorMethod*& outMethod, const AZ::BehaviorClass*& outClass, [[maybe_unused]] AZStd::string_view className, [[maybe_unused]] AZStd::string_view methodName, PropertyStatus propertyStatus, [[maybe_unused]] AZStd::string* outPrettyClassName, [[maybe_unused]] bool warnOnMissing) { AZ::BehaviorContext* behaviorContext(nullptr); AZ::ComponentApplicationBus::BroadcastResult(behaviorContext, &AZ::ComponentApplicationRequests::GetBehaviorContext); @@ -81,16 +81,36 @@ namespace ScriptCanvas const AZ::BehaviorClass* behaviorClass(classIter->second); AZ_Assert(behaviorClass, "BehaviorContext Class entry %s has no class pointer", className.data()); - const auto methodIter(behaviorClass->m_methods.find(methodName.data())); - if (methodIter == behaviorClass->m_methods.end()) + + AZ::BehaviorMethod* method{}; + + if (propertyStatus == PropertyStatus::None) { - AZ_Warning("Script Canvas", !warnOnMissing, "No method by name of %s found in BehaviorContext class %s", methodName.data(), className.data()); - return false; + const auto methodIter(behaviorClass->m_methods.find(methodName.data())); + if (methodIter != behaviorClass->m_methods.end()) + { + method = methodIter->second; + propertyStatus = PropertyStatus::None; + } + else + { + AZ_Warning("Script Canvas", !warnOnMissing, "No method by name of %s found in BehaviorContext class %s", methodName.data(), className.data()); + } + } + else + { + const auto propertyIter(behaviorClass->m_properties.find(methodName.data())); + if (propertyIter == behaviorClass->m_properties.end()) + { + AZ_Warning("Script Canvas", !warnOnMissing, "No property by name of %s found in BehaviorContext class %s", methodName.data(), className.data()); + return false; + } + + method = propertyStatus == PropertyStatus::Getter ? propertyIter->second->m_getter : propertyIter->second->m_setter; } // this argument is the first argument...so perhaps remove the distinction between class and member functions, since it probably won't follow polymorphism // if it will, keep the distinction, and add the first argument separately - AZ::BehaviorMethod* method(methodIter->second); if (!method) { AZ_Warning("Script Canvas", !warnOnMissing, "BehaviorContext Method entry %s has no method pointer", methodName.data()); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.h index 057c99a774..8abe26dfd1 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/BehaviorContextUtils.h @@ -21,7 +21,7 @@ namespace ScriptCanvas class BehaviorContextUtils { public: - static bool FindClass(const AZ::BehaviorMethod*& outMethod, const AZ::BehaviorClass*& outClass, AZStd::string_view className, AZStd::string_view methodName, AZStd::string* outPrettyClassName = nullptr, bool warnOnMissing = true); + static bool FindClass(const AZ::BehaviorMethod*& outMethod, const AZ::BehaviorClass*& outClass, AZStd::string_view className, AZStd::string_view methodName, PropertyStatus propertyStatus = PropertyStatus::None, AZStd::string* outPrettyClassName = nullptr, bool warnOnMissing = true); static bool FindEBus(const AZ::BehaviorEBus*& outEBus, AZStd::string_view ebusName, bool warnOnMissing = true); static bool FindExplicitOverload(const AZ::BehaviorMethod*& outMethod, const AZ::BehaviorClass*& outClass, AZStd::string_view className, AZStd::string_view methodName, AZStd::string* outPrettyClassName = nullptr); static AZStd::string FindExposedMethodName(const AZ::BehaviorMethod& method, const AZ::BehaviorClass* behaviorClass); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.cpp index 06ad79c21d..c6849f0b12 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.cpp @@ -58,7 +58,7 @@ namespace ScriptCanvas } else { - return ConstructMethodNodeIdentifier(methodNode->GetRawMethodClassName(), methodNode->GetName()); + return ConstructMethodNodeIdentifier(methodNode->GetRawMethodClassName(), methodNode->GetName(), methodNode->GetPropertyStatus()); } } else if (auto ebusNode = azrtti_cast(scriptCanvasNode)) @@ -158,13 +158,14 @@ namespace ScriptCanvas return resultHash; } - NodeTypeIdentifier NodeUtils::ConstructMethodNodeIdentifier(AZStd::string_view methodClass, AZStd::string_view methodName) + NodeTypeIdentifier NodeUtils::ConstructMethodNodeIdentifier(AZStd::string_view methodClass, AZStd::string_view methodName, ScriptCanvas::PropertyStatus propertyStatus) { NodeTypeIdentifier resultHash = 0; AZStd::hash_combine(resultHash, AZStd::hash()(azrtti_typeid())); AZStd::hash_combine(resultHash, AZStd::hash()(methodClass)); AZStd::hash_combine(resultHash, AZStd::hash()(methodName)); + AZStd::hash_combine(resultHash, AZStd::hash()(static_cast(propertyStatus))); return resultHash; } @@ -253,7 +254,7 @@ namespace ScriptCanvas if (auto* method = azrtti_cast(node)) { ScriptCanvas::NamespacePath emptyNamespaces; - method->InitializeBehaviorMethod(emptyNamespaces, config.m_className, config.m_methodName); + method->InitializeBehaviorMethod(emptyNamespaces, config.m_className, config.m_methodName, config.m_propertyStatus); } } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.h index 0f5b0f495d..ad8356c42e 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.h @@ -38,7 +38,7 @@ namespace ScriptCanvas static NodeTypeIdentifier ConstructCustomNodeIdentifier(const AZ::Uuid& nodeId); - static NodeTypeIdentifier ConstructMethodNodeIdentifier(AZStd::string_view methodClass, AZStd::string_view methodName); + static NodeTypeIdentifier ConstructMethodNodeIdentifier(AZStd::string_view methodClass, AZStd::string_view methodName, ScriptCanvas::PropertyStatus propertyStatus); static NodeTypeIdentifier ConstructGlobalMethodNodeIdentifier(AZStd::string_view methodName); static NodeTypeIdentifier ConstructMethodOverloadedNodeIdentifier(AZStd::string_view methodName); diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_UseRawBehaviorProperties.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_UseRawBehaviorProperties.scriptcanvas new file mode 100644 index 0000000000..57e57116e0 --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_UseRawBehaviorProperties.scriptcanvas @@ -0,0 +1,2618 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h index 7f026edf58..766353c4c5 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h +++ b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h @@ -21,23 +21,24 @@ #include #include #include +#include #include #include #include +#include +#include +#include #include #include #include #include -#include #include "EntityRefTests.h" #include "ScriptCanvasTestApplication.h" #include "ScriptCanvasTestBus.h" #include "ScriptCanvasTestNodes.h" #include "ScriptCanvasTestUtilities.h" -#include -#include #define SC_EXPECT_DOUBLE_EQ(candidate, reference) EXPECT_NEAR(candidate, reference, 0.001) #define SC_EXPECT_FLOAT_EQ(candidate, reference) EXPECT_NEAR(candidate, reference, 0.001f) @@ -112,6 +113,9 @@ namespace ScriptCanvasTests ScriptCanvasTesting::Reflect(m_serializeContext); ScriptCanvasTesting::Reflect(m_behaviorContext); + ScriptCanvasTestingNodes::BehaviorContextObjectTest::Reflect(m_serializeContext); + ScriptCanvasTestingNodes::BehaviorContextObjectTest::Reflect(m_behaviorContext); + ::Nodes::InputMethodSharedDataSlotExampleNode::Reflect(m_serializeContext); ::Nodes::InputMethodSharedDataSlotExampleNode::Reflect(m_behaviorContext); ::Nodes::BranchMethodSharedDataSlotExampleNode::Reflect(m_serializeContext); diff --git a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.cpp b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.cpp index 9fc023601e..bd31edad09 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.cpp @@ -496,7 +496,7 @@ namespace ScriptCanvasTests ScriptCanvas::Nodes::Core::Method* methodNode(nullptr); SystemRequestBus::BroadcastResult(methodNode, &SystemRequests::GetNode, methodNodeID); EXPECT_TRUE(methodNode != nullptr); - methodNode->InitializeBehaviorMethod(emptyNamespaces, className, methodName); + methodNode->InitializeBehaviorMethod(emptyNamespaces, className, methodName, ScriptCanvas::PropertyStatus::None); return methodNodeID; } diff --git a/Gems/ScriptCanvasTesting/Code/Source/Nodes/BehaviorContextObjectTestNode.h b/Gems/ScriptCanvasTesting/Code/Source/Nodes/BehaviorContextObjectTestNode.h index 2460d37c02..7fa3896ff1 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Nodes/BehaviorContextObjectTestNode.h +++ b/Gems/ScriptCanvasTesting/Code/Source/Nodes/BehaviorContextObjectTestNode.h @@ -30,10 +30,10 @@ namespace ScriptCanvasTestingNodes { serializeContext->Class() ->Version(0) - ->Field("StringName", &BehaviorContextObjectTest::m_string) + ->Field("String", &BehaviorContextObjectTest::m_string) + ->Field("Name", &BehaviorContextObjectTest::m_name) ; - - + if (AZ::EditContext* editContext = serializeContext->GetEditContext()) { editContext->Class("Behavior Context Object Test", "An Object that lives within Behavior Context exclusively for testing") @@ -52,6 +52,7 @@ namespace ScriptCanvasTestingNodes ->Attribute(AZ::Script::Attributes::Category, "Tests/Behavior Context") ->Method("SetString", &BehaviorContextObjectTest::SetString) ->Method("GetString", &BehaviorContextObjectTest::GetString) + ->Property("Name", BehaviorValueProperty(&BehaviorContextObjectTest::m_name)) ; } } @@ -73,7 +74,7 @@ namespace ScriptCanvasTestingNodes } private: - + AZStd::string m_name; AZStd::string m_string; }; diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index a46bb3323b..1633b0fc51 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -90,6 +90,11 @@ public: } }; +TEST_F(ScriptCanvasTestFixture, UseRawBehaviorProperties) +{ + RunUnitTestGraph("LY_SC_UnitTest_UseRawBehaviorProperties"); +} + TEST_F(ScriptCanvasTestFixture, StringSanitization) { RunUnitTestGraph("LY_SC_UnitTest_StringSanitization");