You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
12 KiB
C++
238 lines
12 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
#include <AzCore/Component/EntityId.h>
|
|
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
|
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
|
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
|
|
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
|
|
#include <Prefab/PrefabTestFixture.h>
|
|
|
|
namespace UnitTest
|
|
{
|
|
class PrefabFocusTests
|
|
: public PrefabTestFixture
|
|
{
|
|
protected:
|
|
void GenerateTestHierarchy()
|
|
{
|
|
/*
|
|
* City (Prefab Container)
|
|
* |_ City
|
|
* |_ Street (Prefab Container)
|
|
* |_ Car (Prefab Container)
|
|
* | |_ Passenger
|
|
* |_ SportsCar (Prefab Container)
|
|
* |_ Passenger
|
|
*/
|
|
|
|
// Create loose entities
|
|
m_entityMap[Passenger1EntityName] = CreateEntity(Passenger1EntityName);
|
|
m_entityMap[Passenger2EntityName] = CreateEntity(Passenger2EntityName);
|
|
m_entityMap[CityEntityName] = CreateEntity(CityEntityName);
|
|
|
|
// Call HandleEntitiesAdded to the loose entities to register them with the Prefab EOS
|
|
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
|
|
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded,
|
|
AzToolsFramework::EntityList{ m_entityMap[Passenger1EntityName], m_entityMap[Passenger2EntityName], m_entityMap[CityEntityName] });
|
|
|
|
// Initialize Prefab EOS Interface
|
|
AzToolsFramework::PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
|
AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
|
|
ASSERT_TRUE(prefabEditorEntityOwnershipInterface);
|
|
|
|
// Create a car prefab from the passenger1 entity. The container entity will be created as part of the process.
|
|
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> carInstance =
|
|
m_prefabSystemComponent->CreatePrefab({ m_entityMap[Passenger1EntityName] }, {}, "test/car");
|
|
ASSERT_TRUE(carInstance);
|
|
m_instanceMap[CarEntityName] = carInstance.get();
|
|
|
|
// Create a sportscar prefab from the passenger2 entity. The container entity will be created as part of the process.
|
|
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> sportsCarInstance =
|
|
m_prefabSystemComponent->CreatePrefab({ m_entityMap[Passenger2EntityName] }, {}, "test/sportsCar");
|
|
ASSERT_TRUE(sportsCarInstance);
|
|
m_instanceMap[SportsCarEntityName] = sportsCarInstance.get();
|
|
|
|
// Create a street prefab that nests the car and sportscar instances created above. The container entity will be created as part of the process.
|
|
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> streetInstance =
|
|
m_prefabSystemComponent->CreatePrefab({}, MakeInstanceList(AZStd::move(carInstance), AZStd::move(sportsCarInstance)), "test/street");
|
|
ASSERT_TRUE(streetInstance);
|
|
m_instanceMap[StreetEntityName] = streetInstance.get();
|
|
|
|
// Use the Prefab EOS root instance as the City instance. This will ensure functions that go through the EOS work in these tests too.
|
|
m_rootInstance = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
|
|
ASSERT_TRUE(m_rootInstance.has_value());
|
|
|
|
m_rootInstance->get().AddEntity(*m_entityMap[CityEntityName]);
|
|
m_rootInstance->get().AddInstance(AZStd::move(streetInstance));
|
|
|
|
m_instanceMap[CityEntityName] = &m_rootInstance->get();
|
|
}
|
|
|
|
void SetUpEditorFixtureImpl() override
|
|
{
|
|
PrefabTestFixture::SetUpEditorFixtureImpl();
|
|
|
|
m_prefabFocusInterface = AZ::Interface<PrefabFocusInterface>::Get();
|
|
ASSERT_TRUE(m_prefabFocusInterface != nullptr);
|
|
|
|
m_prefabFocusPublicInterface = AZ::Interface<PrefabFocusPublicInterface>::Get();
|
|
ASSERT_TRUE(m_prefabFocusPublicInterface != nullptr);
|
|
|
|
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(
|
|
m_editorEntityContextId, &AzToolsFramework::EditorEntityContextRequestBus::Events::GetEditorEntityContextId);
|
|
|
|
GenerateTestHierarchy();
|
|
}
|
|
|
|
void TearDownEditorFixtureImpl() override
|
|
{
|
|
m_rootInstance->get().Reset();
|
|
|
|
PrefabTestFixture::TearDownEditorFixtureImpl();
|
|
}
|
|
|
|
AZStd::unordered_map<AZStd::string, AZ::Entity*> m_entityMap;
|
|
AZStd::unordered_map<AZStd::string, Instance*> m_instanceMap;
|
|
|
|
InstanceOptionalReference m_rootInstance;
|
|
|
|
PrefabFocusInterface* m_prefabFocusInterface = nullptr;
|
|
PrefabFocusPublicInterface* m_prefabFocusPublicInterface = nullptr;
|
|
AzFramework::EntityContextId m_editorEntityContextId = AzFramework::EntityContextId::CreateNull();
|
|
|
|
inline static const char* CityEntityName = "City";
|
|
inline static const char* StreetEntityName = "Street";
|
|
inline static const char* CarEntityName = "Car";
|
|
inline static const char* SportsCarEntityName = "SportsCar";
|
|
inline static const char* Passenger1EntityName = "Passenger1";
|
|
inline static const char* Passenger2EntityName = "Passenger2";
|
|
};
|
|
|
|
// Test was disabled because the implementation of GetFocusedPrefabInstance now relies on the Prefab EOS,
|
|
// which is not used by our test environment. This can be restored once Instance handles are implemented.
|
|
TEST_F(PrefabFocusTests, DISABLED_PrefabFocus_FocusOnOwningPrefab_RootContainer)
|
|
{
|
|
// Verify FocusOnOwningPrefab works when passing the container entity of the root prefab.
|
|
{
|
|
m_prefabFocusPublicInterface->FocusOnOwningPrefab(m_instanceMap[CityEntityName]->GetContainerEntityId());
|
|
EXPECT_EQ(
|
|
m_prefabFocusInterface->GetFocusedPrefabTemplateId(m_editorEntityContextId),
|
|
m_instanceMap[CityEntityName]->GetTemplateId());
|
|
|
|
auto instance = m_prefabFocusInterface->GetFocusedPrefabInstance(m_editorEntityContextId);
|
|
EXPECT_TRUE(instance.has_value());
|
|
EXPECT_EQ(&instance->get(), m_instanceMap[CityEntityName]);
|
|
}
|
|
}
|
|
|
|
// Test was disabled because the implementation of GetFocusedPrefabInstance now relies on the Prefab EOS,
|
|
// which is not used by our test environment. This can be restored once Instance handles are implemented.
|
|
TEST_F(PrefabFocusTests, DISABLED_PrefabFocus_FocusOnOwningPrefab_RootEntity)
|
|
{
|
|
// Verify FocusOnOwningPrefab works when passing a nested entity of the root prefab.
|
|
{
|
|
m_prefabFocusPublicInterface->FocusOnOwningPrefab(m_entityMap[CityEntityName]->GetId());
|
|
EXPECT_EQ(
|
|
m_prefabFocusInterface->GetFocusedPrefabTemplateId(m_editorEntityContextId),
|
|
m_instanceMap[CityEntityName]->GetTemplateId());
|
|
|
|
auto instance = m_prefabFocusInterface->GetFocusedPrefabInstance(m_editorEntityContextId);
|
|
EXPECT_TRUE(instance.has_value());
|
|
EXPECT_EQ(&instance->get(), m_instanceMap[CityEntityName]);
|
|
}
|
|
}
|
|
|
|
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_NestedContainer)
|
|
{
|
|
// Verify FocusOnOwningPrefab works when passing the container entity of a nested prefab.
|
|
{
|
|
m_prefabFocusPublicInterface->FocusOnOwningPrefab(m_instanceMap[CarEntityName]->GetContainerEntityId());
|
|
EXPECT_EQ(
|
|
m_prefabFocusInterface->GetFocusedPrefabTemplateId(m_editorEntityContextId), m_instanceMap[CarEntityName]->GetTemplateId());
|
|
|
|
auto instance = m_prefabFocusInterface->GetFocusedPrefabInstance(m_editorEntityContextId);
|
|
EXPECT_TRUE(instance.has_value());
|
|
EXPECT_EQ(&instance->get(), m_instanceMap[CarEntityName]);
|
|
}
|
|
}
|
|
|
|
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_NestedEntity)
|
|
{
|
|
// Verify FocusOnOwningPrefab works when passing a nested entity of the a nested prefab.
|
|
{
|
|
m_prefabFocusPublicInterface->FocusOnOwningPrefab(m_entityMap[Passenger1EntityName]->GetId());
|
|
EXPECT_EQ(
|
|
m_prefabFocusInterface->GetFocusedPrefabTemplateId(m_editorEntityContextId), m_instanceMap[CarEntityName]->GetTemplateId());
|
|
|
|
auto instance = m_prefabFocusInterface->GetFocusedPrefabInstance(m_editorEntityContextId);
|
|
EXPECT_TRUE(instance.has_value());
|
|
EXPECT_EQ(&instance->get(), m_instanceMap[CarEntityName]);
|
|
}
|
|
}
|
|
|
|
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_Clear)
|
|
{
|
|
// Verify FocusOnOwningPrefab points to the root prefab when the focus is cleared.
|
|
{
|
|
AzToolsFramework::PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
|
AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
|
|
AzToolsFramework::Prefab::InstanceOptionalReference rootPrefabInstance =
|
|
prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
|
|
EXPECT_TRUE(rootPrefabInstance.has_value());
|
|
|
|
m_prefabFocusPublicInterface->FocusOnOwningPrefab(AZ::EntityId());
|
|
EXPECT_EQ(
|
|
m_prefabFocusInterface->GetFocusedPrefabTemplateId(m_editorEntityContextId), rootPrefabInstance->get().GetTemplateId());
|
|
|
|
auto instance = m_prefabFocusInterface->GetFocusedPrefabInstance(m_editorEntityContextId);
|
|
EXPECT_TRUE(instance.has_value());
|
|
EXPECT_EQ(&instance->get(), &rootPrefabInstance->get());
|
|
}
|
|
}
|
|
|
|
TEST_F(PrefabFocusTests, PrefabFocus_IsOwningPrefabBeingFocused_Content)
|
|
{
|
|
// Verify IsOwningPrefabBeingFocused returns true for all entities in a focused prefab (container/nested)
|
|
{
|
|
m_prefabFocusPublicInterface->FocusOnOwningPrefab(m_instanceMap[CityEntityName]->GetContainerEntityId());
|
|
|
|
EXPECT_TRUE(m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(m_instanceMap[CityEntityName]->GetContainerEntityId()));
|
|
EXPECT_TRUE(m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(m_entityMap[CityEntityName]->GetId()));
|
|
}
|
|
}
|
|
|
|
TEST_F(PrefabFocusTests, PrefabFocus_IsOwningPrefabBeingFocused_AncestorsDescendants)
|
|
{
|
|
// Verify IsOwningPrefabBeingFocused returns false for all entities not in a focused prefab (ancestors/descendants)
|
|
{
|
|
m_prefabFocusPublicInterface->FocusOnOwningPrefab(m_instanceMap[StreetEntityName]->GetContainerEntityId());
|
|
|
|
EXPECT_TRUE(m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(m_instanceMap[StreetEntityName]->GetContainerEntityId()));
|
|
EXPECT_FALSE(m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(m_instanceMap[CityEntityName]->GetContainerEntityId()));
|
|
EXPECT_FALSE(m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(m_entityMap[CityEntityName]->GetId()));
|
|
EXPECT_FALSE(m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(m_instanceMap[CarEntityName]->GetContainerEntityId()));
|
|
EXPECT_FALSE(m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(m_entityMap[Passenger1EntityName]->GetId()));
|
|
}
|
|
}
|
|
|
|
TEST_F(PrefabFocusTests, PrefabFocus_IsOwningPrefabBeingFocused_Siblings)
|
|
{
|
|
// Verify IsOwningPrefabBeingFocused returns false for all entities not in a focused prefab (siblings)
|
|
{
|
|
m_prefabFocusPublicInterface->FocusOnOwningPrefab(m_instanceMap[SportsCarEntityName]->GetContainerEntityId());
|
|
|
|
EXPECT_TRUE(m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(m_instanceMap[SportsCarEntityName]->GetContainerEntityId()));
|
|
EXPECT_TRUE(m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(m_entityMap[Passenger2EntityName]->GetId()));
|
|
EXPECT_FALSE(m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(m_instanceMap[CarEntityName]->GetContainerEntityId()));
|
|
EXPECT_FALSE(m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(m_entityMap[Passenger1EntityName]->GetId()));
|
|
}
|
|
}
|
|
|
|
}
|