123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- /*
- * 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/IO/FileIO.h>
- #include <AzCore/IO/Path/PathReflect.h>
- #include <AzCore/Serialization/Json/JsonSystemComponent.h>
- #include <AzCore/Serialization/Json/RegistrationContext.h>
- #include <AzCore/Settings/SettingsRegistryImpl.h>
- #include <AzFramework/IO/LocalFileIO.h>
- #include <Prefab/PrefabTestFixture.h>
- #include <Prefab/ProceduralPrefabSystemComponent.h>
- #include <AzCore/Settings/SettingsRegistryMergeUtils.h>
- #include <AZTestShared/Utils/Utils.h>
- namespace UnitTest
- {
- struct ProceduralPrefabSystemComponentTests
- : LeakDetectionFixture
- , AZ::ComponentApplicationBus::Handler
- {
- void SetUp() override
- {
- TestRunner::Instance().m_suppressOutput = false;
- TestRunner::Instance().m_suppressPrintf = false;
- TestRunner::Instance().m_suppressWarnings = false;
- TestRunner::Instance().m_suppressErrors = false;
- TestRunner::Instance().m_suppressAsserts = false;
- LeakDetectionFixture::SetUp();
- AZ::ComponentApplicationBus::Handler::BusConnect();
- m_localFileIo = AZStd::make_unique<AZ::IO::LocalFileIO>();
- m_prevIoBase = AZ::IO::FileIOBase::GetInstance();
- AZ::IO::FileIOBase::SetInstance(nullptr); // Need to clear the previous instance first
- AZ::IO::FileIOBase::SetInstance(m_localFileIo.get());
- AZ::JsonSystemComponent::Reflect(&m_jsonContext);
- m_settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
- AZ::SettingsRegistry::Register(m_settingsRegistry.get());
- m_settingsRegistry->Set(AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath, m_temporaryDirectory.GetDirectory());
- m_prefabSystem = PrefabSystemComponent::CreateDescriptor();
- m_procSystem = ProceduralPrefabSystemComponent::CreateDescriptor();
- m_prefabSystem->Reflect(&m_context);
- m_prefabSystem->Reflect(&m_jsonContext);
- m_procSystem->Reflect(&m_context);
- m_procSystem->Reflect(&m_jsonContext);
- AZ::Entity::Reflect(&m_context);
- AZ::Entity::Reflect(&m_jsonContext);
- AZ::IO::PathReflect(&m_context);
- m_systemEntity = AZStd::make_unique<AZ::Entity>();
- m_systemEntity->CreateComponent<PrefabSystemComponent>();
- m_systemEntity->CreateComponent<ProceduralPrefabSystemComponent>();
- m_systemEntity->Init();
- m_systemEntity->Activate();
- AZ::Data::AssetManager::Create({});
- }
- void TearDown() override
- {
- AZ::Data::AssetManager::Destroy();
- m_systemEntity->Deactivate();
- m_systemEntity = nullptr;
- m_jsonContext.EnableRemoveReflection();
- AZ::JsonSystemComponent::Reflect(&m_jsonContext);
- m_prefabSystem->Reflect(&m_jsonContext);
- m_procSystem->Reflect(&m_jsonContext);
- AZ::Entity::Reflect(&m_jsonContext);
- m_jsonContext.DisableRemoveReflection();
- AZ::IO::FileIOBase::SetInstance(nullptr); // Clear the previous instance first
- AZ::IO::FileIOBase::SetInstance(m_prevIoBase);
- m_prevIoBase = nullptr;
- AZ::SettingsRegistry::Unregister(m_settingsRegistry.get());
- AZ::ComponentApplicationBus::Handler::BusDisconnect();
- LeakDetectionFixture::TearDown();
- TestRunner::Instance().ResetSuppressionSettingsToDefault();
- delete m_procSystem;
- m_procSystem = nullptr;
- delete m_prefabSystem;
- m_prefabSystem = nullptr;
- }
- // ComponentApplicationBus
- AZ::ComponentApplication* GetApplication() override
- {
- return nullptr;
- }
- void RegisterComponentDescriptor(const AZ::ComponentDescriptor*) override { }
- void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override { }
- void RegisterEntityAddedEventHandler(AZ::EntityAddedEvent::Handler&) override { }
- void RegisterEntityRemovedEventHandler(AZ::EntityRemovedEvent::Handler&) override { }
- void RegisterEntityActivatedEventHandler(AZ::EntityActivatedEvent::Handler&) override { }
- void RegisterEntityDeactivatedEventHandler(AZ::EntityDeactivatedEvent::Handler&) override { }
- void SignalEntityActivated(AZ::Entity*) override { }
- void SignalEntityDeactivated(AZ::Entity*) override { }
- bool AddEntity(AZ::Entity*) override
- {
- return true;
- }
- bool RemoveEntity(AZ::Entity*) override
- {
- return true;
- }
- bool DeleteEntity(const AZ::EntityId&) override
- {
- return true;
- }
- AZ::Entity* FindEntity(const AZ::EntityId&) override
- {
- return nullptr;
- }
- AZ::SerializeContext* GetSerializeContext() override
- {
- return &m_context;
- }
- AZ::BehaviorContext* GetBehaviorContext() override
- {
- return nullptr;
- }
- AZ::JsonRegistrationContext* GetJsonRegistrationContext() override
- {
- return &m_jsonContext;
- }
- const char* GetEngineRoot() const override
- {
- return nullptr;
- }
- const char* GetExecutableFolder() const override
- {
- return nullptr;
- }
- void EnumerateEntities(const EntityCallback& /*callback*/) override { }
- void QueryApplicationType(AZ::ApplicationTypeQuery& /*appType*/) const override { }
- ////
- AZ::ComponentDescriptor* m_prefabSystem{};
- AZ::ComponentDescriptor* m_procSystem{};
- AZStd::unique_ptr<AZ::SettingsRegistryImpl> m_settingsRegistry;
- AZ::SerializeContext m_context;
- AZ::JsonRegistrationContext m_jsonContext;
- AZStd::unique_ptr<AZ::IO::LocalFileIO> m_localFileIo;
- AZ::Test::ScopedAutoTempDirectory m_temporaryDirectory;
- AZStd::unique_ptr<AZ::Entity> m_systemEntity;
- AZ::IO::FileIOBase* m_prevIoBase{};
- };
- struct MockCatalog : AZ::Data::AssetCatalogRequestBus::Handler
- {
- static const inline AZ::Data::AssetId TestId{ AZ::Uuid::CreateRandom(), 1234 };
- MockCatalog(AZStd::string testFile)
- : m_testFile(AZStd::move(testFile))
- {
- BusConnect();
- }
- ~MockCatalog() override
- {
- BusDisconnect();
- }
- AZStd::string GetAssetPathById(const AZ::Data::AssetId& assetId) override
- {
- if (assetId == TestId)
- {
- return m_testFile;
- }
- return "InvalidAssetId";
- }
- AZ::Data::AssetId GetAssetIdByPath(const char* path, const AZ::Data::AssetType&, bool) override
- {
- AZ::IO::PathView pathView{ AZStd::string_view(path) };
- if (AZ::IO::PathView(m_testFile) == pathView)
- {
- return TestId;
- }
- AZ_Error("MockCatalog", false, "Requested path %s does not match expected asset path of %s", path, m_testFile.c_str());
- ADD_FAILURE();
- return {};
- }
- AZStd::string m_testFile;
- };
- struct PrefabPublicNotificationsListener : PrefabPublicNotificationBus::Handler
- {
- PrefabPublicNotificationsListener()
- {
- BusConnect();
- }
- ~PrefabPublicNotificationsListener() override
- {
- BusDisconnect();
- }
- void OnPrefabInstancePropagationBegin() override
- {
- m_updated = true;
- }
- bool m_updated = false;
- };
- TEST_F(ProceduralPrefabSystemComponentTests, RegisteredPrefabUpdates)
- {
- const AZStd::string prefabFile = (AZ::IO::Path(m_temporaryDirectory.GetDirectory()) / "test.prefab").Native();
- MockCatalog catalog(prefabFile.c_str());
- auto proceduralPrefabSystemComponentInterface = AZ::Interface<ProceduralPrefabSystemComponentInterface>::Get();
- auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
- auto prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
- ASSERT_NE(proceduralPrefabSystemComponentInterface, nullptr);
- ASSERT_NE(prefabSystemComponentInterface, nullptr);
- ASSERT_NE(prefabLoaderInterface, nullptr);
- auto entity = aznew AZ::Entity();
- AZStd::unique_ptr<Instance> instance = prefabSystemComponentInterface->CreatePrefab({ entity }, {}, prefabFile.c_str());
- ASSERT_NE(instance, nullptr);
- prefabLoaderInterface->SaveTemplateToFile(instance->GetTemplateId(), prefabFile.c_str());
- proceduralPrefabSystemComponentInterface->RegisterProceduralPrefab(prefabFile, instance->GetTemplateId());
- AzFramework::AssetCatalogEventBus::Broadcast(&AzFramework::AssetCatalogEventBus::Events::OnCatalogAssetChanged, MockCatalog::TestId);
- PrefabPublicNotificationsListener listener;
- AZ::SystemTickBus::Broadcast(&AZ::SystemTickBus::Events::OnSystemTick);
- EXPECT_TRUE(listener.m_updated);
- }
- TEST_F(ProceduralPrefabSystemComponentTests, UnregisteredPrefabDoesNotUpdate)
- {
- PrefabPublicNotificationsListener listener;
- const AZStd::string prefabFile = (AZ::IO::Path(m_temporaryDirectory.GetDirectory()) / "test.prefab").Native();
- MockCatalog catalog(prefabFile.c_str());
- auto proceduralPrefabSystemComponentInterface = AZ::Interface<ProceduralPrefabSystemComponentInterface>::Get();
- auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
- auto prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
- ASSERT_NE(proceduralPrefabSystemComponentInterface, nullptr);
- ASSERT_NE(prefabSystemComponentInterface, nullptr);
- ASSERT_NE(prefabLoaderInterface, nullptr);
- auto entity = aznew AZ::Entity();
- AZStd::unique_ptr<Instance> instance = prefabSystemComponentInterface->CreatePrefab({ entity }, {}, prefabFile.c_str());
- ASSERT_NE(instance, nullptr);
- prefabLoaderInterface->SaveTemplateToFile(instance->GetTemplateId(), prefabFile.c_str());
- AzFramework::AssetCatalogEventBus::Broadcast(
- &AzFramework::AssetCatalogEventBus::Events::OnCatalogAssetChanged, MockCatalog::TestId);
- AZ::SystemTickBus::Broadcast(&AZ::SystemTickBus::Events::OnSystemTick);
- EXPECT_FALSE(listener.m_updated);
- }
- }
|