NodeCreateUtils.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Editor/Nodes/NodeCreateUtils.h>
  9. #include <Editor/Nodes/NodeDisplayUtils.h>
  10. #include <GraphCanvas/Components/Nodes/NodeBus.h>
  11. #include <GraphCanvas/Components/Nodes/NodeTitleBus.h>
  12. #include <GraphCanvas/GraphCanvasBus.h>
  13. #include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
  14. #include <ScriptCanvas/Core/NodelingBus.h>
  15. #include <ScriptCanvas/Core/ScriptCanvasBus.h>
  16. #include <ScriptCanvas/Libraries/Core/AzEventHandler.h>
  17. #include <ScriptCanvas/Libraries/Core/EBusEventHandler.h>
  18. #include <ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h>
  19. #include <ScriptCanvas/Libraries/Core/FunctionCallNode.h>
  20. #include <ScriptCanvas/Libraries/Core/GetVariable.h>
  21. #include <ScriptCanvas/Libraries/Core/Method.h>
  22. #include <ScriptCanvas/Libraries/Core/MethodOverloaded.h>
  23. #include <ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h>
  24. #include <ScriptCanvas/Libraries/Core/SendScriptEvent.h>
  25. #include <ScriptCanvas/Libraries/Core/SetVariable.h>
  26. namespace ScriptCanvasEditor::Nodes
  27. {
  28. NodeIdPair CreateFunctionDefinitionNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasId, bool isInput, AZStd::string rootName)
  29. {
  30. ScriptCanvasEditor::Nodes::StyleConfiguration styleConfiguration;
  31. auto nodeAndPair = CreateAndGetNode(azrtti_typeid<ScriptCanvas::Nodes::Core::FunctionDefinitionNode>(), scriptCanvasId, styleConfiguration, [isInput](ScriptCanvas::Node* node)
  32. {
  33. ScriptCanvas::Nodes::Core::FunctionDefinitionNode* fdn = azrtti_cast<ScriptCanvas::Nodes::Core::FunctionDefinitionNode*>(node);
  34. if (!isInput)
  35. {
  36. fdn->MarkExecutionExit();
  37. }
  38. }
  39. );
  40. NodeIdPair createdPair = nodeAndPair.second;
  41. auto functionDefinitionNode = azrtti_cast<ScriptCanvas::Nodes::Core::FunctionDefinitionNode*>(nodeAndPair.first);
  42. if (functionDefinitionNode && createdPair.m_scriptCanvasId.IsValid())
  43. {
  44. AZStd::unordered_set<AZStd::string> nodelingNames;
  45. auto enumerationFunction = [&nodelingNames, scriptCanvasId](ScriptCanvas::NodelingRequests* nodelingRequests)
  46. {
  47. if (nodelingRequests->GetGraphScopedNodeId().m_scriptCanvasId == scriptCanvasId)
  48. {
  49. nodelingNames.insert(nodelingRequests->GetDisplayName());
  50. }
  51. return true;
  52. };
  53. ScriptCanvas::NodelingRequestBus::EnumerateHandlers(enumerationFunction);
  54. int counter = 1;
  55. AZStd::string nodelingName = rootName;
  56. while (nodelingNames.find(nodelingName) != nodelingNames.end())
  57. {
  58. nodelingName = AZStd::string::format("%.*s %i", aznumeric_cast<int>(rootName.size()), rootName.data(), counter);
  59. ++counter;
  60. }
  61. ScriptCanvas::GraphScopedNodeId nodelingId;
  62. nodelingId.m_identifier = createdPair.m_scriptCanvasId;
  63. nodelingId.m_scriptCanvasId = scriptCanvasId;
  64. ScriptCanvas::NodelingRequestBus::Event(nodelingId, &ScriptCanvas::NodelingRequests::SetDisplayName, nodelingName);
  65. if (!isInput)
  66. {
  67. functionDefinitionNode->MarkExecutionExit();
  68. }
  69. GraphCanvas::NodeTitleRequestBus::Event(createdPair.m_graphCanvasId, &GraphCanvas::NodeTitleRequests::SetSubTitle, "Function");
  70. }
  71. return createdPair;
  72. }
  73. NodeIdPair CreateNode(const AZ::Uuid& classId, const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const StyleConfiguration& styleConfiguration)
  74. {
  75. return CreateAndGetNode(classId, scriptCanvasId, styleConfiguration).second;
  76. }
  77. AZStd::pair<ScriptCanvas::Node*, NodeIdPair> CreateAndGetNode(const AZ::Uuid& classId, const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const StyleConfiguration& styleConfiguration, AZStd::function<void(ScriptCanvas::Node*)> onCreateCallback)
  78. {
  79. AZ_PROFILE_FUNCTION(ScriptCanvas);
  80. NodeIdPair nodeIdPair;
  81. ScriptCanvas::Node* node{};
  82. AZ::Entity* scriptCanvasEntity{ aznew AZ::Entity };
  83. scriptCanvasEntity->Init();
  84. nodeIdPair.m_scriptCanvasId = scriptCanvasEntity->GetId();
  85. ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasId, classId);
  86. if (onCreateCallback)
  87. {
  88. onCreateCallback(node);
  89. }
  90. scriptCanvasEntity->SetName(AZStd::string::format("SC-Node(%s)", scriptCanvasEntity->GetName().data()));
  91. AZ::EntityId graphCanvasGraphId;
  92. EditorGraphRequestBus::EventResult(graphCanvasGraphId, scriptCanvasId, &EditorGraphRequests::GetGraphCanvasGraphId);
  93. nodeIdPair.m_graphCanvasId = DisplayScriptCanvasNode(graphCanvasGraphId, node);
  94. if (nodeIdPair.m_graphCanvasId.IsValid())
  95. {
  96. if (!styleConfiguration.m_titlePalette.empty())
  97. {
  98. GraphCanvas::NodeTitleRequestBus::Event(nodeIdPair.m_graphCanvasId, &GraphCanvas::NodeTitleRequests::SetPaletteOverride, styleConfiguration.m_titlePalette);
  99. }
  100. // TODO: Add support for this, but should be mostly irrelevant, as the display node should be the one that handles setting that up.
  101. //nodeConfiguration.m_nodeSubStyle = styleConfiguration.m_nodeSubStyle;
  102. }
  103. return AZStd::make_pair(node, nodeIdPair);
  104. }
  105. NodeIdPair CreateObjectMethodNode(AZStd::string_view className, AZStd::string_view methodName, const ScriptCanvas::ScriptCanvasId& scriptCanvasId, ScriptCanvas::PropertyStatus propertyStatus)
  106. {
  107. AZ_PROFILE_FUNCTION(ScriptCanvas);
  108. NodeIdPair nodeIds;
  109. ScriptCanvas::Node* node = nullptr;
  110. AZ::Entity* scriptCanvasEntity = aznew AZ::Entity();
  111. scriptCanvasEntity->Init();
  112. nodeIds.m_scriptCanvasId = scriptCanvasEntity->GetId();
  113. ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasId, ScriptCanvas::Nodes::Core::Method::RTTI_Type());
  114. auto* methodNode = azrtti_cast<ScriptCanvas::Nodes::Core::Method*>(node);
  115. ScriptCanvas::NamespacePath emptyNamespacePath;
  116. methodNode->InitializeBehaviorMethod(emptyNamespacePath, className, methodName, propertyStatus);
  117. AZStd::string_view displayName = methodNode->GetName();
  118. scriptCanvasEntity->SetName(AZStd::string::format("SC-Node(%.*s)", aznumeric_cast<int>(displayName.size()), displayName.data()));
  119. AZ::EntityId graphCanvasGraphId;
  120. EditorGraphRequestBus::EventResult(graphCanvasGraphId, scriptCanvasId, &EditorGraphRequests::GetGraphCanvasGraphId);
  121. nodeIds.m_graphCanvasId = DisplayMethodNode(graphCanvasGraphId, methodNode);
  122. return nodeIds;
  123. }
  124. NodeIdPair CreateObjectMethodOverloadNode(AZStd::string_view className, AZStd::string_view methodName, const ScriptCanvas::ScriptCanvasId& scriptCanvasGraphId)
  125. {
  126. AZ_PROFILE_FUNCTION(ScriptCanvas);
  127. NodeIdPair nodeIds;
  128. ScriptCanvas::Node* node = nullptr;
  129. AZ::Entity* scriptCanvasEntity = aznew AZ::Entity();
  130. scriptCanvasEntity->Init();
  131. nodeIds.m_scriptCanvasId = scriptCanvasEntity->GetId();
  132. ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasGraphId, ScriptCanvas::Nodes::Core::MethodOverloaded::RTTI_Type());
  133. auto* methodNode = azrtti_cast<ScriptCanvas::Nodes::Core::MethodOverloaded*>(node);
  134. ScriptCanvas::NamespacePath emptyNamespacePath;
  135. methodNode->InitializeBehaviorMethod(emptyNamespacePath, className, methodName, ScriptCanvas::PropertyStatus::None);
  136. AZStd::string_view displayName = methodNode->GetName();
  137. scriptCanvasEntity->SetName(AZStd::string::format("SC-Node(%.*s)", aznumeric_cast<int>(displayName.size()), displayName.data()));
  138. AZ::EntityId graphCanvasGraphId;
  139. EditorGraphRequestBus::EventResult(graphCanvasGraphId, scriptCanvasGraphId, &EditorGraphRequests::GetGraphCanvasGraphId);
  140. nodeIds.m_graphCanvasId = DisplayMethodNode(graphCanvasGraphId, methodNode);
  141. return nodeIds;
  142. }
  143. NodeIdPair CreateGlobalMethodNode(AZStd::string_view methodName, bool isProperty, const ScriptCanvas::ScriptCanvasId& scriptCanvasId)
  144. {
  145. AZ_PROFILE_FUNCTION(ScriptCanvas);
  146. NodeIdPair nodeIds;
  147. ScriptCanvas::Node* node = nullptr;
  148. AZ::Entity* scriptCanvasEntity = aznew AZ::Entity();
  149. scriptCanvasEntity->Init();
  150. nodeIds.m_scriptCanvasId = scriptCanvasEntity->GetId();
  151. ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasId, ScriptCanvas::Nodes::Core::Method::RTTI_Type());
  152. auto* methodNode = azrtti_cast<ScriptCanvas::Nodes::Core::Method*>(node);
  153. ScriptCanvas::NamespacePath emptyNamespacePath;
  154. methodNode->InitializeFree(emptyNamespacePath, methodName);
  155. AZStd::string displayName = methodNode->GetName();
  156. scriptCanvasEntity->SetName(AZStd::string::format("SC-Node(%.*s)", aznumeric_cast<int>(displayName.size()), displayName.data()));
  157. AZ::EntityId graphCanvasGraphId;
  158. EditorGraphRequestBus::EventResult(graphCanvasGraphId, scriptCanvasId, &EditorGraphRequests::GetGraphCanvasGraphId);
  159. nodeIds.m_graphCanvasId = DisplayMethodNode(graphCanvasGraphId, methodNode, isProperty);
  160. return nodeIds;
  161. }
  162. NodeIdPair CreateEbusWrapperNode(AZStd::string_view busName, const ScriptCanvas::ScriptCanvasId& scriptCanvasId)
  163. {
  164. AZ_PROFILE_FUNCTION(ScriptCanvas);
  165. NodeIdPair nodeIdPair;
  166. ScriptCanvas::Node* node = nullptr;
  167. AZ::Entity* scriptCanvasEntity = aznew AZ::Entity(AZStd::string::format("SC-Node(%.*s)", aznumeric_cast<int>(busName.size()), busName.data()));
  168. scriptCanvasEntity->Init();
  169. ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasId, ScriptCanvas::Nodes::Core::EBusEventHandler::RTTI_Type());
  170. auto* busNode = azrtti_cast<ScriptCanvas::Nodes::Core::EBusEventHandler*>(node);
  171. busNode->InitializeBus(busName);
  172. nodeIdPair.m_scriptCanvasId = scriptCanvasEntity->GetId();
  173. AZ::EntityId graphCanvasGraphId;
  174. EditorGraphRequestBus::EventResult(graphCanvasGraphId, scriptCanvasId, &EditorGraphRequests::GetGraphCanvasGraphId);
  175. nodeIdPair.m_graphCanvasId = DisplayEbusWrapperNode(graphCanvasGraphId, busNode);
  176. return nodeIdPair;
  177. }
  178. NodeIdPair CreateScriptEventReceiverNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const AZ::Data::AssetId& assetId)
  179. {
  180. AZ_Assert(assetId.IsValid(), "CreateScriptEventReceiverNode asset Id must be valid");
  181. AZ_PROFILE_FUNCTION(ScriptCanvas);
  182. NodeIdPair nodeIdPair;
  183. AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> asset = AZ::Data::AssetManager::Instance().GetAsset<ScriptEvents::ScriptEventsAsset>(assetId, AZ::Data::AssetLoadBehavior::Default);
  184. if (!asset)
  185. {
  186. AZ_Error("GraphCanvas", asset, "Unable to CreateScriptEventReceiverNode, asset %s not found.", assetId.ToString<AZStd::string>().c_str());
  187. return nodeIdPair;
  188. }
  189. asset.BlockUntilLoadComplete();
  190. ScriptCanvas::Node* node = nullptr;
  191. AZ::Entity* scriptCanvasEntity = aznew AZ::Entity(AZStd::string::format("SC-Node(%s)", asset.Get()->m_definition.GetName().data()));
  192. scriptCanvasEntity->Init();
  193. ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasId, ScriptCanvas::Nodes::Core::ReceiveScriptEvent::RTTI_Type());
  194. auto* busNode = azrtti_cast<ScriptCanvas::Nodes::Core::ReceiveScriptEvent*>(node);
  195. busNode->Initialize(assetId);
  196. nodeIdPair.m_scriptCanvasId = scriptCanvasEntity->GetId();
  197. AZ::EntityId graphCanvasGraphId;
  198. EditorGraphRequestBus::EventResult(graphCanvasGraphId, scriptCanvasId, &EditorGraphRequests::GetGraphCanvasGraphId);
  199. nodeIdPair.m_graphCanvasId = DisplayScriptEventWrapperNode(graphCanvasGraphId, busNode);
  200. return nodeIdPair;
  201. }
  202. NodeIdPair CreateScriptEventSenderNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const AZ::Data::AssetId& assetId, const ScriptCanvas::EBusEventId& eventId)
  203. {
  204. AZ_Assert(assetId.IsValid(), "CreateScriptEventSenderNode asset Id must be valid");
  205. AZ_PROFILE_FUNCTION(ScriptCanvas);
  206. NodeIdPair nodeIdPair;
  207. AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> asset = AZ::Data::AssetManager::Instance().GetAsset<ScriptEvents::ScriptEventsAsset>(assetId, AZ::Data::AssetLoadBehavior::Default);
  208. AZ::Entity* scriptCanvasEntity = aznew AZ::Entity(AZStd::string::format("SC-Node(%s)", asset.Get()->m_definition.GetName().data()));
  209. scriptCanvasEntity->Init();
  210. ScriptCanvas::Node* node = nullptr;
  211. ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasId, ScriptCanvas::Nodes::Core::SendScriptEvent::RTTI_Type());
  212. auto* senderNode = azrtti_cast<ScriptCanvas::Nodes::Core::SendScriptEvent*>(node);
  213. senderNode->ConfigureNode(assetId, eventId);
  214. nodeIdPair.m_scriptCanvasId = scriptCanvasEntity->GetId();
  215. AZ::EntityId graphCanvasGraphId;
  216. EditorGraphRequestBus::EventResult(graphCanvasGraphId, scriptCanvasId, &EditorGraphRequests::GetGraphCanvasGraphId);
  217. nodeIdPair.m_graphCanvasId = DisplayScriptEventSenderNode(graphCanvasGraphId, senderNode);
  218. return nodeIdPair;
  219. }
  220. CreateNodeResult CreateGetVariableNodeResult(const ScriptCanvas::VariableId& variableId, ScriptCanvas::ScriptCanvasId scriptCanvasId)
  221. {
  222. AZ_PROFILE_FUNCTION(ScriptCanvas);
  223. const AZ::Uuid k_VariableNodeTypeId = azrtti_typeid<ScriptCanvas::Nodes::Core::GetVariableNode>();
  224. NodeIdPair nodeIds;
  225. ScriptCanvas::Node* node = nullptr;
  226. AZ::Entity* scriptCanvasEntity = aznew AZ::Entity();
  227. scriptCanvasEntity->Init();
  228. ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasId, k_VariableNodeTypeId);
  229. ScriptCanvas::Nodes::Core::GetVariableNode* variableNode = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Nodes::Core::GetVariableNode>(scriptCanvasEntity);
  230. if (variableNode)
  231. {
  232. variableNode->SetId(variableId);
  233. }
  234. nodeIds.m_scriptCanvasId = scriptCanvasEntity->GetId();
  235. AZ::EntityId graphCanvasGraphId;
  236. EditorGraphRequestBus::EventResult(graphCanvasGraphId, scriptCanvasId, &EditorGraphRequests::GetGraphCanvasGraphId);
  237. nodeIds.m_graphCanvasId = DisplayGetVariableNode(graphCanvasGraphId, variableNode);
  238. scriptCanvasEntity->SetName(AZStd::string::format("SC Node(GetVariable)"));
  239. CreateNodeResult result;
  240. result.node = node;
  241. result.nodeIdPair = nodeIds;
  242. return result;
  243. }
  244. CreateNodeResult CreateSetVariableNodeResult(const ScriptCanvas::VariableId& variableId, ScriptCanvas::ScriptCanvasId scriptCanvasId)
  245. {
  246. AZ_PROFILE_FUNCTION(ScriptCanvas);
  247. const AZ::Uuid k_VariableNodeTypeId = azrtti_typeid<ScriptCanvas::Nodes::Core::SetVariableNode>();
  248. NodeIdPair nodeIds;
  249. ScriptCanvas::Node* node = nullptr;
  250. AZ::Entity* scriptCanvasEntity = aznew AZ::Entity();
  251. scriptCanvasEntity->Init();
  252. ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasId, k_VariableNodeTypeId);
  253. ScriptCanvas::Nodes::Core::SetVariableNode* variableNode = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Nodes::Core::SetVariableNode>(scriptCanvasEntity);
  254. if (variableNode)
  255. {
  256. variableNode->SetId(variableId);
  257. }
  258. nodeIds.m_scriptCanvasId = scriptCanvasEntity->GetId();
  259. AZ::EntityId graphCanvasGraphId;
  260. EditorGraphRequestBus::EventResult(graphCanvasGraphId, scriptCanvasId, &EditorGraphRequests::GetGraphCanvasGraphId);
  261. nodeIds.m_graphCanvasId = DisplaySetVariableNode(graphCanvasGraphId, variableNode);
  262. scriptCanvasEntity->SetName(AZStd::string::format("SC Node(SetVariable)"));
  263. CreateNodeResult result;
  264. result.node = node;
  265. result.nodeIdPair = nodeIds;
  266. return result;
  267. }
  268. NodeIdPair CreateGetVariableNode(const ScriptCanvas::VariableId& variableId, ScriptCanvas::ScriptCanvasId scriptCanvasGraphId)
  269. {
  270. return CreateGetVariableNodeResult(variableId, scriptCanvasGraphId).nodeIdPair;
  271. }
  272. NodeIdPair CreateSetVariableNode(const ScriptCanvas::VariableId& variableId, ScriptCanvas::ScriptCanvasId scriptCanvasGraphId)
  273. {
  274. return CreateSetVariableNodeResult(variableId, scriptCanvasGraphId).nodeIdPair;
  275. }
  276. NodeIdPair CreateFunctionNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasGraphId, const AZ::Data::AssetId& assetId, const ScriptCanvas::Grammar::FunctionSourceId& sourceId)
  277. {
  278. AZ_Assert(assetId.IsValid(), "CreateFunctionNode source asset Id must be valid");
  279. AZ_PROFILE_FUNCTION(ScriptCanvas);
  280. NodeIdPair nodeIdPair;
  281. AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset> asset = AZ::Data::AssetManager::Instance().GetAsset<ScriptCanvas::SubgraphInterfaceAsset>(assetId, AZ::Data::AssetLoadBehavior::PreLoad);
  282. asset.BlockUntilLoadComplete();
  283. AZ::Entity* scriptCanvasEntity = aznew AZ::Entity(AZStd::string::format("SC-Function (%s)", asset.GetId().ToString<AZStd::string>().c_str()));
  284. scriptCanvasEntity->Init();
  285. ScriptCanvas::Node* node = nullptr;
  286. ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasGraphId, ScriptCanvas::Nodes::Core::FunctionCallNode::RTTI_Type());
  287. auto functionNode = azrtti_cast<ScriptCanvas::Nodes::Core::FunctionCallNode*>(node);
  288. functionNode->Initialize(assetId, sourceId);
  289. functionNode->BuildNode();
  290. nodeIdPair.m_scriptCanvasId = scriptCanvasEntity->GetId();
  291. AZ::EntityId graphCanvasGraphId;
  292. EditorGraphRequestBus::EventResult(graphCanvasGraphId, scriptCanvasGraphId, &EditorGraphRequests::GetGraphCanvasGraphId);
  293. nodeIdPair.m_graphCanvasId = DisplayFunctionNode(graphCanvasGraphId, functionNode);
  294. return nodeIdPair;
  295. }
  296. NodeIdPair CreateAzEventHandlerNode(const AZ::BehaviorMethod& methodWithAzEventReturn, ScriptCanvas::ScriptCanvasId scriptCanvasId,
  297. AZ::EntityId connectingMethodNodeId)
  298. {
  299. AZ_PROFILE_FUNCTION(ScriptCanvas);
  300. NodeIdPair nodeIdPair;
  301. // Make sure the method returns an AZ::Event by reference or pointer
  302. if (!AZ::MethodReturnsAzEventByReferenceOrPointer(methodWithAzEventReturn))
  303. {
  304. return {};
  305. }
  306. // Read in AZ Event Description data to retrieve the event name and parameter names
  307. AZ::Attribute* azEventDescAttribute = AZ::FindAttribute(AZ::Script::Attributes::AzEventDescription, methodWithAzEventReturn.m_attributes);
  308. AZ::BehaviorAzEventDescription behaviorAzEventDesc;
  309. AZ::AttributeReader azEventDescAttributeReader(nullptr, azEventDescAttribute);
  310. azEventDescAttributeReader.Read<decltype(behaviorAzEventDesc)>(behaviorAzEventDesc);
  311. if (behaviorAzEventDesc.m_eventName.empty())
  312. {
  313. AZ_Error("NodeUtils", false, "Cannot create an AzEvent node with empty event name")
  314. return {};
  315. }
  316. auto scriptCanvasEntity = aznew AZ::Entity{ AZStd::string::format("SC-EventNode(%s)", behaviorAzEventDesc.m_eventName.c_str()) };
  317. scriptCanvasEntity->Init();
  318. auto azEventHandler = scriptCanvasEntity->CreateComponent<ScriptCanvas::Nodes::Core::AzEventHandler>();
  319. ScriptCanvas::GraphRequestBus::Event(scriptCanvasId, &ScriptCanvas::GraphRequests::AddNode, scriptCanvasEntity->GetId());
  320. azEventHandler->InitEventFromMethod(methodWithAzEventReturn);
  321. azEventHandler->SetRestrictedNodeId(connectingMethodNodeId);
  322. nodeIdPair.m_scriptCanvasId = scriptCanvasEntity->GetId();
  323. AZ::EntityId graphCanvasGraphId;
  324. EditorGraphRequestBus::EventResult(graphCanvasGraphId, scriptCanvasId, &EditorGraphRequests::GetGraphCanvasGraphId);
  325. nodeIdPair.m_graphCanvasId = DisplayAzEventHandlerNode(graphCanvasGraphId, azEventHandler);
  326. return nodeIdPair;
  327. }
  328. }