merging latest origin

This commit is contained in:
karlberg
2021-05-03 21:27:27 -07:00
4864 changed files with 37281 additions and 612775 deletions
+1
View File
@@ -42,6 +42,7 @@ namespace UnitTest
MOCK_METHOD3(InstantiateDynamicSlice, AzFramework::SliceInstantiationTicket(const AZ::Data::Asset<AZ::Data::AssetData>&, const AZ::Transform&, const AZ::IdUtils::Remapper<AZ::EntityId>::IdMapper&));
MOCK_METHOD0(GetGameEntityContextId, AzFramework::EntityContextId());
MOCK_METHOD0(GetGameEntityContextInstance, AzFramework::EntityContext*());
MOCK_METHOD1(CreateGameEntity, AZ::Entity*(const char*));
MOCK_METHOD1(AddGameEntity, void (AZ::Entity*));
MOCK_METHOD1(DestroyGameEntity, void (const AZ::EntityId&));
+90 -118
View File
@@ -130,6 +130,8 @@ namespace SceneUnitTest
m_systemEntity->CreateComponent<AZ::JobManagerComponent>();
m_systemEntity->CreateComponent<AZ::StreamerComponent>();
m_systemEntity->Activate();
m_sceneSystem = AzFramework::SceneSystemInterface::Get();
}
void TearDown() override
@@ -146,167 +148,119 @@ namespace SceneUnitTest
AZ::IO::FileIOBase* m_prevFileIO;
AZ::ComponentApplication m_app;
AZ::Entity* m_systemEntity = nullptr;
AzFramework::ISceneSystem* m_sceneSystem = nullptr;
};
TEST_F(SceneTest, CreateScene)
{
Scene* scene = nullptr;
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
{
// A scene should be able to be created with a given name.
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, "TestScene");
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene("TestScene");
EXPECT_TRUE(createSceneOutcome.IsSuccess()) << "Unable to create a scene.";
// The scene pointer returned should be valid
scene = createSceneOutcome.GetValue();
EXPECT_TRUE(scene != nullptr) << "Scene creation reported success, but no scene actually was actually returned.";
AZStd::shared_ptr<Scene> scene = createSceneOutcome.TakeValue();
EXPECT_NE(scene, nullptr) << "Scene creation reported success, but no scene actually was actually returned.";
// Attempting to create another scene with the same name should fail.
createSceneOutcome = AZ::Failure<AZStd::string>("");
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, "TestScene");
createSceneOutcome = m_sceneSystem->CreateScene("TestScene");
EXPECT_TRUE(!createSceneOutcome.IsSuccess()) << "Should not be able to create two scenes with the same name.";
}
TEST_F(SceneTest, GetScene)
{
Scene* createdScene = nullptr;
Scene* retrievedScene = nullptr;
Scene* nullScene = nullptr;
const static AZStd::string_view s_sceneName = "TestScene";
constexpr AZStd::string_view sceneName = "TestScene";
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, s_sceneName);
createdScene = createSceneOutcome.GetValue();
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene(sceneName);
AZStd::shared_ptr<Scene> createdScene = createSceneOutcome.TakeValue();
// Should be able to get a scene by name, and it should match the scene that was created.
AzFramework::SceneSystemRequestBus::BroadcastResult(retrievedScene, &AzFramework::SceneSystemRequestBus::Events::GetScene, s_sceneName);
EXPECT_TRUE(retrievedScene != nullptr) << "Attempting to get scene by name resulted in nullptr.";
EXPECT_TRUE(retrievedScene == createdScene) << "Retrieved scene does not match created scene.";
AZStd::shared_ptr<Scene> retrievedScene = m_sceneSystem->GetScene(sceneName);
EXPECT_NE(retrievedScene, nullptr) << "Attempting to get scene by name resulted in nullptr.";
EXPECT_EQ(retrievedScene, createdScene) << "Retrieved scene does not match created scene.";
// An invalid name should return a null scene.
AzFramework::SceneSystemRequestBus::BroadcastResult(nullScene, &AzFramework::SceneSystemRequestBus::Events::GetScene, "non-existant scene");
EXPECT_TRUE(nullScene == nullptr) << "Should not be able to retrieve a scene that wasn't created.";
AZStd::shared_ptr<Scene> nullScene = m_sceneSystem->GetScene("non-existant scene");
EXPECT_EQ(nullScene, nullptr) << "Should not be able to retrieve a scene that wasn't created.";
}
TEST_F(SceneTest, RemoveScene)
{
Scene* createdScene = nullptr;
const static AZStd::string_view s_sceneName = "TestScene";
constexpr AZStd::string_view sceneName = "TestScene";
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, s_sceneName);
createdScene = createSceneOutcome.GetValue();
bool success = false;
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::RemoveScene, s_sceneName);
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene(sceneName);
bool success = m_sceneSystem->RemoveScene(sceneName);
EXPECT_TRUE(success) << "Failed to remove the scene that was just created.";
success = true;
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::RemoveScene, "non-existant scene");
success = m_sceneSystem->RemoveScene("non-existant scene");
EXPECT_FALSE(success) << "Remove scene returned success for a non-existant scene.";
}
TEST_F(SceneTest, GetAllScenes)
TEST_F(SceneTest, IterateActiveScenes)
{
constexpr size_t NumScenes = 5;
Scene* scenes[NumScenes] = { nullptr };
AZStd::shared_ptr<Scene> scenes[NumScenes] = {nullptr};
for (size_t i = 0; i < NumScenes; ++i)
{
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
AZStd::string sceneName = AZStd::string::format("scene %zu", i);
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, sceneName);
scenes[i] = createSceneOutcome.GetValue();
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene(sceneName);
scenes[i] = createSceneOutcome.TakeValue();
}
AZStd::vector<Scene*> retrievedScenes;
AzFramework::SceneSystemRequestBus::BroadcastResult(retrievedScenes, &AzFramework::SceneSystemRequestBus::Events::GetAllScenes);
EXPECT_EQ(NumScenes, retrievedScenes.size()) << "GetAllScenes() returned a different number of scenes than those created.";
for (size_t i = 0; i < NumScenes; ++i)
{
EXPECT_EQ(scenes[i], retrievedScenes.at(i)) << "GetAllScenes() returned scenes in a different order than they were created.";
}
size_t index = 0;
m_sceneSystem->IterateActiveScenes([&index, &scenes](const AZStd::shared_ptr<Scene>& scene)
{
EXPECT_EQ(scenes[index++], scene);
return true;
});
}
TEST_F(SceneTest, EntityContextSceneMapping)
TEST_F(SceneTest, IterateZombieScenes)
{
AZStd::unique_ptr<SliceEntityOwnershipService> m_entityOwnershipService =
AZStd::make_unique<AzFramework::SliceEntityOwnershipService>(AZ::Uuid::CreateNull(), m_app.GetSerializeContext());
// Create the entity context, entity, and component
EntityContext* testEntityContext = new EntityContext(AZ::Uuid::CreateRandom(), AZStd::move(m_entityOwnershipService));
testEntityContext->InitContext();
EntityContextId testEntityContextId = testEntityContext->GetContextId();
AZ::Entity* testEntity = testEntityContext->CreateEntity("TestEntity");
TestComponent* testComponent = testEntity->CreateComponent<TestComponent>();
constexpr size_t NumScenes = 5;
// Try to activate an entity and get the scene before a scene has been set. This should fail.
TestComponentConfig failConfig;
failConfig.m_activateFunction = [](TestComponent* component)
AZStd::shared_ptr<Scene> scenes[NumScenes] = {nullptr};
// Create zombies.
for (size_t i = 0; i < NumScenes; ++i)
{
(void)component;
Scene* scene = nullptr;
EntityContextId entityContextId = EntityContextId::CreateNull();
AZStd::string sceneName = AZStd::string::format("scene %zu", i);
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene(sceneName);
scenes[i] = createSceneOutcome.TakeValue();
m_sceneSystem->RemoveScene(sceneName);
}
AzFramework::EntityIdContextQueryBus::BroadcastResult(entityContextId, &AzFramework::EntityIdContextQueryBus::Events::GetOwningContextId);
// Check to make sure there are no more active scenes.
size_t index = 0;
m_sceneSystem->IterateActiveScenes([&index, &scenes](const AZStd::shared_ptr<Scene>&)
{
index++;
return true;
});
EXPECT_EQ(0, index);
// A null scene should be returned since a scene has not been set for this entity context.
AzFramework::SceneSystemRequestBus::BroadcastResult(scene, &AzFramework::SceneSystemRequestBus::Events::GetSceneFromEntityContextId, entityContextId);
EXPECT_TRUE(scene == nullptr) << "Found a scene when one shouldn't exist.";
};
testComponent->SetConfiguration(failConfig);
testComponent->Activate();
testComponent->Deactivate();
// Check that the scenes are still returned as zombies.
index = 0;
m_sceneSystem->IterateZombieScenes([&index, &scenes](Scene& scene)
{
EXPECT_EQ(scenes[index++].get(), &scene);
return true;
});
// Create the scene
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, "TestScene");
Scene* scene = createSceneOutcome.GetValue();
// Map the Entity context to the scene
bool success = false;
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::SetSceneForEntityContextId, testEntityContextId, scene);
EXPECT_TRUE(success) << "Unable to associate an entity context with a scene.";
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::SetSceneForEntityContextId, testEntityContextId, scene);
EXPECT_FALSE(success) << "Attempting to map an entity context to a scene that's already mapped, this should not work.";
// Now it should be possible to get the scene from the entity context within an Entity's Activate()
TestComponentConfig successConfig;
successConfig.m_activateFunction = [](TestComponent* component)
// Check that all scenes are removed when there are no more handles.
for (size_t i = 0; i < NumScenes; ++i)
{
(void)component;
Scene* scene = nullptr;
EntityContextId entityContextId = EntityContextId::CreateNull();
AzFramework::EntityIdContextQueryBus::BroadcastResult(entityContextId, &AzFramework::EntityIdContextQueryBus::Events::GetOwningContextId);
// A scene should be returned since a scene has been set for this entity context.
AzFramework::SceneSystemRequestBus::BroadcastResult(scene, &AzFramework::SceneSystemRequestBus::Events::GetSceneFromEntityContextId, entityContextId);
EXPECT_TRUE(scene != nullptr) << "Could not find a scene for the entity context.";
};
testComponent->SetConfiguration(successConfig);
testComponent->Activate();
testComponent->Deactivate();
// Now remove the entity context / scene association and make sure things fail again.
success = false;
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::RemoveSceneForEntityContextId, testEntityContextId, nullptr);
EXPECT_FALSE(success) << "Should not be able to remove an entity context from a scene it's not associated with.";
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::RemoveSceneForEntityContextId, testEntityContextId, scene);
EXPECT_TRUE(success) << "Was not able to remove an entity context from a scene it's associated with.";
testComponent->SetConfiguration(failConfig);
testComponent->Activate();
testComponent->Deactivate();
delete testEntityContext; // This should also clean up owned entities / components.
scenes[i].reset();
}
index = 0;
m_sceneSystem->IterateZombieScenes([&index, &scenes](Scene&) {
index++;
return true;
});
EXPECT_EQ(0, index);
}
// Test classes for use in the SceneSystem test. These can't be defined in the test itself due to some functions created by AZ_RTTI not having a body which breaks VS2015.
@@ -324,30 +278,48 @@ namespace SceneUnitTest
TEST_F(SceneTest, SceneSystem)
{
// Create the scene
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, "TestScene");
AzFramework::Scene* scene = createSceneOutcome.GetValue();
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene("TestScene");
EXPECT_TRUE(createSceneOutcome.IsSuccess());
AZStd::shared_ptr<Scene> scene = createSceneOutcome.TakeValue();
// Set a class on the Scene
Foo1* foo1a = new Foo1();
EXPECT_TRUE(scene->SetSubsystem(foo1a));
// Get that class back from the Scene
EXPECT_EQ(foo1a, scene->GetSubsystem<Foo1>());
EXPECT_EQ(foo1a, *scene->FindSubsystem<Foo1*>());
// Try to set the same class type twice, this should fail.
Foo1* foo1b = new Foo1();
EXPECT_FALSE(scene->SetSubsystem(foo1b));
delete foo1b;
// Add a child scene
createSceneOutcome = m_sceneSystem->CreateSceneWithParent("ChildScene", scene);
EXPECT_TRUE(createSceneOutcome.IsSuccess());
AZStd::shared_ptr<Scene> childScene = createSceneOutcome.TakeValue();
// Get class back from parent scene.
EXPECT_EQ(foo1a, *childScene->FindSubsystem<Foo1*>());
// Find overloaded version of class on child scene.
Foo1* foo1c = new Foo1();
EXPECT_TRUE(childScene->SetSubsystem(foo1c));
EXPECT_EQ(foo1c, *childScene->FindSubsystem<Foo1*>());
// Unset system on child scene, using alternative unset function.
EXPECT_TRUE(childScene->UnsetSubsystem(foo1c));
delete foo1c;
// Try to un-set a class that was never set, this should fail.
EXPECT_FALSE(scene->UnsetSubsystem<Foo2>());
// Unset the class that was previously set
EXPECT_TRUE(scene->UnsetSubsystem<Foo1>());
delete foo1a;
// Make sure that the previsouly set class was really removed.
EXPECT_EQ(nullptr, scene->GetSubsystem<Foo1>());
// Make sure that the previously set class was really removed.
EXPECT_EQ(nullptr, scene->FindSubsystem<Foo1*>());
}
} // UnitTest