NodeComponent.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  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 <QCoreApplication>
  9. #include <AzCore/Component/ComponentApplication.h>
  10. #include <AzCore/Serialization/EditContext.h>
  11. #include <AzCore/std/smart_ptr/unique_ptr.h>
  12. #include <AzToolsFramework/Entity/EditorEntityHelpers.h>
  13. #include <Components/Nodes/NodeComponent.h>
  14. #include <Components/GeometryComponent.h>
  15. #include <Components/PersistentIdComponent.h>
  16. #include <GraphCanvas/Components/Nodes/NodeUIBus.h>
  17. #include <GraphCanvas/Components/Slots/SlotBus.h>
  18. namespace GraphCanvas
  19. {
  20. //////////////////
  21. // NodeComponent
  22. //////////////////
  23. void NodeComponent::Reflect(AZ::ReflectContext* context)
  24. {
  25. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
  26. if (!serializeContext)
  27. {
  28. return;
  29. }
  30. serializeContext->Class<NodeSaveData>()
  31. ->Version(1)
  32. ->Field("HideUnusedSlots", &NodeSaveData::m_hideUnusedSlots)
  33. ;
  34. serializeContext->Class<NodeComponent, GraphCanvasPropertyComponent>()
  35. ->Version(4)
  36. ->Field("Configuration", &NodeComponent::m_configuration)
  37. ->Field("Slots", &NodeComponent::m_slots)
  38. ->Field("UserData", &NodeComponent::m_userData)
  39. ->FieldFromBase<NodeComponent>("SaveData", &ComponentSaveDataInterface<NodeSaveData>::m_saveData)
  40. ;
  41. AZ::EditContext* editContext = serializeContext->GetEditContext();
  42. if (!editContext)
  43. {
  44. return;
  45. }
  46. editContext->Class<NodeComponent>("Node", "The node's UI representation")
  47. ->ClassElement(AZ::Edit::ClassElements::EditorData, "Node's class attributes")
  48. ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
  49. ->DataElement(AZ::Edit::UIHandlers::Default, &NodeComponent::m_configuration, "Configuration", "This node's properties")
  50. ;
  51. }
  52. AZ::Entity* NodeComponent::CreateCoreNodeEntity(const NodeConfiguration& config)
  53. {
  54. // Create this Node's entity.
  55. AZ::Entity* entity = aznew AZ::Entity();
  56. entity->CreateComponent<NodeComponent>(config);
  57. entity->CreateComponent<GeometryComponent>();
  58. entity->CreateComponent<PersistentIdComponent>();
  59. return entity;
  60. }
  61. NodeComponent::NodeComponent()
  62. {
  63. }
  64. NodeComponent::NodeComponent(const NodeConfiguration& config)
  65. : m_configuration(config)
  66. {
  67. }
  68. NodeComponent::~NodeComponent()
  69. {
  70. for (auto& slotRef : m_slots)
  71. {
  72. delete slotRef;
  73. }
  74. }
  75. void NodeComponent::Init()
  76. {
  77. InitSaveDataInterface(GetEntityId());
  78. AZ::EntityBus::Handler::BusConnect(GetEntityId());
  79. for (auto entityRef : m_slots)
  80. {
  81. AZ::Entity* slotEntity = entityRef;
  82. if (slotEntity)
  83. {
  84. if (slotEntity->GetState() == AZ::Entity::State::Constructed)
  85. {
  86. slotEntity->Init();
  87. }
  88. }
  89. }
  90. }
  91. void NodeComponent::Activate()
  92. {
  93. }
  94. void NodeComponent::Deactivate()
  95. {
  96. GraphCanvasPropertyComponent::Deactivate();
  97. GroupableSceneMemberRequestBus::Handler::BusDisconnect();
  98. SceneMemberRequestBus::Handler::BusDisconnect();
  99. NodeRequestBus::Handler::BusDisconnect();
  100. for (AZ::Entity* slotEntity : m_slots)
  101. {
  102. if (slotEntity)
  103. {
  104. if (slotEntity && slotEntity->GetState() == AZ::Entity::State::Active)
  105. {
  106. slotEntity->Deactivate();
  107. }
  108. }
  109. }
  110. ConnectionNotificationBus::Handler::BusDisconnect();
  111. }
  112. void NodeComponent::OnConnectedTo(const AZ::EntityId& /*connectionId*/, const Endpoint& /*endpoint*/)
  113. {
  114. UpdateDisabledStateVisuals();
  115. }
  116. void NodeComponent::OnDisconnectedFrom(const AZ::EntityId& /*connectionId*/, const Endpoint& /*endpoint*/)
  117. {
  118. RootGraphicsItemRequests* itemInterface = RootGraphicsItemRequestBus::FindFirstHandler(GetEntityId());
  119. if (itemInterface)
  120. {
  121. RootGraphicsItemEnabledState enabledState = itemInterface->GetEnabledState();
  122. RootGraphicsItemEnabledState updatedState = UpdateEnabledState();
  123. if (updatedState != enabledState)
  124. {
  125. AZStd::unordered_set< NodeId > updatedStateSet;
  126. updatedStateSet.insert(GetEntityId());
  127. GraphUtils::SetNodesEnabledState(updatedStateSet, updatedState);
  128. }
  129. }
  130. }
  131. void NodeComponent::OnEntityExists(const AZ::EntityId& /*entityId*/)
  132. {
  133. // Temporary version conversion added in 1.xx to add a PersistentId onto the SceneMembers.
  134. // Remove after a few revisions with warnings about resaving graphs.
  135. if (AZ::EntityUtils::FindFirstDerivedComponent<PersistentIdComponent>(GetEntityId()) == nullptr)
  136. {
  137. AZ::Entity* selfEntity = GetEntity();
  138. if (selfEntity)
  139. {
  140. selfEntity->CreateComponent<PersistentIdComponent>();
  141. }
  142. }
  143. }
  144. void NodeComponent::OnEntityActivated(const AZ::EntityId&)
  145. {
  146. AZ::EntityBus::Handler::BusDisconnect();
  147. // Removing the Node properties from the side panel until we decide what we want to show.
  148. //GraphCanvasPropertyComponent::Activate();
  149. NodeRequestBus::Handler::BusConnect(GetEntityId());
  150. SceneMemberRequestBus::Handler::BusConnect(GetEntityId());
  151. GroupableSceneMemberRequestBus::Handler::BusConnect(GetEntityId());
  152. for (AZ::Entity* slotEntity : m_slots)
  153. {
  154. if (slotEntity)
  155. {
  156. if (slotEntity && slotEntity->GetState() == AZ::Entity::State::Init)
  157. {
  158. slotEntity->Activate();
  159. SlotRequestBus::Event(slotEntity->GetId(), &SlotRequests::SetNode, GetEntityId());
  160. StyleNotificationBus::Event(slotEntity->GetId(), &StyleNotifications::OnStyleChanged);
  161. }
  162. }
  163. }
  164. NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnNodeActivated);
  165. }
  166. void NodeComponent::SetScene(const AZ::EntityId& sceneId)
  167. {
  168. if (SceneNotificationBus::Handler::BusIsConnected())
  169. {
  170. SceneMemberNotificationBus::Event(GetEntityId(), &SceneMemberNotifications::OnRemovedFromScene, m_sceneId);
  171. SceneNotificationBus::Handler::BusDisconnect(m_sceneId);
  172. }
  173. m_sceneId = sceneId;
  174. RegisterIds(GetEntityId(), m_sceneId);
  175. if (m_sceneId.IsValid())
  176. {
  177. SceneNotificationBus::Handler::BusConnect(m_sceneId);
  178. SceneMemberNotificationBus::Handler::BusConnect(m_sceneId);
  179. SceneMemberNotificationBus::Event(GetEntityId(), &SceneMemberNotifications::OnSceneSet, m_sceneId);
  180. OnStylesChanged();
  181. AZ::EntityId grid;
  182. SceneRequestBus::EventResult(grid, m_sceneId, &SceneRequests::GetGrid);
  183. NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::SetGrid, grid);
  184. NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::SetSnapToGrid, true);
  185. NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::SetResizeToGrid, true);
  186. NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnAddedToScene, m_sceneId);
  187. }
  188. }
  189. void NodeComponent::ClearScene(const AZ::EntityId& oldSceneId)
  190. {
  191. SceneNotificationBus::Handler::BusDisconnect(oldSceneId);
  192. AZ_Assert(m_sceneId.IsValid(), "This node (ID: %p) is not in a scene (ID: %p)!", GetEntityId(), m_sceneId);
  193. AZ_Assert(GetEntityId().IsValid(), "This node (ID: %p) doesn't have an Entity!", GetEntityId());
  194. if (!m_sceneId.IsValid() || !GetEntityId().IsValid())
  195. {
  196. return;
  197. }
  198. SceneMemberNotificationBus::Event(GetEntityId(), &SceneMemberNotifications::OnRemovedFromScene, m_sceneId);
  199. m_sceneId.SetInvalid();
  200. }
  201. void NodeComponent::SignalMemberSetupComplete()
  202. {
  203. SceneMemberNotificationBus::Event(GetEntityId(), &SceneMemberNotifications::OnMemberSetupComplete);
  204. if (m_saveData.m_hideUnusedSlots)
  205. {
  206. SceneRequests* requests = SceneRequestBus::FindFirstHandler(GetScene());
  207. if (requests->IsLoading() || requests->IsPasting())
  208. {
  209. m_updateSlotState = true;
  210. }
  211. else
  212. {
  213. HideUnusedSlotsImpl();
  214. }
  215. }
  216. }
  217. AZ::EntityId NodeComponent::GetScene() const
  218. {
  219. return m_sceneId;
  220. }
  221. void NodeComponent::OnSceneReady()
  222. {
  223. SceneMemberNotificationBus::Event(GetEntityId(), &SceneMemberNotifications::OnSceneReady);
  224. }
  225. void NodeComponent::OnStylesChanged()
  226. {
  227. for (auto& slotRef : m_slots)
  228. {
  229. StyleNotificationBus::Event(slotRef->GetId(), &StyleNotifications::OnStyleChanged);
  230. }
  231. }
  232. void NodeComponent::OnGraphLoadComplete()
  233. {
  234. if (m_updateSlotState)
  235. {
  236. m_updateSlotState = false;
  237. if (m_saveData.m_hideUnusedSlots)
  238. {
  239. HideUnusedSlotsImpl();
  240. }
  241. }
  242. }
  243. void NodeComponent::OnPasteEnd()
  244. {
  245. if (m_updateSlotState)
  246. {
  247. m_updateSlotState = false;
  248. if (m_saveData.m_hideUnusedSlots)
  249. {
  250. HideUnusedSlotsImpl();
  251. }
  252. }
  253. }
  254. void NodeComponent::SetTooltip(const AZStd::string& tooltip)
  255. {
  256. m_configuration.SetTooltip(tooltip);
  257. NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnTooltipChanged, m_configuration.GetTooltip());
  258. }
  259. void NodeComponent::AddSlot(const AZ::EntityId& slotId)
  260. {
  261. AZ_Assert(slotId.IsValid(), "Slot entity (ID: %s) is not valid!", slotId.ToString().data());
  262. if (SlotRequestBus::FindFirstHandler(slotId))
  263. {
  264. auto slotEntity = AzToolsFramework::GetEntityById(slotId);
  265. auto entry = AZStd::find_if(m_slots.begin(), m_slots.end(), [slotId](AZ::Entity* slot) { return slot->GetId() == slotId; });
  266. if (entry == m_slots.end() && slotEntity)
  267. {
  268. m_slots.emplace_back(slotEntity);
  269. SlotRequestBus::Event(slotId, &SlotRequests::SetNode, GetEntityId());
  270. NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnSlotAddedToNode, slotId);
  271. SlotNotificationBus::MultiHandler::BusConnect(slotId);
  272. }
  273. }
  274. else
  275. {
  276. AZ_Assert(false, "Entity (ID: %s) does not implement SlotRequestBus", slotId.ToString().data());
  277. }
  278. }
  279. void NodeComponent::RemoveSlot(const AZ::EntityId& slotId)
  280. {
  281. AZ_Assert(slotId.IsValid(), "Slot (ID: %s) is not valid!", slotId.ToString().data());
  282. auto entry = AZStd::find_if(m_slots.begin(), m_slots.end(), [slotId](AZ::Entity* slot) { return slot->GetId() == slotId; });
  283. AZ_Assert(entry != m_slots.end(), "Slot (ID: %s) is unknown", slotId.ToString().data());
  284. if (entry != m_slots.end())
  285. {
  286. m_slots.erase(entry);
  287. QGraphicsLayoutItem* layoutItem = nullptr;
  288. VisualRequestBus::EventResult(layoutItem, slotId, &VisualRequests::AsGraphicsLayoutItem);
  289. SlotNotificationBus::MultiHandler::BusDisconnect(slotId);
  290. NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnSlotRemovedFromNode, slotId);
  291. SlotRequestBus::Event(slotId, &SlotRequests::ClearConnections);
  292. SlotRequestBus::Event(slotId, &SlotRequests::SetNode, AZ::EntityId());
  293. AZ::ComponentApplicationBus::Broadcast(&AZ::ComponentApplicationRequests::DeleteEntity, slotId);
  294. NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::AdjustSize);
  295. delete layoutItem;
  296. }
  297. }
  298. AZStd::vector<AZ::EntityId> NodeComponent::GetSlotIds() const
  299. {
  300. AZStd::vector<AZ::EntityId> result;
  301. result.reserve(m_slots.size());
  302. for (auto slot : m_slots)
  303. {
  304. result.emplace_back(slot->GetId());
  305. }
  306. return result;
  307. }
  308. AZStd::vector<SlotId> NodeComponent::GetVisibleSlotIds() const
  309. {
  310. AZStd::vector< SlotId > result;
  311. result.reserve(m_slots.size());
  312. for (auto slot : m_slots)
  313. {
  314. SlotId slotId = slot->GetId();
  315. bool isVisible = false;
  316. SlotGroup slotGroup = SlotGroups::Invalid;
  317. SlotRequestBus::EventResult(slotGroup, slotId, &SlotRequests::GetSlotGroup);
  318. SlotLayoutRequestBus::EventResult(isVisible, GetEntityId(), &SlotLayoutRequests::IsSlotGroupVisible, slotGroup);
  319. if (!isVisible)
  320. {
  321. continue;
  322. }
  323. result.emplace_back(slotId);
  324. }
  325. return result;
  326. }
  327. AZStd::vector<SlotId> NodeComponent::FindVisibleSlotIdsByType(const ConnectionType& connectionType, const SlotType& slotType) const
  328. {
  329. AZStd::vector<SlotId> result;
  330. result.reserve(m_slots.size());
  331. for (auto slot : m_slots)
  332. {
  333. SlotId slotId = slot->GetId();
  334. bool isVisible = false;
  335. SlotGroup slotGroup = SlotGroups::Invalid;
  336. SlotRequestBus::EventResult(slotGroup, slotId, &SlotRequests::GetSlotGroup);
  337. SlotLayoutRequestBus::EventResult(isVisible, GetEntityId(), &SlotLayoutRequests::IsSlotGroupVisible, slotGroup);
  338. if (!isVisible)
  339. {
  340. continue;
  341. }
  342. ConnectionType testConnectionType = ConnectionType::CT_Invalid;
  343. SlotRequestBus::EventResult(testConnectionType, slotId, &SlotRequests::GetConnectionType);
  344. if (testConnectionType == ConnectionType::CT_Invalid || testConnectionType != connectionType)
  345. {
  346. continue;
  347. }
  348. SlotType testSlotType = SlotTypes::Invalid;
  349. SlotRequestBus::EventResult(testSlotType, slotId, &SlotRequests::GetSlotType);
  350. if (testSlotType == SlotTypes::Invalid || testSlotType != slotType)
  351. {
  352. continue;
  353. }
  354. result.emplace_back(slotId);
  355. }
  356. return result;
  357. }
  358. bool NodeComponent::HasConnections() const
  359. {
  360. bool hasConnections = false;
  361. for (auto slot : m_slots)
  362. {
  363. SlotId slotId = slot->GetId();
  364. SlotRequestBus::EventResult(hasConnections, slotId, &SlotRequests::HasConnections);
  365. if (hasConnections)
  366. {
  367. break;
  368. }
  369. }
  370. return hasConnections;
  371. }
  372. AZStd::any* NodeComponent::GetUserData()
  373. {
  374. return &m_userData;
  375. }
  376. bool NodeComponent::IsWrapped() const
  377. {
  378. return m_wrappingNode.IsValid();
  379. }
  380. void NodeComponent::SetWrappingNode(const AZ::EntityId& wrappingNode)
  381. {
  382. if (!wrappingNode.IsValid())
  383. {
  384. AZ::EntityId wrappedNodeCache = m_wrappingNode;
  385. m_wrappingNode = wrappingNode;
  386. if (wrappedNodeCache.IsValid())
  387. {
  388. NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnNodeUnwrapped, wrappedNodeCache);
  389. }
  390. }
  391. else if (!m_wrappingNode.IsValid())
  392. {
  393. m_wrappingNode = wrappingNode;
  394. NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnNodeWrapped, wrappingNode);
  395. }
  396. else
  397. {
  398. AZ_Warning("Graph Canvas", false, "The same node is trying to be wrapped by two objects at once.");
  399. }
  400. }
  401. AZ::EntityId NodeComponent::GetWrappingNode() const
  402. {
  403. return m_wrappingNode;
  404. }
  405. void NodeComponent::SignalBatchedConnectionManipulationBegin()
  406. {
  407. NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnBatchedConnectionManipulationBegin);
  408. }
  409. void NodeComponent::SignalBatchedConnectionManipulationEnd()
  410. {
  411. NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnBatchedConnectionManipulationEnd);
  412. }
  413. void NodeComponent::SignalConnectionMoveBegin(const ConnectionId& connectionId)
  414. {
  415. ConnectionNotificationBus::Handler::BusConnect(connectionId);
  416. }
  417. RootGraphicsItemEnabledState NodeComponent::UpdateEnabledState()
  418. {
  419. RootGraphicsItemRequests* graphicsInterface = RootGraphicsItemRequestBus::FindFirstHandler(GetEntityId());
  420. if (graphicsInterface == nullptr)
  421. {
  422. return RootGraphicsItemEnabledState::ES_Enabled;
  423. }
  424. if (graphicsInterface && graphicsInterface->GetEnabledState() == RootGraphicsItemEnabledState::ES_Disabled)
  425. {
  426. return graphicsInterface->GetEnabledState();
  427. }
  428. bool foundDisabledNode = false;
  429. bool foundEnabledNode = false;
  430. AZStd::unordered_set< NodeId > connectedNodes;
  431. for (AZ::Entity* slotEntity : m_slots)
  432. {
  433. Endpoint currentEndpoint(GetEntityId(), slotEntity->GetId());
  434. SlotRequests* slotInterface = SlotRequestBus::FindFirstHandler(slotEntity->GetId());
  435. if (slotInterface == nullptr)
  436. {
  437. continue;
  438. }
  439. ConnectionType connectionType = slotInterface->GetConnectionType();
  440. SlotType slotType = slotInterface->GetSlotType();
  441. // We only want to follow execution In's for now.
  442. if (connectionType == CT_Input
  443. && slotType == SlotTypes::ExecutionSlot)
  444. {
  445. AZStd::vector< ConnectionId > connections;
  446. SlotRequestBus::EventResult(connections, slotEntity->GetId(), &SlotRequests::GetConnections);
  447. for (ConnectionId connectionId : connections)
  448. {
  449. Endpoint otherEndpoint;
  450. ConnectionRequestBus::EventResult(otherEndpoint, connectionId, &ConnectionRequests::FindOtherEndpoint, currentEndpoint);
  451. if (otherEndpoint.IsValid())
  452. {
  453. bool isEnabled = false;
  454. RootGraphicsItemRequestBus::EventResult(isEnabled, otherEndpoint.GetNodeId(), &RootGraphicsItemRequests::IsEnabled);
  455. if (isEnabled)
  456. {
  457. foundEnabledNode = true;
  458. break;
  459. }
  460. else
  461. {
  462. foundDisabledNode = true;
  463. }
  464. }
  465. }
  466. }
  467. }
  468. if (foundDisabledNode && !foundEnabledNode)
  469. {
  470. graphicsInterface->SetEnabledState(RootGraphicsItemEnabledState::ES_PartialDisabled);
  471. }
  472. else
  473. {
  474. graphicsInterface->SetEnabledState(RootGraphicsItemEnabledState::ES_Enabled);
  475. }
  476. return graphicsInterface->GetEnabledState();
  477. }
  478. bool NodeComponent::HasHideableSlots() const
  479. {
  480. bool canHideSlots = false;
  481. for (auto slotEntity : m_slots)
  482. {
  483. if (GraphUtils::IsSlotHideable(slotEntity->GetId()))
  484. {
  485. canHideSlots = true;
  486. break;
  487. }
  488. }
  489. return canHideSlots;
  490. }
  491. bool NodeComponent::IsHidingUnusedSlots() const
  492. {
  493. return m_saveData.m_hideUnusedSlots;
  494. }
  495. void NodeComponent::ShowAllSlots()
  496. {
  497. if (m_saveData.m_hideUnusedSlots)
  498. {
  499. for (auto slotEntity : m_slots)
  500. {
  501. VisualRequestBus::Event(slotEntity->GetId(), &VisualRequests::SetVisible, true);
  502. }
  503. m_saveData.m_hideUnusedSlots = false;
  504. m_saveData.SignalDirty();
  505. }
  506. }
  507. void NodeComponent::HideUnusedSlots()
  508. {
  509. // Always hide the slots to deal with new slots that might have been added. Or previously filled slots that
  510. // are no unfilled.
  511. HideUnusedSlotsImpl();
  512. m_saveData.m_hideUnusedSlots = true;
  513. m_saveData.SignalDirty();
  514. }
  515. void NodeComponent::SignalNodeAboutToBeDeleted()
  516. {
  517. NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnNodeAboutToBeDeleted);
  518. }
  519. void NodeComponent::OnMoveFinalized(bool isValidConnection)
  520. {
  521. if (isValidConnection)
  522. {
  523. UpdateDisabledStateVisuals();
  524. }
  525. ConnectionNotificationBus::Handler::BusDisconnect();
  526. }
  527. bool NodeComponent::IsGrouped() const
  528. {
  529. return !IsWrapped() && m_owningGroupId.IsValid();
  530. }
  531. const AZ::EntityId& NodeComponent::GetGroupId() const
  532. {
  533. return m_owningGroupId;
  534. }
  535. void NodeComponent::RegisterToGroup(const AZ::EntityId& groupId)
  536. {
  537. if (!IsWrapped())
  538. {
  539. m_owningGroupId = groupId;
  540. GroupableSceneMemberNotificationBus::Event(GetEntityId(), &GroupableSceneMemberNotifications::OnGroupChanged);
  541. }
  542. }
  543. void NodeComponent::UnregisterFromGroup(const AZ::EntityId& groupId)
  544. {
  545. if (m_owningGroupId == groupId)
  546. {
  547. m_owningGroupId.SetInvalid();
  548. GroupableSceneMemberNotificationBus::Event(GetEntityId(), &GroupableSceneMemberNotifications::OnGroupChanged);
  549. }
  550. }
  551. void NodeComponent::RemoveFromGroup()
  552. {
  553. if (m_owningGroupId.IsValid())
  554. {
  555. NodeGroupRequestBus::Event(m_owningGroupId, &NodeGroupRequests::RemoveElementFromGroup, GetEntityId());
  556. }
  557. }
  558. void NodeComponent::HideUnusedSlotsImpl()
  559. {
  560. HideSlotConfig hideConfig;
  561. for (auto slotEntity : m_slots)
  562. {
  563. Endpoint endpoint(GetEntityId(), slotEntity->GetId());
  564. if (GraphUtils::CanHideEndpoint(endpoint, hideConfig))
  565. {
  566. VisualRequestBus::Event(endpoint.GetSlotId(), &VisualRequests::SetVisible, false);
  567. }
  568. }
  569. }
  570. void NodeComponent::UpdateDisabledStateVisuals()
  571. {
  572. RootGraphicsItemRequests* itemInterface = RootGraphicsItemRequestBus::FindFirstHandler(GetEntityId());
  573. if (itemInterface)
  574. {
  575. RootGraphicsItemEnabledState enabledState = itemInterface->GetEnabledState();
  576. RootGraphicsItemEnabledState updatedState = UpdateEnabledState();
  577. if (updatedState != enabledState)
  578. {
  579. AZStd::unordered_set< NodeId > updatedStateSet;
  580. updatedStateSet.insert(GetEntityId());
  581. GraphUtils::SetNodesEnabledState(updatedStateSet, updatedState);
  582. }
  583. }
  584. }
  585. }