ExtenderSlotComponent.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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 <Components/Slots/Extender/ExtenderSlotComponent.h>
  9. #include <Components/Slots/Extender/ExtenderSlotLayoutComponent.h>
  10. #include <Components/Slots/SlotConnectionFilterComponent.h>
  11. #include <Components/StylingComponent.h>
  12. #include <GraphCanvas/Components/Connections/ConnectionFilters/ConnectionFilters.h>
  13. namespace GraphCanvas
  14. {
  15. //////////////////////////
  16. // ExtenderSlotComponent
  17. //////////////////////////
  18. void ExtenderSlotComponent::Reflect(AZ::ReflectContext* reflectContext)
  19. {
  20. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
  21. if (serializeContext)
  22. {
  23. serializeContext->Class<ExtenderSlotComponent, SlotComponent>()
  24. ->Version(SaveVersion::Current)
  25. ->Field("ExtensionId", &ExtenderSlotComponent::m_extenderId)
  26. ;
  27. }
  28. }
  29. AZ::Entity* ExtenderSlotComponent::CreateExtenderSlot(const AZ::EntityId& nodeId, const ExtenderSlotConfiguration& extenderSlotConfiguration)
  30. {
  31. AZ::Entity* entity = SlotComponent::CreateCoreSlotEntity();
  32. ExtenderSlotComponent* extenderSlot = aznew ExtenderSlotComponent(extenderSlotConfiguration);
  33. if (!entity->AddComponent(extenderSlot))
  34. {
  35. AZ_Error("GraphCanvas", false, "Failed to add ExtenderSlotComponent to entity.");
  36. delete extenderSlot;
  37. delete entity;
  38. return nullptr;
  39. }
  40. entity->CreateComponent<ExtenderSlotLayoutComponent>();
  41. AZStd::string styleClass;
  42. StyledEntityRequestBus::EventResult(styleClass, nodeId, &StyledEntityRequests::GetClass);
  43. entity->CreateComponent<StylingComponent>(Styling::Elements::ExtenderSlot, nodeId, styleClass);
  44. SlotConnectionFilterComponent* connectionFilter = entity->CreateComponent<SlotConnectionFilterComponent>();
  45. SlotTypeFilter* slotTypeFilter = aznew SlotTypeFilter(ConnectionFilterType::Include);
  46. slotTypeFilter->AddSlotType(SlotTypes::DataSlot);
  47. connectionFilter->AddFilter(slotTypeFilter);
  48. ConnectionTypeFilter* connectionTypeFilter = aznew ConnectionTypeFilter(ConnectionFilterType::Include);
  49. switch (extenderSlot->GetConnectionType())
  50. {
  51. case ConnectionType::CT_Input:
  52. connectionTypeFilter->AddConnectionType(CT_Output);
  53. break;
  54. case ConnectionType::CT_Output:
  55. connectionTypeFilter->AddConnectionType(CT_Input);
  56. break;
  57. default:
  58. break;
  59. };
  60. connectionFilter->AddFilter(connectionTypeFilter);
  61. return entity;
  62. }
  63. ExtenderSlotComponent::ExtenderSlotComponent()
  64. : SlotComponent(SlotTypes::ExtenderSlot)
  65. {
  66. if (m_slotConfiguration.m_slotGroup == SlotGroups::Invalid)
  67. {
  68. m_slotConfiguration.m_slotGroup = SlotGroups::ExtenderGroup;
  69. }
  70. }
  71. ExtenderSlotComponent::ExtenderSlotComponent(const ExtenderSlotConfiguration& extenderSlotConfiguration)
  72. : SlotComponent(SlotTypes::ExtenderSlot, extenderSlotConfiguration)
  73. , m_extenderId(extenderSlotConfiguration.m_extenderId)
  74. {
  75. }
  76. ExtenderSlotComponent::~ExtenderSlotComponent()
  77. {
  78. }
  79. void ExtenderSlotComponent::Init()
  80. {
  81. SlotComponent::Init();
  82. }
  83. void ExtenderSlotComponent::Activate()
  84. {
  85. SlotComponent::Activate();
  86. ExtenderSlotRequestBus::Handler::BusConnect(GetEntityId());
  87. }
  88. void ExtenderSlotComponent::Deactivate()
  89. {
  90. SlotComponent::Deactivate();
  91. ExtenderSlotRequestBus::Handler::BusDisconnect();
  92. }
  93. void ExtenderSlotComponent::OnSceneMemberAboutToSerialize(GraphSerialization&)
  94. {
  95. }
  96. void ExtenderSlotComponent::AddConnectionId(const AZ::EntityId& connectionId, const Endpoint& endpoint)
  97. {
  98. AZ_UNUSED(connectionId);
  99. AZ_UNUSED(endpoint);
  100. }
  101. void ExtenderSlotComponent::RemoveConnectionId(const AZ::EntityId& connectionId, const Endpoint& endpoint)
  102. {
  103. AZ_UNUSED(connectionId);
  104. AZ_UNUSED(endpoint);
  105. }
  106. void ExtenderSlotComponent::SetNode(const AZ::EntityId& nodeId)
  107. {
  108. SlotComponent::SetNode(nodeId);
  109. }
  110. SlotConfiguration* ExtenderSlotComponent::CloneSlotConfiguration() const
  111. {
  112. ExtenderSlotConfiguration* slotConfiguration = aznew ExtenderSlotConfiguration();
  113. slotConfiguration->m_extenderId = m_extenderId;
  114. PopulateSlotConfiguration((*slotConfiguration));
  115. return slotConfiguration;
  116. }
  117. int ExtenderSlotComponent::GetLayoutPriority() const
  118. {
  119. return std::numeric_limits<int>::min();
  120. }
  121. void ExtenderSlotComponent::SetLayoutPriority(int layoutPriority)
  122. {
  123. // Extenders should not have their layout priority changed
  124. AZ_UNUSED(layoutPriority);
  125. }
  126. void ExtenderSlotComponent::OnMoveFinalized(bool isValidConnection)
  127. {
  128. ConnectionNotificationBus::Handler::BusDisconnect();
  129. m_proposedSlot = false;
  130. m_trackedConnectionId.SetInvalid();
  131. if (m_createdSlot.IsValid())
  132. {
  133. if (isValidConnection)
  134. {
  135. NodeId nodeId = GetNode();
  136. GraphId graphId;
  137. SceneMemberRequestBus::EventResult(graphId, GetNode(), &SceneMemberRequests::GetScene);
  138. GraphModelRequestBus::Event(graphId, &GraphModelRequests::FinalizeExtension, nodeId, m_extenderId);
  139. m_createdSlot.SetInvalid();
  140. }
  141. else
  142. {
  143. EraseSlot();
  144. }
  145. }
  146. }
  147. void ExtenderSlotComponent::OnSourceSlotIdChanged(const SlotId& oldSlotId, const SlotId& /*newSlotId*/)
  148. {
  149. if (m_proposedSlot)
  150. {
  151. if (oldSlotId == m_createdSlot)
  152. {
  153. CleanupProposedSlot();
  154. }
  155. }
  156. }
  157. void ExtenderSlotComponent::OnTargetSlotIdChanged(const SlotId& oldSlotId, const SlotId& /*newSlotId*/)
  158. {
  159. if (m_proposedSlot)
  160. {
  161. if (oldSlotId == m_createdSlot)
  162. {
  163. CleanupProposedSlot();
  164. }
  165. }
  166. }
  167. void ExtenderSlotComponent::TriggerExtension()
  168. {
  169. // Don't need to track anything. Just create the slot then ignore whatever the return is.
  170. ConstructSlot(GraphModelRequests::ExtensionRequestReason::UserRequest);
  171. if (m_createdSlot.IsValid())
  172. {
  173. const bool isValidSlot = true;
  174. OnMoveFinalized(isValidSlot);
  175. GraphId graphId;
  176. SceneMemberRequestBus::EventResult(graphId, GetNode(), &SceneMemberRequests::GetScene);
  177. GraphModelRequestBus::Event(graphId, &GraphModelRequests::RequestUndoPoint);
  178. }
  179. m_createdSlot.SetInvalid();
  180. }
  181. Endpoint ExtenderSlotComponent::ExtendForConnectionProposal(const ConnectionId& connectionId, const Endpoint& endpoint)
  182. {
  183. // Don't want to extend if we are already extended.
  184. if (m_createdSlot.IsValid())
  185. {
  186. return Endpoint();
  187. }
  188. ConstructSlot(GraphModelRequests::ExtensionRequestReason::ConnectionProposal);
  189. if (!m_createdSlot.IsValid())
  190. {
  191. return Endpoint();
  192. }
  193. bool isValidConnection = false;
  194. SlotRequestBus::EventResult(isValidConnection, m_createdSlot, &SlotRequests::CanCreateConnectionTo, endpoint);
  195. if (!isValidConnection)
  196. {
  197. EraseSlot();
  198. return Endpoint();
  199. }
  200. m_proposedSlot = true;
  201. m_trackedConnectionId = connectionId;
  202. ConnectionNotificationBus::Handler::BusConnect(connectionId);
  203. return Endpoint(GetNode(), m_createdSlot);
  204. }
  205. void ExtenderSlotComponent::OnFinalizeDisplay()
  206. {
  207. }
  208. void ExtenderSlotComponent::ConstructSlot(GraphModelRequests::ExtensionRequestReason reason)
  209. {
  210. if (!m_createdSlot.IsValid())
  211. {
  212. NodeId nodeId = GetNode();
  213. GraphId graphId;
  214. SceneMemberRequestBus::EventResult(graphId, nodeId, &SceneMemberRequests::GetScene);
  215. {
  216. ScopedGraphUndoBlocker undoBlocker(graphId);
  217. GraphModelRequestBus::EventResult(m_createdSlot, graphId, &GraphModelRequests::RequestExtension, nodeId, m_extenderId, reason);
  218. }
  219. }
  220. }
  221. void ExtenderSlotComponent::EraseSlot()
  222. {
  223. if (m_createdSlot.IsValid())
  224. {
  225. NodeId nodeId = GetNode();
  226. GraphId graphId;
  227. SceneMemberRequestBus::EventResult(graphId, nodeId, &SceneMemberRequests::GetScene);
  228. {
  229. ScopedGraphUndoBlocker undoBlocker(graphId);
  230. GraphModelRequestBus::Event(graphId, &GraphModelRequests::RemoveSlot, Endpoint(nodeId, m_createdSlot));
  231. GraphModelRequestBus::Event(graphId, &GraphModelRequests::ExtensionCancelled, nodeId, m_extenderId);
  232. }
  233. m_createdSlot.SetInvalid();
  234. }
  235. }
  236. void ExtenderSlotComponent::CleanupProposedSlot()
  237. {
  238. ConnectionNotificationBus::Handler::BusDisconnect();
  239. m_proposedSlot = false;
  240. m_trackedConnectionId.SetInvalid();
  241. EraseSlot();
  242. }
  243. AZ::Entity* ExtenderSlotComponent::ConstructConnectionEntity(const Endpoint& sourceEndpoint, const Endpoint& targetEndpoint, bool createModelConnection)
  244. {
  245. ConstructSlot(GraphModelRequests::ExtensionRequestReason::Internal);
  246. if (m_createdSlot.IsValid())
  247. {
  248. Endpoint otherEndpoint;
  249. if (GetConnectionType() == CT_Input)
  250. {
  251. otherEndpoint = sourceEndpoint;
  252. }
  253. else if (GetConnectionType() == CT_Output)
  254. {
  255. otherEndpoint = targetEndpoint;
  256. }
  257. if (createModelConnection)
  258. {
  259. SlotRequestBus::EventResult(m_trackedConnectionId, m_createdSlot, &SlotRequests::CreateConnectionWithEndpoint, otherEndpoint);
  260. }
  261. else
  262. {
  263. SlotRequestBus::EventResult(m_trackedConnectionId, m_createdSlot, &SlotRequests::DisplayConnectionWithEndpoint, otherEndpoint);
  264. }
  265. AZ::Entity* connectionEntity = nullptr;
  266. if (m_trackedConnectionId.IsValid())
  267. {
  268. ConnectionNotificationBus::Handler::BusConnect(m_trackedConnectionId);
  269. AZ::ComponentApplicationBus::BroadcastResult(connectionEntity, &AZ::ComponentApplicationRequests::FindEntity, m_trackedConnectionId);
  270. }
  271. return connectionEntity;
  272. }
  273. return nullptr;
  274. }
  275. }