GraphCanvas.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  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 <GraphCanvas.h>
  9. #include <AzCore/Serialization/EditContext.h>
  10. #include <AzCore/Component/EntityUtils.h>
  11. #include <AzCore/RTTI/BehaviorContext.h>
  12. #include <Components/BookmarkManagerComponent.h>
  13. #include <Components/BookmarkAnchor/BookmarkAnchorComponent.h>
  14. #include <Components/BookmarkAnchor/BookmarkAnchorLayerControllerComponent.h>
  15. #include <Components/BookmarkAnchor/BookmarkAnchorVisualComponent.h>
  16. #include <Components/GeometryComponent.h>
  17. #include <Components/GridComponent.h>
  18. #include <Components/GridVisualComponent.h>
  19. #include <Components/PersistentIdComponent.h>
  20. #include <Components/SceneComponent.h>
  21. #include <Components/SceneMemberComponent.h>
  22. #include <Components/StylingComponent.h>
  23. #include <Components/Connections/ConnectionComponent.h>
  24. #include <Components/Connections/ConnectionVisualComponent.h>
  25. #include <Components/Connections/DataConnections/DataConnectionComponent.h>
  26. #include <Components/Connections/DataConnections/DataConnectionVisualComponent.h>
  27. #include <Components/Nodes/NodeComponent.h>
  28. #include <Components/Nodes/Comment/CommentNodeLayoutComponent.h>
  29. #include <Components/Nodes/General/GeneralNodeLayoutComponent.h>
  30. #include <Components/Nodes/General/GeneralSlotLayoutComponent.h>
  31. #include <Components/Nodes/Group/CollapsedNodeGroupComponent.h>
  32. #include <Components/Nodes/Group/NodeGroupFrameComponent.h>
  33. #include <Components/Nodes/Group/NodeGroupLayoutComponent.h>
  34. #include <Components/Nodes/Wrapper/WrapperNodeLayoutComponent.h>
  35. #include <Components/NodePropertyDisplays/AssetIdNodePropertyDisplay.h>
  36. #include <Components/NodePropertyDisplays/BooleanNodePropertyDisplay.h>
  37. #include <Components/NodePropertyDisplays/ComboBoxNodePropertyDisplay.h>
  38. #include <Components/NodePropertyDisplays/EntityIdNodePropertyDisplay.h>
  39. #include <Components/NodePropertyDisplays/NumericNodePropertyDisplay.h>
  40. #include <Components/NodePropertyDisplays/ReadOnlyNodePropertyDisplay.h>
  41. #include <Components/NodePropertyDisplays/StringNodePropertyDisplay.h>
  42. #include <Components/NodePropertyDisplays/VectorNodePropertyDisplay.h>
  43. #include <Components/Slots/Data/DataSlotComponent.h>
  44. #include <Components/Slots/Execution/ExecutionSlotComponent.h>
  45. #include <Components/Slots/Extender/ExtenderSlotComponent.h>
  46. #include <Components/Slots/Property/PropertySlotComponent.h>
  47. #include <GraphCanvas/Styling/Selector.h>
  48. #include <GraphCanvas/Styling/SelectorImplementations.h>
  49. #include <GraphCanvas/Styling/PseudoElement.h>
  50. #include <GraphCanvas/Types/ConstructPresets.h>
  51. #include <GraphCanvas/Types/EntitySaveData.h>
  52. #include <GraphCanvas/Widgets/GraphCanvasEditor/GraphCanvasAssetEditorMainWindow.h>
  53. #include <GraphCanvas/Widgets/GraphCanvasMimeEvent.h>
  54. #include <GraphCanvas/Widgets/GraphCanvasTreeModel.h>
  55. #include <GraphCanvas/Widgets/MimeEvents/CreateSplicingNodeMimeEvent.h>
  56. #include <AzToolsFramework/ToolsComponents/ToolsAssetCatalogBus.h>
  57. namespace GraphCanvas
  58. {
  59. bool EntitySaveDataContainerVersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
  60. {
  61. if (classElement.GetVersion() == 1)
  62. {
  63. AZ::Crc32 componentDataId = AZ_CRC("ComponentData", 0xa6acc628);
  64. AZStd::unordered_map< AZ::Uuid, GraphCanvas::ComponentSaveData* > componentSaveData;
  65. AZ::SerializeContext::DataElementNode* dataNode = classElement.FindSubElement(componentDataId);
  66. if (dataNode)
  67. {
  68. dataNode->GetDataHierarchy(context, componentSaveData);
  69. }
  70. classElement.RemoveElementByName(componentDataId);
  71. AZStd::unordered_map< AZ::Uuid, GraphCanvas::ComponentSaveData* > remappedComponentSaveData;
  72. for (const auto& mapPair : componentSaveData)
  73. {
  74. auto mapIter = remappedComponentSaveData.find(azrtti_typeid(mapPair.second));
  75. if (mapIter == remappedComponentSaveData.end())
  76. {
  77. remappedComponentSaveData[azrtti_typeid(mapPair.second)] = mapPair.second;
  78. }
  79. }
  80. classElement.AddElementWithData(context, "ComponentData", remappedComponentSaveData);
  81. }
  82. return true;
  83. }
  84. void GraphCanvasSystemComponent::Reflect(AZ::ReflectContext* context)
  85. {
  86. if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  87. {
  88. serializeContext->Class<GraphCanvasSystemComponent, AZ::Component>()
  89. ->Version(1)
  90. ;
  91. // Reflect information for the stripped down saving
  92. serializeContext->Class<ComponentSaveData>()
  93. ->Version(1)
  94. ;
  95. serializeContext->Class<EntitySaveDataContainer>()
  96. ->Version(2, &EntitySaveDataContainerVersionConverter)
  97. ->Field("ComponentData", &EntitySaveDataContainer::m_entityData)
  98. ;
  99. ////
  100. if (AZ::EditContext* editContext = serializeContext->GetEditContext())
  101. {
  102. editContext->Class<GraphCanvasSystemComponent>(
  103. "LmbrCentral", "Provides factory methods for Graph Canvas components")
  104. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  105. ->Attribute(AZ::Edit::Attributes::Category, "Editor")
  106. ;
  107. }
  108. NodeConfiguration::Reflect(serializeContext);
  109. Styling::SelectorImplementation::Reflect(serializeContext);
  110. Styling::Selector::Reflect(serializeContext);
  111. Styling::NullSelector::Reflect(serializeContext);
  112. Styling::BasicSelector::Reflect(serializeContext);
  113. Styling::DefaultSelector::Reflect(serializeContext);
  114. Styling::CompoundSelector::Reflect(serializeContext);
  115. Styling::NestedSelector::Reflect(serializeContext);
  116. Styling::Style::Reflect(serializeContext);
  117. AssetEditorUserSettings::Reflect(serializeContext);
  118. }
  119. EditorConstructPresets::Reflect(context);
  120. GraphCanvasMimeEvent::Reflect(context);
  121. GraphCanvasTreeModel::Reflect(context);
  122. CreateSplicingNodeMimeEvent::Reflect(context);
  123. TranslationAsset::Reflect(context);
  124. if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  125. {
  126. behaviorContext->EBus<AssetEditorRequestBus>("AssetEditorRequestBus")
  127. ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
  128. ->Attribute(AZ::Script::Attributes::Category, "AssetEditor")
  129. ->Attribute(AZ::Script::Attributes::Module, EditorGraphModuleName)
  130. ->Event("CreateNewGraph", &AssetEditorRequests::CreateNewGraph)
  131. ->Event("ContainsGraph", &AssetEditorRequests::ContainsGraph)
  132. ->Event("CloseGraph", &AssetEditorRequests::CloseGraph)
  133. ;
  134. behaviorContext->EBus<SceneRequestBus>("SceneRequestBus")
  135. ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
  136. ->Attribute(AZ::Script::Attributes::Category, "Scene")
  137. ->Attribute(AZ::Script::Attributes::Module, EditorGraphModuleName)
  138. ->Event("CutSelection", &SceneRequests::CutSelection)
  139. ->Event("CopySelection", &SceneRequests::CopySelection)
  140. ->Event("Paste", &SceneRequests::Paste)
  141. ->Event("DuplicateSelection", &SceneRequests::DuplicateSelection)
  142. ;
  143. }
  144. }
  145. void GraphCanvasSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  146. {
  147. required.push_back(AZ_CRC("AssetDatabaseService", 0x3abf5601));
  148. }
  149. void GraphCanvasSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  150. {
  151. provided.push_back(GraphCanvasRequestsServiceId);
  152. }
  153. void GraphCanvasSystemComponent::Init()
  154. {
  155. m_translationDatabase.Init();
  156. }
  157. void GraphCanvasSystemComponent::Activate()
  158. {
  159. RegisterTranslationBuilder();
  160. AzFramework::AssetCatalogEventBus::Handler::BusConnect();
  161. GraphCanvasRequestBus::Handler::BusConnect();
  162. Styling::PseudoElementFactoryRequestBus::Handler::BusConnect();
  163. }
  164. void GraphCanvasSystemComponent::RegisterTranslationBuilder()
  165. {
  166. // Register ScriptCanvas Builder
  167. {
  168. AssetBuilderSDK::AssetBuilderDesc builderDescriptor;
  169. builderDescriptor.m_name = "Graph Canvas Translation Builder";
  170. builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.names", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
  171. builderDescriptor.m_busId = TranslationAssetWorker::GetUUID();
  172. // changing the analysis fingerprint just invalidates analysis (ie, not the assets themselves)
  173. // which will cause the "CreateJobs" function to be called, for each asset, even if the
  174. // source file has not changed, but won't actually do the jobs unless the source file has changed
  175. // or the fingerprint of the individual job is different.
  176. builderDescriptor.m_analysisFingerprint = m_translationAssetWorker.GetFingerprintString();
  177. m_translationAssetWorker.BusConnect(builderDescriptor.m_busId);
  178. AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, builderDescriptor);
  179. AzToolsFramework::ToolsAssetSystemBus::Broadcast(&AzToolsFramework::ToolsAssetSystemRequests::RegisterSourceAssetType, azrtti_typeid<TranslationAsset>(), TranslationAsset::GetFileFilter());
  180. m_translationAssetWorker.Activate();
  181. m_assetHandler = AZStd::make_unique<TranslationAssetHandler>();
  182. m_assetHandler->Register();
  183. }
  184. }
  185. void GraphCanvasSystemComponent::Deactivate()
  186. {
  187. AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
  188. Styling::PseudoElementFactoryRequestBus::Handler::BusDisconnect();
  189. GraphCanvasRequestBus::Handler::BusDisconnect();
  190. m_translationAssetWorker.Deactivate();
  191. UnregisterAssetHandler();
  192. }
  193. AZ::Entity* GraphCanvasSystemComponent::CreateBookmarkAnchor() const
  194. {
  195. AZ::Entity* entity = aznew AZ::Entity("BookmarkAnchor");
  196. entity->CreateComponent<BookmarkAnchorComponent>();
  197. entity->CreateComponent<BookmarkAnchorVisualComponent>();
  198. const bool isGroupable = false;
  199. entity->CreateComponent<SceneMemberComponent>(isGroupable);
  200. entity->CreateComponent<GeometryComponent>();
  201. entity->CreateComponent<StylingComponent>(Styling::Elements::BookmarkAnchor, AZ::EntityId());
  202. entity->CreateComponent<PersistentIdComponent>();
  203. entity->CreateComponent<BookmarkAnchorLayerControllerComponent>();
  204. return entity;
  205. }
  206. AZ::Entity* GraphCanvasSystemComponent::CreateScene() const
  207. {
  208. // create a new empty canvas, give it a name to avoid serialization generating one based on
  209. // the ID (which in some cases caused diffs to fail in the editor)
  210. AZ::Entity* entity = aznew AZ::Entity("GraphCanvasScene");
  211. entity->CreateComponent<SceneComponent>();
  212. entity->CreateComponent<BookmarkManagerComponent>();
  213. return entity;
  214. }
  215. AZ::Entity* GraphCanvasSystemComponent::CreateCoreNode() const
  216. {
  217. return NodeComponent::CreateCoreNodeEntity();
  218. }
  219. AZ::Entity* GraphCanvasSystemComponent::CreateGeneralNode(const char* nodeType) const
  220. {
  221. return GeneralNodeLayoutComponent::CreateGeneralNodeEntity(nodeType);
  222. }
  223. AZ::Entity* GraphCanvasSystemComponent::CreateCommentNode() const
  224. {
  225. return CommentNodeLayoutComponent::CreateCommentNodeEntity();
  226. }
  227. AZ::Entity* GraphCanvasSystemComponent::CreateWrapperNode(const char* nodeType) const
  228. {
  229. return WrapperNodeLayoutComponent::CreateWrapperNodeEntity(nodeType);
  230. }
  231. AZ::Entity* GraphCanvasSystemComponent::CreateNodeGroup() const
  232. {
  233. return NodeGroupLayoutComponent::CreateNodeGroupEntity();
  234. }
  235. AZ::Entity* GraphCanvasSystemComponent::CreateCollapsedNodeGroup(const CollapsedNodeGroupConfiguration& collapsedNodeGroupConfiguration) const
  236. {
  237. return CollapsedNodeGroupComponent::CreateCollapsedNodeGroupEntity(collapsedNodeGroupConfiguration);
  238. }
  239. AZ::Entity* GraphCanvasSystemComponent::CreateSlot(const AZ::EntityId& nodeId, const SlotConfiguration& slotConfiguration) const
  240. {
  241. if (const DataSlotConfiguration* dataSlotConfiguration = azrtti_cast<const DataSlotConfiguration*>(&slotConfiguration))
  242. {
  243. return DataSlotComponent::CreateDataSlot(nodeId, (*dataSlotConfiguration));
  244. }
  245. else if (const ExecutionSlotConfiguration* executionSlotConfiguration = azrtti_cast<const ExecutionSlotConfiguration*>(&slotConfiguration))
  246. {
  247. return ExecutionSlotComponent::CreateExecutionSlot(nodeId, (*executionSlotConfiguration));
  248. }
  249. else if (const ExtenderSlotConfiguration* extenderSlotConfiguration = azrtti_cast<const ExtenderSlotConfiguration*>(&slotConfiguration))
  250. {
  251. return ExtenderSlotComponent::CreateExtenderSlot(nodeId, (*extenderSlotConfiguration));
  252. }
  253. else
  254. {
  255. AZ_Error("GraphCanvas", false, "Trying to create using an unknown Slot Configuration");
  256. }
  257. return nullptr;
  258. }
  259. NodePropertyDisplay* GraphCanvasSystemComponent::CreateBooleanNodePropertyDisplay(BooleanDataInterface* dataInterface) const
  260. {
  261. return aznew BooleanNodePropertyDisplay(dataInterface);
  262. }
  263. NodePropertyDisplay* GraphCanvasSystemComponent::CreateNumericNodePropertyDisplay(NumericDataInterface* dataInterface) const
  264. {
  265. return aznew NumericNodePropertyDisplay(dataInterface);
  266. }
  267. NodePropertyDisplay* GraphCanvasSystemComponent::CreateComboBoxNodePropertyDisplay(ComboBoxDataInterface* dataInterface) const
  268. {
  269. return aznew ComboBoxNodePropertyDisplay(dataInterface);
  270. }
  271. NodePropertyDisplay* GraphCanvasSystemComponent::CreateEntityIdNodePropertyDisplay(EntityIdDataInterface* dataInterface) const
  272. {
  273. return aznew EntityIdNodePropertyDisplay(dataInterface);
  274. }
  275. NodePropertyDisplay* GraphCanvasSystemComponent::CreateReadOnlyNodePropertyDisplay(ReadOnlyDataInterface* dataInterface) const
  276. {
  277. return aznew ReadOnlyNodePropertyDisplay(dataInterface);
  278. }
  279. NodePropertyDisplay* GraphCanvasSystemComponent::CreateStringNodePropertyDisplay(StringDataInterface* dataInterface) const
  280. {
  281. return aznew StringNodePropertyDisplay(dataInterface);
  282. }
  283. NodePropertyDisplay* GraphCanvasSystemComponent::CreateVectorNodePropertyDisplay(VectorDataInterface* dataInterface) const
  284. {
  285. return aznew VectorNodePropertyDisplay(dataInterface);
  286. }
  287. NodePropertyDisplay* GraphCanvasSystemComponent::CreateAssetIdNodePropertyDisplay(AssetIdDataInterface* dataInterface) const
  288. {
  289. return aznew AssetIdNodePropertyDisplay(dataInterface);
  290. }
  291. AZ::Entity* GraphCanvasSystemComponent::CreatePropertySlot(const AZ::EntityId& nodeId, const AZ::Crc32& propertyId, const SlotConfiguration& configuration) const
  292. {
  293. return PropertySlotComponent::CreatePropertySlot(nodeId, propertyId, configuration);
  294. }
  295. AZ::EntityId GraphCanvasSystemComponent::CreateStyleEntity(const AZStd::string& style) const
  296. {
  297. return StylingComponent::CreateStyleEntity(style);
  298. }
  299. AZ::EntityId GraphCanvasSystemComponent::CreateVirtualChild(const AZ::EntityId& real, const AZStd::string& virtualChildElement) const
  300. {
  301. return Styling::VirtualChildElement::Create(real, virtualChildElement);
  302. }
  303. void GraphCanvasSystemComponent::OnCatalogLoaded(const char* /*catalogFile*/)
  304. {
  305. GraphCanvas::TranslationRequestBus::Broadcast(&GraphCanvas::TranslationRequests::Restore);
  306. }
  307. void GraphCanvasSystemComponent::OnCatalogAssetRemoved(const AZ::Data::AssetId& /*assetId*/, const AZ::Data::AssetInfo& assetInfo)
  308. {
  309. if (assetInfo.m_assetType == azrtti_typeid<TranslationAsset>())
  310. {
  311. GraphCanvas::TranslationRequestBus::Broadcast(&GraphCanvas::TranslationRequests::Restore);
  312. }
  313. }
  314. void GraphCanvasSystemComponent::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
  315. {
  316. ReloadDatabase(assetId);
  317. }
  318. void GraphCanvasSystemComponent::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId)
  319. {
  320. ReloadDatabase(assetId);
  321. }
  322. void GraphCanvasSystemComponent::ReloadDatabase(const AZ::Data::AssetId& assetId)
  323. {
  324. AZ::Data::AssetInfo assetInfo;
  325. AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, assetId);
  326. if (assetInfo.m_assetType == azrtti_typeid<TranslationAsset>())
  327. {
  328. GraphCanvas::TranslationRequestBus::Broadcast(&GraphCanvas::TranslationRequests::Restore);
  329. }
  330. }
  331. void GraphCanvasSystemComponent::UnregisterAssetHandler()
  332. {
  333. if (m_assetHandler)
  334. {
  335. AZ::Data::AssetManager::Instance().UnregisterHandler(m_assetHandler.get());
  336. m_assetHandler.reset();
  337. }
  338. }
  339. }