PrefabTestFixture.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. #pragma once
  9. #include <AzCore/Settings/SettingsRegistryMergeUtils.h>
  10. #include <AzToolsFramework/Prefab/PrefabSystemComponent.h>
  11. #include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
  12. #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
  13. #include <Prefab/PrefabTestData.h>
  14. #include <Prefab/PrefabTestUtils.h>
  15. namespace AzToolsFramework
  16. {
  17. namespace Prefab
  18. {
  19. class InstanceEntityMapperInterface;
  20. class PrefabLoaderInterface;
  21. }
  22. class PrefabEditorEntityOwnershipInterface;
  23. }
  24. namespace UnitTest
  25. {
  26. using namespace AzToolsFramework::Prefab;
  27. using namespace PrefabTestUtils;
  28. //! Defines prefab test tools application.
  29. class PrefabTestToolsApplication
  30. : public ToolsTestApplication
  31. {
  32. public:
  33. PrefabTestToolsApplication(AZStd::string appName);
  34. };
  35. //! Defines prefab testing environment.
  36. class PrefabTestFixture
  37. : public ToolsApplicationFixture<>
  38. , public AzToolsFramework::EditorRequestBus::Handler
  39. {
  40. protected:
  41. inline static const char* PrefabMockFilePath = "SomePath";
  42. inline static const char* NestedPrefabMockFilePath = "SomePathToNested";
  43. inline static const char* WheelPrefabMockFilePath = "SomePathToWheel";
  44. inline static const char* AxlePrefabMockFilePath = "SomePathToAxle";
  45. inline static const char* CarPrefabMockFilePath = "SomePathToCar";
  46. void SetUpEditorFixtureImpl() override;
  47. void TearDownEditorFixtureImpl() override;
  48. AZStd::unique_ptr<ToolsTestApplication> CreateTestApplication() override;
  49. //! Creates root prefab and focus on the root prefab instance as level.
  50. void CreateRootPrefab();
  51. //! Functions that internally call prefab public interface APIs to create editor entities and prefab instances.
  52. //! Entities and instances are updated correctly, and template DOM representations are also updated accordingly.
  53. //! Note:
  54. //! 1. It may create entities and instances as overrides depending on which instance is currently focused.
  55. //! 2. The returned entity id cannot always be depended on. For example, if the new entity is used to create a new prefab,
  56. //! the entity id changes after it is added to the instance.
  57. //! @{
  58. AZ::EntityId CreateEditorEntityUnderRoot(const AZStd::string& entityName);
  59. AZ::EntityId CreateEditorEntity(const AZStd::string& entityName, AZ::EntityId parentId);
  60. AZ::EntityId CreateEditorPrefab(AZ::IO::PathView filePath, const AzToolsFramework::EntityIdList& entityIds);
  61. AZ::EntityId InstantiateEditorPrefab(AZ::IO::PathView filePath, AZ::EntityId parentId);
  62. //! @}
  63. //! Creates a loose entity object with no components.
  64. //! This creates an entity object through aznew rather than calling public prefab APIs.
  65. //! Note: Editor components can be added manually or by calling AddRequiredEditorComponents.
  66. //! @param entityName Name of the new entity.
  67. //! @param shouldActivate Flag that decides if the new entity should be activated after creation.
  68. //! @return The new entity.
  69. AZ::Entity* CreateEntity(const AZStd::string& entityName, bool shouldActivate = true);
  70. //! Helper function to get container entity id of root prefab.
  71. //! @return Container entity id for root prefab.
  72. AZ::EntityId GetRootContainerEntityId();
  73. //! After prefab template is updated, we need to propagate the changes to all prefab instances.
  74. //! Note that any instances involved inside this template may be destroyed and recreated, so do not hold
  75. //! onto Entity* or Component* pointers into objects that may be affected by this call. They may not be valid.
  76. void PropagateAllTemplateChanges();
  77. //! Helper function to compare two instances and asserts will be thrown if two instances are not identical.
  78. //! @param instanceA The given first instance.
  79. //! @param instanceB The given second instance.
  80. //! @param shouldCompareLinkIds Flag of whether it compares two link ids.
  81. //! @param shouldCompareContainerEntities Flag of whether it compares two container entities.
  82. void CompareInstances(const Instance& instanceA, const Instance& instanceB, bool shouldCompareLinkIds = true,
  83. bool shouldCompareContainerEntities = true);
  84. void DeleteInstances(const InstanceList& instancesToDelete);
  85. //! Helper function for finding entity alias by entity name in owning instance.
  86. //! If there are multiple aliases, then return the first one it found.
  87. //! @param containerEntityId The given container entity id of the owning instance.
  88. //! @param entityName Entity name for the entity alias to find.
  89. //! @return Entity alias for the given entity name. Returns "" if not found.
  90. EntityAlias FindEntityAliasInInstance(AZ::EntityId containerEntityId, const AZStd::string& entityName);
  91. //! Helper function for finding nested instance alias by container entity name in owning instance.
  92. //! If there are multiple aliases, then return the first one it found.
  93. //! @param containerEntityId The given container entity id of the owning instance.
  94. //! @param nestedContainerEntityName Container entity name for the instance alias to find.
  95. //! @return Nested instance alias for the given container entity name. Returns "" if not found.
  96. InstanceAlias FindNestedInstanceAliasInInstance(AZ::EntityId containerEntityId, const AZStd::string& nestedContainerEntityName);
  97. //! Rename an entity.
  98. //! Note: Renaming a container entity would be an override edit on the focused prefab.
  99. //! @param entityId Entity id for entity to be renamed.
  100. //! @param newName New entity name.
  101. void RenameEntity(AZ::EntityId entityId, const AZStd::string& newName);
  102. //! Helper functions for validation.
  103. //! @{
  104. void ValidateEntityUnderInstance(AZ::EntityId containerEntityId, const EntityAlias& entityAlias, const AZStd::string& entityName);
  105. void ValidateEntityNotUnderInstance(AZ::EntityId containerEntityId, const EntityAlias& entityAlias);
  106. void ValidateNestedInstanceUnderInstance(AZ::EntityId containerEntityId, const InstanceAlias& nestedInstanceAlias);
  107. void ValidateNestedInstanceNotUnderInstance(AZ::EntityId containerEntityId, const InstanceAlias& nestedInstanceAlias);
  108. // Validates that all entities within a prefab instance are in 'Active' state.
  109. void ValidateInstanceEntitiesActive(Instance& instance);
  110. //! @}
  111. // Kicks off any updates scheduled for the next tick
  112. virtual void ProcessDeferredUpdates();
  113. // Performs an undo operation and ensures the tick-scheduled updates happen
  114. void Undo();
  115. // Performs a redo operation and ensures the tick-scheduled updates happen
  116. void Redo();
  117. //! Adds required editor components to entity.
  118. //! This function does similar work as CreateEditorRepresentation does. But we use this one to manually add
  119. //! editor components when we create a new entity via PrefabTestFixture::CreateEntity() or aznew operator.
  120. //! Note: This will add a transform component, so you should not add the transform by yourself before
  121. //! and after calling this for the same entity.
  122. //! @param entity The entity that components will be added to.
  123. void AddRequiredEditorComponents(const AzToolsFramework::EntityIdList& entityIds);
  124. //! EditorRequestBus.
  125. //! CreateEditorRepresentation is implemented in this test fixture. Then the required editor components
  126. //! will be added during entity and prefab creation, eg transform component, child entity sort component.
  127. //! @{
  128. void CreateEditorRepresentation(AZ::Entity* entity) override;
  129. void BrowseForAssets([[maybe_unused]] AzToolsFramework::AssetBrowser::AssetSelectionModel& selection) override
  130. {
  131. }
  132. //! @}
  133. // Prefab interfaces
  134. PrefabSystemComponent* m_prefabSystemComponent = nullptr;
  135. PrefabLoaderInterface* m_prefabLoaderInterface = nullptr;
  136. PrefabPublicInterface* m_prefabPublicInterface = nullptr;
  137. InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
  138. InstanceUpdateExecutorInterface* m_instanceUpdateExecutorInterface = nullptr;
  139. InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
  140. AzToolsFramework::PrefabEditorEntityOwnershipInterface* m_prefabEditorEntityOwnershipInterface = nullptr;
  141. // SettingsRegistryInterface
  142. AZ::SettingsRegistryInterface* m_settingsRegistryInterface = nullptr;
  143. // Undo Stack
  144. AzToolsFramework::UndoSystem::UndoStack* m_undoStack = nullptr;
  145. };
  146. } // namespace UnitTest