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.
440 lines
21 KiB
C++
440 lines
21 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 <Atom/RPI.Public/Base.h>
|
|
#include <Atom/RPI.Public/FeatureProcessor.h>
|
|
#include <Atom/RPI.Public/FeatureProcessorFactory.h>
|
|
#include <Atom/RPI.Public/Pass/RasterPass.h>
|
|
#include <Atom/RPI.Public/RenderPipeline.h>
|
|
#include <Atom/RPI.Public/Scene.h>
|
|
#include <Atom/RPI.Public/View.h>
|
|
|
|
#include <Atom/RPI.Reflect/Pass/RasterPassData.h>
|
|
|
|
#include <AzFramework/Visibility/OctreeSystemComponent.h>
|
|
|
|
#include <AzTest/AzTest.h>
|
|
|
|
#include <Common/RPITestFixture.h>
|
|
#include <Common/SerializeTester.h>
|
|
#include <Common/ErrorMessageFinder.h>
|
|
#include <Common/TestFeatureProcessors.h>
|
|
|
|
namespace UnitTest
|
|
{
|
|
using namespace AZ;
|
|
using namespace AZ::RPI;
|
|
|
|
class SceneTests
|
|
: public RPITestFixture
|
|
{
|
|
protected:
|
|
AzFramework::OctreeSystemComponent* m_octreeSystemComponent;
|
|
|
|
void SetUp() override
|
|
{
|
|
RPITestFixture::SetUp();
|
|
|
|
m_octreeSystemComponent = new AzFramework::OctreeSystemComponent;
|
|
|
|
TestFeatureProcessor1::Reflect(GetSerializeContext());
|
|
TestFeatureProcessor2::Reflect(GetSerializeContext());
|
|
TestFeatureProcessorImplementation::Reflect(GetSerializeContext());
|
|
TestFeatureProcessorImplementation2::Reflect(GetSerializeContext());
|
|
|
|
AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessor<TestFeatureProcessor1>();
|
|
AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessor<TestFeatureProcessor2>();
|
|
AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessorWithInterface<TestFeatureProcessorImplementation, TestFeatureProcessorInterface>();
|
|
AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessorWithInterface<TestFeatureProcessorImplementation2, TestFeatureProcessorInterface>();
|
|
}
|
|
|
|
void TearDown() override
|
|
{
|
|
AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor<TestFeatureProcessor1>();
|
|
AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor<TestFeatureProcessor2>();
|
|
AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor<TestFeatureProcessorImplementation>();
|
|
AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor<TestFeatureProcessorImplementation2>();
|
|
|
|
delete m_octreeSystemComponent;
|
|
|
|
RPITestFixture::TearDown();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Unit test to test RPI::Scene's feature processor management functions
|
|
*/
|
|
TEST_F(SceneTests, FeatureProcessorManagement)
|
|
{
|
|
// Create scene with two test feature processors
|
|
SceneDescriptor sceneDesc;
|
|
sceneDesc.m_featureProcessorNames.push_back(AZStd::string(TestFeatureProcessor1::RTTI_TypeName()));
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor(FeatureProcessorId{ TestFeatureProcessor1::RTTI_TypeName() }) != nullptr);
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor(FeatureProcessorId{ TestFeatureProcessor2::RTTI_TypeName() }) == nullptr);
|
|
|
|
testScene->DisableAllFeatureProcessors();
|
|
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor(FeatureProcessorId{ TestFeatureProcessor1::RTTI_TypeName() }) == nullptr);
|
|
|
|
// Enable feature processors
|
|
FeatureProcessor* testFeature1 = testScene->EnableFeatureProcessor(FeatureProcessorId{ TestFeatureProcessor1::RTTI_TypeName() });
|
|
EXPECT_TRUE(testFeature1 != nullptr);
|
|
|
|
TestFeatureProcessor2* testFeature2 = testScene->EnableFeatureProcessor<TestFeatureProcessor2>();
|
|
EXPECT_TRUE(testFeature2 != nullptr);
|
|
|
|
testScene->DisableFeatureProcessor< TestFeatureProcessor1>();
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor(FeatureProcessorId{ TestFeatureProcessor1::RTTI_TypeName() }) == nullptr);
|
|
|
|
testScene->DisableFeatureProcessor(FeatureProcessorId{ testFeature2->RTTI_GetTypeName() });
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor< TestFeatureProcessor2>() == nullptr);
|
|
}
|
|
|
|
/**
|
|
* Unit test to test RPI::Scene's render pipeline management functions
|
|
*/
|
|
TEST_F(SceneTests, RenderPipelineManagement)
|
|
{
|
|
RenderPipelineId pipelineId1 = RenderPipelineId("pipeline1");
|
|
RenderPipelineId pipelineId2 = RenderPipelineId("pipeline2");
|
|
|
|
RenderPipelineDescriptor pipelineDesc;
|
|
pipelineDesc.m_name = pipelineId1.GetCStr();
|
|
RenderPipelinePtr pipeline1 = RenderPipeline::CreateRenderPipeline(pipelineDesc);
|
|
RenderPipelinePtr pipeline2 = RenderPipeline::CreateRenderPipeline(pipelineDesc);
|
|
|
|
SceneDescriptor sceneDesc;
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
|
|
testScene->AddRenderPipeline(pipeline1);
|
|
EXPECT_TRUE(testScene->GetRenderPipeline(pipelineId1) == pipeline1);
|
|
EXPECT_TRUE(testScene->GetRenderPipeline(pipelineId2) == nullptr);
|
|
|
|
// Asset false with pipeline have same name. And the pipeline won't be added
|
|
AZ_TEST_START_ASSERTTEST;
|
|
testScene->AddRenderPipeline(pipeline2);
|
|
AZ_TEST_STOP_ASSERTTEST(1);
|
|
EXPECT_TRUE(testScene->GetRenderPipeline(pipelineId2) == nullptr);
|
|
|
|
pipelineDesc.m_name = pipelineId2.GetCStr();
|
|
pipeline2 = RenderPipeline::CreateRenderPipeline(pipelineDesc);
|
|
testScene->AddRenderPipeline(pipeline2);
|
|
EXPECT_TRUE(testScene->GetRenderPipeline(pipelineId2) != nullptr);
|
|
|
|
EXPECT_TRUE(pipeline2->GetId() == pipelineId2);
|
|
EXPECT_TRUE(testScene->GetRenderPipeline(pipelineId2) == pipeline2);
|
|
|
|
// create another pipeline with same name as pipeline2
|
|
RenderPipelinePtr pipeline3 = RenderPipeline::CreateRenderPipeline(pipelineDesc);
|
|
|
|
AZ_TEST_START_ASSERTTEST;
|
|
pipeline3->RemoveFromScene();
|
|
AZ_TEST_STOP_ASSERTTEST(1);
|
|
EXPECT_TRUE(testScene->GetRenderPipeline(pipelineId2) == pipeline2);
|
|
|
|
pipeline2->RemoveFromScene();
|
|
EXPECT_TRUE(testScene->GetRenderPipeline(pipelineId2) == nullptr);
|
|
}
|
|
|
|
TEST_F(SceneTests, SceneNotificationTest)
|
|
{
|
|
// Create scene with feature processor which enables scene notification handler
|
|
SceneDescriptor sceneDesc;
|
|
sceneDesc.m_featureProcessorNames.push_back(AZStd::string(TestFeatureProcessor1::RTTI_TypeName()));
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
testScene->Activate();
|
|
auto feature = testScene->GetFeatureProcessor< TestFeatureProcessor1>();
|
|
|
|
RenderPipelineId pipelineId1 = RenderPipelineId("pipeline1");
|
|
RenderPipelineId pipelineId2 = RenderPipelineId("pipeline2");
|
|
|
|
RenderPipelineDescriptor pipelineDesc;
|
|
pipelineDesc.m_name = pipelineId1.GetCStr();
|
|
RenderPipelinePtr pipeline1 = RenderPipeline::CreateRenderPipeline(pipelineDesc);
|
|
pipelineDesc.m_name = pipelineId2.GetCStr();
|
|
RenderPipelinePtr pipeline2 = RenderPipeline::CreateRenderPipeline(pipelineDesc);
|
|
|
|
// Add one render pipeline
|
|
testScene->AddRenderPipeline(pipeline1);
|
|
EXPECT_TRUE(feature->m_pipelineCount == 1);
|
|
EXPECT_TRUE(pipeline1.get() == feature->m_lastPipeline);
|
|
|
|
// Add another render pipeline
|
|
testScene->AddRenderPipeline(pipeline2);
|
|
EXPECT_TRUE(pipeline2.get() == feature->m_lastPipeline);
|
|
EXPECT_TRUE(feature->m_pipelineCount == 2);
|
|
|
|
// Remove the first render pipeline which was added
|
|
testScene->RemoveRenderPipeline(pipelineId1);
|
|
EXPECT_TRUE(feature->m_pipelineCount == 1);
|
|
EXPECT_TRUE(pipeline1.get() == feature->m_lastPipeline);
|
|
|
|
// Create a raster pass with viewTag "mainCamera"
|
|
const RPI::PipelineViewTag viewTag{ "mainCamera" };
|
|
PassDescriptor passDesc;
|
|
AZStd::shared_ptr<PassTemplate> passTemplate = AZStd::make_shared<PassTemplate>();
|
|
AZStd::shared_ptr<RasterPassData> passData = AZStd::make_shared<RasterPassData>();
|
|
passData->m_drawListTag = "forward";
|
|
passData->m_pipelineViewTag = viewTag.GetCStr();
|
|
passTemplate->m_passData = passData;
|
|
passDesc.m_passName = "raster";
|
|
passDesc.m_passTemplate = passTemplate;
|
|
Ptr<RasterPass> newPass = RasterPass::Create(passDesc);
|
|
|
|
// Add new pass to render pipeline which should trigger render pipeline pass modify notification
|
|
pipeline2->GetRootPass()->AddChild(newPass);
|
|
// This function is called in every RPISystem render tick. We call it manually here to trigger the pass change notification
|
|
pipeline2->OnPassModified();
|
|
EXPECT_TRUE(feature->m_pipelineChangedCount == 1);
|
|
EXPECT_TRUE(pipeline2.get() == feature->m_lastPipeline);
|
|
|
|
ViewPtr view = View::CreateView(AZ::Name("TestView"), RPI::View::UsageCamera);
|
|
pipeline2->SetPersistentView(viewTag, view);
|
|
EXPECT_TRUE(feature->m_viewSetCount == 1);
|
|
pipeline2->SetPersistentView(viewTag, nullptr);
|
|
EXPECT_TRUE(feature->m_viewSetCount == 2);
|
|
|
|
testScene->Deactivate();
|
|
}
|
|
|
|
TEST_F(SceneTests, SceneNotificationTest_ConnectAfterRenderPipelineAdded)
|
|
{
|
|
// Create scene with feature processor which enables scene notification handler
|
|
SceneDescriptor sceneDesc;
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
testScene->Activate();
|
|
|
|
RenderPipelineId pipelineId1 = RenderPipelineId("pipeline1");
|
|
RenderPipelineId pipelineId2 = RenderPipelineId("pipeline2");
|
|
|
|
RenderPipelineDescriptor pipelineDesc;
|
|
pipelineDesc.m_name = pipelineId1.GetCStr();
|
|
RenderPipelinePtr pipeline1 = RenderPipeline::CreateRenderPipeline(pipelineDesc);
|
|
pipelineDesc.m_name = pipelineId2.GetCStr();
|
|
RenderPipelinePtr pipeline2 = RenderPipeline::CreateRenderPipeline(pipelineDesc);
|
|
|
|
// Do some render pipeline operations and keep render pipeline1 added
|
|
testScene->AddRenderPipeline(pipeline1);
|
|
testScene->AddRenderPipeline(pipeline2);
|
|
testScene->RemoveRenderPipeline(pipelineId2);
|
|
|
|
// Create a raster pass with viewTag "mainCamera"
|
|
const RPI::PipelineViewTag viewTag{ "mainCamera" };
|
|
PassDescriptor passDesc;
|
|
AZStd::shared_ptr<PassTemplate> passTemplate = AZStd::make_shared<PassTemplate>();
|
|
AZStd::shared_ptr<RasterPassData> passData = AZStd::make_shared<RasterPassData>();
|
|
passData->m_drawListTag = "forward";
|
|
passData->m_pipelineViewTag = viewTag.GetCStr();
|
|
passTemplate->m_passData = passData;
|
|
passDesc.m_passName = "raster";
|
|
passDesc.m_passTemplate = passTemplate;
|
|
Ptr<RasterPass> newPass = RasterPass::Create(passDesc);
|
|
|
|
// Add new pass to render pipeline which should trigger render pipeline pass modify notification
|
|
pipeline1->GetRootPass()->AddChild(newPass);
|
|
// This function is called in every RPISystem render tick. We call it manually here to trigger the pass change notification
|
|
pipeline1->OnPassModified();
|
|
// Set view to pipeline
|
|
ViewPtr view = View::CreateView(AZ::Name("TestView"), RPI::View::UsageCamera);
|
|
pipeline1->SetPersistentView(viewTag, view);
|
|
|
|
// Enable the feature processor which has notification handler enabled
|
|
TestFeatureProcessor1* feature = testScene->EnableFeatureProcessor<TestFeatureProcessor1>();
|
|
EXPECT_TRUE(feature->m_pipelineCount == 1);
|
|
EXPECT_TRUE(feature->m_lastPipeline == pipeline1.get());
|
|
EXPECT_TRUE(feature->m_viewSetCount == 1);
|
|
EXPECT_TRUE(feature->m_pipelineChangedCount == 0);
|
|
|
|
testScene->Deactivate();
|
|
}
|
|
|
|
|
|
TEST_F(SceneTests, GetFeatureProcessor_ByInterface_CanModifyFeatureProcessorViaInterface)
|
|
{
|
|
// Create scene with one test feature processor
|
|
SceneDescriptor sceneDesc;
|
|
sceneDesc.m_featureProcessorNames.push_back(AZStd::string(TestFeatureProcessorImplementation::RTTI_TypeName()));
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
testScene->Activate();
|
|
|
|
TestFeatureProcessorInterface* featureProcessorInterface = testScene->GetFeatureProcessor<TestFeatureProcessorInterface>();
|
|
EXPECT_TRUE(featureProcessorInterface != nullptr);
|
|
|
|
// Check that the pointer is valid
|
|
int testValue = 7;
|
|
featureProcessorInterface->SetValue(testValue);
|
|
EXPECT_EQ(featureProcessorInterface->GetValue(), testValue);
|
|
|
|
// Check that changes made by the interface apply to the underlying implemented feature processor
|
|
TestFeatureProcessorImplementation* featureProcessorImplementation = testScene->GetFeatureProcessor<TestFeatureProcessorImplementation>();
|
|
EXPECT_TRUE(featureProcessorInterface == featureProcessorImplementation);
|
|
EXPECT_TRUE(featureProcessorImplementation->GetValue() == testValue);
|
|
|
|
// Check that changes made by the implementation apply to the interface
|
|
int anotherTestValue = 21;
|
|
featureProcessorImplementation->SetValue(anotherTestValue);
|
|
EXPECT_TRUE(featureProcessorInterface->GetValue() == anotherTestValue);
|
|
|
|
// Check that the feature processor can be disabled
|
|
testScene->DisableFeatureProcessor<TestFeatureProcessorImplementation>();
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor<TestFeatureProcessorInterface>() == nullptr);
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor<TestFeatureProcessorImplementation>() == nullptr);
|
|
|
|
testScene->Deactivate();
|
|
}
|
|
|
|
TEST_F(SceneTests, GetFeatureProcessorByNameId_UsingStringForFeatureProcessorId_ReturnsValidFeatureProcessor)
|
|
{
|
|
// Create scene with one test feature processor
|
|
SceneDescriptor sceneDesc;
|
|
sceneDesc.m_featureProcessorNames.push_back(AZStd::string(TestFeatureProcessor1::RTTI_TypeName()));
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
testScene->Activate();
|
|
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor(FeatureProcessorId{ "TestFeatureProcessor1" }) != nullptr);
|
|
|
|
testScene->Deactivate();
|
|
}
|
|
|
|
//
|
|
// Two implementations of the same interface
|
|
//
|
|
TEST_F(SceneTests, EnableDisableFeatureProcessorByNameId_MultipleImplmentationsOfTheSameInterface_ReturnsValidFeatureProcessor)
|
|
{
|
|
SceneDescriptor sceneDesc;
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
testScene->Activate();
|
|
|
|
// You can enable either implementation, as long as they are not both active in the same scene
|
|
FeatureProcessor* firstImplementation = testScene->EnableFeatureProcessor(FeatureProcessorId{ TestFeatureProcessorImplementation::RTTI_TypeName() });
|
|
EXPECT_TRUE(firstImplementation != nullptr);
|
|
testScene->DisableFeatureProcessor(FeatureProcessorId{ TestFeatureProcessorImplementation::RTTI_TypeName() });
|
|
|
|
FeatureProcessor* secondImplementation = testScene->EnableFeatureProcessor(FeatureProcessorId{ TestFeatureProcessorImplementation2::RTTI_TypeName() });
|
|
EXPECT_TRUE(secondImplementation != nullptr);
|
|
|
|
testScene->Deactivate();
|
|
}
|
|
|
|
TEST_F(SceneTests, EnableDisableFeatureProcessorByType_MultipleImplmentationsOfTheSameInterface_ReturnsValidFeatureProcessor)
|
|
{
|
|
SceneDescriptor sceneDesc;
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
testScene->Activate();
|
|
|
|
// You can enable either implementation, as long as they are not both active in the same scene
|
|
FeatureProcessor* firstImplementation = testScene->EnableFeatureProcessor<TestFeatureProcessorImplementation>();
|
|
EXPECT_TRUE(firstImplementation != nullptr);
|
|
testScene->DisableFeatureProcessor<TestFeatureProcessorImplementation>();
|
|
|
|
FeatureProcessor* secondImplementation = testScene->EnableFeatureProcessor<TestFeatureProcessorImplementation2>();
|
|
EXPECT_TRUE(secondImplementation != nullptr);
|
|
|
|
testScene->Deactivate();
|
|
}
|
|
|
|
TEST_F(SceneTests, GetFeatureProcessorByNameId_MultipleImplmentationsOfTheSameInterface_ReturnsValidFeatureProcessor)
|
|
{
|
|
SceneDescriptor sceneDesc;
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
testScene->Activate();
|
|
|
|
// You can get a feature processor via its name ID, no matter which implementation is enabled by the scene
|
|
FeatureProcessor* firstImplementation = testScene->EnableFeatureProcessor<TestFeatureProcessorImplementation>();
|
|
FeatureProcessor* featureProcessor = testScene->GetFeatureProcessor(FeatureProcessorId{ TestFeatureProcessorImplementation::RTTI_TypeName() });
|
|
EXPECT_TRUE(firstImplementation == featureProcessor);
|
|
testScene->DisableFeatureProcessor(FeatureProcessorId{ TestFeatureProcessorImplementation::RTTI_TypeName() });
|
|
|
|
FeatureProcessor* secondImplementation = testScene->EnableFeatureProcessor<TestFeatureProcessorImplementation2>();
|
|
featureProcessor = testScene->GetFeatureProcessor(FeatureProcessorId{ TestFeatureProcessorImplementation2::RTTI_TypeName() });
|
|
EXPECT_TRUE(secondImplementation == featureProcessor);
|
|
|
|
testScene->Deactivate();
|
|
}
|
|
|
|
TEST_F(SceneTests, GetFeatureProcessorByInterface_MultipleImplmentationsOfTheSameInterface_ReturnsValidFeatureProcessor)
|
|
{
|
|
SceneDescriptor sceneDesc;
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
testScene->Activate();
|
|
|
|
// You can get a feature processor via its interface, no matter which implementation is enabled by the scene
|
|
// as long as only one is enabled by the scene
|
|
FeatureProcessor* firstImplementation = testScene->EnableFeatureProcessor<TestFeatureProcessorImplementation>();
|
|
TestFeatureProcessorInterface* featureProcessorInterface = testScene->GetFeatureProcessor<TestFeatureProcessorInterface>();
|
|
EXPECT_TRUE(firstImplementation == featureProcessorInterface);
|
|
testScene->DisableFeatureProcessor(FeatureProcessorId{ TestFeatureProcessorImplementation::RTTI_TypeName() });
|
|
|
|
FeatureProcessor* secondImplementation = testScene->EnableFeatureProcessor<TestFeatureProcessorImplementation2>();
|
|
|
|
featureProcessorInterface = testScene->GetFeatureProcessor<TestFeatureProcessorInterface>();
|
|
EXPECT_TRUE(secondImplementation == featureProcessorInterface);
|
|
|
|
testScene->Deactivate();
|
|
}
|
|
|
|
//
|
|
// Invalid cases
|
|
//
|
|
TEST_F(SceneTests, EnableFeatureProcessor_ByInterfaceName_FailsToEnable)
|
|
{
|
|
SceneDescriptor sceneDesc;
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
testScene->Activate();
|
|
|
|
AZ_TEST_START_ASSERTTEST;
|
|
FeatureProcessor* featureProcessor = testScene->EnableFeatureProcessor(FeatureProcessorId{ TestFeatureProcessorInterface::RTTI_TypeName() });
|
|
AZ_TEST_STOP_ASSERTTEST(1);
|
|
|
|
EXPECT_TRUE(featureProcessor == nullptr);
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor<TestFeatureProcessorImplementation>() == nullptr);
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor<TestFeatureProcessorInterface>() == nullptr);
|
|
|
|
testScene->Deactivate();
|
|
}
|
|
|
|
TEST_F(SceneTests, DisableFeatureProcessor_ByInterface_FailsToDisable)
|
|
{
|
|
SceneDescriptor sceneDesc;
|
|
sceneDesc.m_featureProcessorNames.push_back(AZStd::string(TestFeatureProcessorImplementation::RTTI_TypeName()));
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
testScene->Activate();
|
|
|
|
testScene->DisableFeatureProcessor(FeatureProcessorId{ TestFeatureProcessorInterface::RTTI_TypeName() });
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor<TestFeatureProcessorImplementation>() != nullptr);
|
|
EXPECT_TRUE(testScene->GetFeatureProcessor<TestFeatureProcessorInterface>() != nullptr);
|
|
|
|
testScene->Deactivate();
|
|
}
|
|
|
|
TEST_F(SceneTests, EnableFeatureProcessor_MultipleImplmentationsOfTheSameInterface_FailsToEnable)
|
|
{
|
|
SceneDescriptor sceneDesc;
|
|
ScenePtr testScene = Scene::CreateScene(sceneDesc);
|
|
testScene->Activate();
|
|
|
|
// You can enable one implementation of a feature processor on a scene
|
|
FeatureProcessor* firstImplementation = testScene->EnableFeatureProcessor(FeatureProcessorId{ TestFeatureProcessorImplementation::RTTI_TypeName() });
|
|
EXPECT_TRUE(firstImplementation != nullptr);
|
|
|
|
// But you can't enable two implementations of the same interface in one scene at the same time.
|
|
// Otherwise, when you get a feature processor by its interface, the scene wouldn't know which one to return.
|
|
AZ_TEST_START_ASSERTTEST;
|
|
FeatureProcessor* secondImplementation = testScene->EnableFeatureProcessor(FeatureProcessorId{ TestFeatureProcessorImplementation2::RTTI_TypeName() });
|
|
AZ_TEST_STOP_ASSERTTEST(1);
|
|
|
|
// If another implementation that uses the same interface exists, that will be the feature processor that is returned
|
|
EXPECT_TRUE(secondImplementation == firstImplementation);
|
|
|
|
testScene->Deactivate();
|
|
}
|
|
|
|
} // namespace UnitTest
|