EditorUtils.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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 <AzCore/Serialization/SerializeContext.h>
  9. AZ_PUSH_DISABLE_WARNING(4251 4800 4244, "-Wunknown-warning-option")
  10. #include <ScriptCanvas/Components/EditorUtils.h>
  11. AZ_POP_DISABLE_WARNING
  12. #include <ScriptCanvas/Components/EditorGraph.h>
  13. #include <ScriptCanvas/GraphCanvas/MappingBus.h>
  14. #include <ScriptCanvas/Libraries/Core/EBusEventHandler.h>
  15. #include <ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h>
  16. #include <ScriptCanvas/Utils/NodeUtils.h>
  17. #include <AzToolsFramework/API/EditorAssetSystemAPI.h>
  18. #include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
  19. #include <Editor/Include/ScriptCanvas/GraphCanvas/NodeDescriptorBus.h>
  20. #include <Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.h>
  21. #include <Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.h>
  22. #include <Editor/View/Widgets/NodePalette/ScriptEventsNodePaletteTreeItemTypes.h>
  23. #include <Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.h>
  24. #include <Editor/View/Widgets/NodePalette/NodePaletteModel.h>
  25. #include <Editor/View/Widgets/NodePalette/SpecializedNodePaletteTreeItemTypes.h>
  26. #include <Editor/View/Widgets/NodePalette/VariableNodePaletteTreeItemTypes.h>
  27. namespace ScriptCanvasEditor
  28. {
  29. AZStd::optional<SourceHandle> CreateFromAnyPath(const SourceHandle& source, const AZ::IO::Path& path)
  30. {
  31. return CompleteDescription(SourceHandle::FromRelativePath(source, path));
  32. }
  33. AZStd::optional<SourceHandle> CompleteDescription(const SourceHandle& source)
  34. {
  35. using namespace AzToolsFramework;
  36. if (AssetSystemRequestBus::Events* assetSystem = AssetSystemRequestBus::FindFirstHandler())
  37. {
  38. if (!source.Id().IsNull())
  39. {
  40. AZStd::string watchFolderID;
  41. AZ::Data::AssetInfo assetInfoID;
  42. if (assetSystem->GetSourceInfoBySourceUUID(source.Id(), assetInfoID, watchFolderID))
  43. {
  44. return SourceHandle::MarkAbsolutePath
  45. ( SourceHandle::FromRelativePath(source, assetInfoID.m_assetId.m_guid, assetInfoID.m_relativePath.c_str())
  46. , (AZ::IO::Path(watchFolderID) / AZ::IO::Path(assetInfoID.m_relativePath)));
  47. }
  48. }
  49. if (!source.RelativePath().empty())
  50. {
  51. AZStd::string watchFolderPath;
  52. AZ::Data::AssetInfo assetInfoPath;
  53. if (assetSystem->GetSourceInfoBySourcePath(source.RelativePath().c_str(), assetInfoPath, watchFolderPath)
  54. && assetInfoPath.m_assetId.IsValid())
  55. {
  56. return SourceHandle::MarkAbsolutePath
  57. ( SourceHandle::FromRelativePath(source, assetInfoPath.m_assetId.m_guid, assetInfoPath.m_relativePath.c_str())
  58. , (AZ::IO::Path(watchFolderPath) / AZ::IO::Path(assetInfoPath.m_relativePath)));
  59. }
  60. }
  61. }
  62. return AZStd::nullopt;
  63. }
  64. bool CompleteDescriptionInPlace(SourceHandle& source)
  65. {
  66. if (auto completed = CompleteDescription(source))
  67. {
  68. source = *completed;
  69. return true;
  70. }
  71. else
  72. {
  73. return false;
  74. }
  75. }
  76. //////////////////////////
  77. // NodeIdentifierFactory
  78. //////////////////////////
  79. ScriptCanvas::NodeTypeIdentifier NodeIdentifierFactory::ConstructNodeIdentifier(const GraphCanvas::GraphCanvasTreeItem* treeItem)
  80. {
  81. ScriptCanvas::NodeTypeIdentifier resultHash = 0;
  82. if (auto getVariableMethodTreeItem = azrtti_cast<const GetVariableNodePaletteTreeItem*>(treeItem))
  83. {
  84. resultHash = ScriptCanvas::NodeUtils::ConstructGetVariableNodeIdentifier(getVariableMethodTreeItem->GetVariableId());
  85. }
  86. else if (auto setVariableMethodTreeItem = azrtti_cast<const SetVariableNodePaletteTreeItem*>(treeItem))
  87. {
  88. resultHash = ScriptCanvas::NodeUtils::ConstructSetVariableNodeIdentifier(setVariableMethodTreeItem->GetVariableId());
  89. }
  90. else if (auto classMethodTreeItem = azrtti_cast<const ClassMethodEventPaletteTreeItem*>(treeItem))
  91. {
  92. if (classMethodTreeItem->IsOverload())
  93. {
  94. resultHash = ScriptCanvas::NodeUtils::ConstructMethodOverloadedNodeIdentifier(classMethodTreeItem->GetMethodName());
  95. }
  96. else
  97. {
  98. resultHash = ScriptCanvas::NodeUtils::ConstructMethodNodeIdentifier(classMethodTreeItem->GetClassMethodName(), classMethodTreeItem->GetMethodName(), classMethodTreeItem->GetPropertyStatus());
  99. }
  100. }
  101. else if (auto globalMethodTreeItem = azrtti_cast<const GlobalMethodEventPaletteTreeItem*>(treeItem); globalMethodTreeItem != nullptr)
  102. {
  103. resultHash = ScriptCanvas::NodeUtils::ConstructGlobalMethodNodeIdentifier(globalMethodTreeItem->GetMethodName());
  104. }
  105. else if (auto customNodeTreeItem = azrtti_cast<const CustomNodePaletteTreeItem*>(treeItem))
  106. {
  107. resultHash = ScriptCanvas::NodeUtils::ConstructCustomNodeIdentifier(customNodeTreeItem->GetTypeId());
  108. }
  109. else if (auto sendEbusEventTreeItem = azrtti_cast<const EBusSendEventPaletteTreeItem*>(treeItem))
  110. {
  111. resultHash = ScriptCanvas::NodeUtils::ConstructEBusEventSenderIdentifier(sendEbusEventTreeItem->GetBusId(), sendEbusEventTreeItem->GetEventId());
  112. }
  113. else if (auto handleEbusEventTreeItem = azrtti_cast<const EBusHandleEventPaletteTreeItem*>(treeItem))
  114. {
  115. resultHash = ScriptCanvas::NodeUtils::ConstructEBusEventReceiverIdentifier(handleEbusEventTreeItem->GetBusId(), handleEbusEventTreeItem->GetEventId());
  116. }
  117. else if (auto functionTreeItem = azrtti_cast<const FunctionPaletteTreeItem*>(treeItem))
  118. {
  119. resultHash = ScriptCanvas::NodeUtils::ConstructFunctionNodeIdentifier(functionTreeItem->GetAssetId());
  120. }
  121. return resultHash;
  122. }
  123. AZStd::vector< ScriptCanvas::NodeTypeIdentifier > NodeIdentifierFactory::ConstructNodeIdentifiers(const GraphCanvas::GraphCanvasTreeItem* treeItem)
  124. {
  125. AZStd::vector< ScriptCanvas::NodeTypeIdentifier > nodeIdentifiers;
  126. if (auto scriptEventTreeItem = azrtti_cast<const ScriptEventsEventNodePaletteTreeItem*>(treeItem))
  127. {
  128. nodeIdentifiers.emplace_back(ScriptCanvas::NodeUtils::ConstructScriptEventReceiverIdentifier(scriptEventTreeItem->GetBusIdentifier(), scriptEventTreeItem->GetEventIdentifier()));
  129. nodeIdentifiers.emplace_back(ScriptCanvas::NodeUtils::ConstructSendScriptEventIdentifier(scriptEventTreeItem->GetBusIdentifier(), scriptEventTreeItem->GetEventIdentifier()));
  130. }
  131. else
  132. {
  133. nodeIdentifiers.emplace_back(ConstructNodeIdentifier(treeItem));
  134. }
  135. return nodeIdentifiers;
  136. }
  137. //////////////////////////
  138. // GraphStatisticsHelper
  139. //////////////////////////
  140. void GraphStatisticsHelper::Reflect(AZ::ReflectContext* reflectContext)
  141. {
  142. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
  143. if (serializeContext)
  144. {
  145. serializeContext->Class<GraphStatisticsHelper>()
  146. ->Version(1)
  147. ->Field("InstanceCounter", &GraphStatisticsHelper::m_nodeIdentifierCount)
  148. ;
  149. }
  150. }
  151. void GraphStatisticsHelper::PopulateStatisticData(const EditorGraph* editorGraph)
  152. {
  153. // Opportunistically use this time to refresh out node count array.
  154. m_nodeIdentifierCount.clear();
  155. for (auto* nodeEntity : editorGraph->GetNodeEntities())
  156. {
  157. auto nodeComponent = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Node>(nodeEntity);
  158. if (nodeComponent)
  159. {
  160. if (auto ebusHandlerNode = azrtti_cast<ScriptCanvas::Nodes::Core::EBusEventHandler*>(nodeComponent))
  161. {
  162. GraphCanvas::NodeId graphCanvasNodeId;
  163. SceneMemberMappingRequestBus::EventResult(graphCanvasNodeId, nodeEntity->GetId(), &SceneMemberMappingRequests::GetGraphCanvasEntityId);
  164. const ScriptCanvas::Nodes::Core::EBusEventHandler::EventMap& events = ebusHandlerNode->GetEvents();
  165. ScriptCanvas::EBusBusId busId = ebusHandlerNode->GetEBusId();
  166. for (const auto& eventPair : events)
  167. {
  168. bool hasEvent = false;
  169. EBusHandlerNodeDescriptorRequestBus::EventResult(hasEvent, graphCanvasNodeId, &EBusHandlerNodeDescriptorRequests::ContainsEvent, eventPair.second.m_eventId);
  170. // In case we are populating from an uncreated scene if we don't have a valid graph canvas node id
  171. // just accept everything. We can overreport on unknown data for now.
  172. if (hasEvent || !graphCanvasNodeId.IsValid())
  173. {
  174. RegisterNodeType(ScriptCanvas::NodeUtils::ConstructEBusEventReceiverIdentifier(busId, eventPair.second.m_eventId));
  175. }
  176. }
  177. }
  178. else if (auto scriptEventHandler = azrtti_cast<ScriptCanvas::Nodes::Core::ReceiveScriptEvent*>(nodeComponent))
  179. {
  180. GraphCanvas::NodeId graphCanvasNodeId;
  181. SceneMemberMappingRequestBus::EventResult(graphCanvasNodeId, nodeEntity->GetId(), &SceneMemberMappingRequests::GetGraphCanvasEntityId);
  182. EBusHandlerNodeDescriptorRequests* ebusDescriptorRequests = EBusHandlerNodeDescriptorRequestBus::FindFirstHandler(graphCanvasNodeId);
  183. if (ebusDescriptorRequests == nullptr)
  184. {
  185. continue;
  186. }
  187. AZStd::vector< HandlerEventConfiguration > eventConfigurations = ebusDescriptorRequests->GetEventConfigurations();
  188. ScriptCanvas::EBusBusId busId = scriptEventHandler->GetBusId();
  189. for (const auto& eventConfiguration : eventConfigurations)
  190. {
  191. bool hasEvent = ebusDescriptorRequests->ContainsEvent(eventConfiguration.m_eventId);
  192. // In case we are populating from an uncreated scene if we don't have a valid graph canvas node id
  193. // just accept everything. We can overreport on unknown data for now.
  194. if (hasEvent)
  195. {
  196. RegisterNodeType(ScriptCanvas::NodeUtils::ConstructScriptEventReceiverIdentifier(busId, eventConfiguration.m_eventId));
  197. }
  198. }
  199. }
  200. else
  201. {
  202. ScriptCanvas::NodeTypeIdentifier nodeType = nodeComponent->GetNodeType();
  203. // Fallback in case something isn't initialized for whatever reason
  204. if (nodeType == 0)
  205. {
  206. nodeType = ScriptCanvas::NodeUtils::ConstructNodeType(nodeComponent);
  207. }
  208. RegisterNodeType(nodeType);
  209. }
  210. }
  211. }
  212. }
  213. void GraphStatisticsHelper::RegisterNodeType(const ScriptCanvas::NodeTypeIdentifier& nodeTypeIdentifier)
  214. {
  215. auto nodeIter = m_nodeIdentifierCount.find(nodeTypeIdentifier);
  216. if (nodeIter == m_nodeIdentifierCount.end())
  217. {
  218. m_nodeIdentifierCount.emplace(AZStd::make_pair(nodeTypeIdentifier, 1));
  219. }
  220. else
  221. {
  222. nodeIter->second++;
  223. }
  224. }
  225. }