[LYN-7064] Hot Loading of Procedural Prefabs (#4923)
* Prefab hotloading - load and maintain asset references Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Working hotloading Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Clean up code, add comments Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add missing includes Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add event for template removal. Clear ProceduralPrefabSystemComponent lookup when templates are removed. Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add unit test. Fix missing include, make sure source name is set Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix missing include Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix missing include Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Update comments to make ebus event behavior more clear Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix missing include Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix missing includes Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix missing include Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix temp directory usage which doesn't work on linux Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix temp directory usage which doesn't work on linux Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Use AZ::IO::Path for comparison. Print paths on failure Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix unit test - register asset with catalog so it can be looked up later Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>monroegm-disable-blank-issue-2
parent
45abb9f88e
commit
71bb200e0a
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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 <AssetCatalog/PlatformAddressedAssetCatalogBus.h>
|
||||
#include <AzCore/Serialization/Json/JsonUtils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
#include <AzToolsFramework/Prefab/ProceduralPrefabSystemComponent.h>
|
||||
#include <Prefab/PrefabDomUtils.h>
|
||||
#include <Prefab/PrefabLoaderInterface.h>
|
||||
#include <Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <Prefab/Procedural/ProceduralPrefabAsset.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
void ProceduralPrefabSystemComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializationContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializationContext->Class<ProceduralPrefabSystemComponent>();
|
||||
}
|
||||
}
|
||||
|
||||
void ProceduralPrefabSystemComponent::Activate()
|
||||
{
|
||||
AZ::Interface<ProceduralPrefabSystemComponentInterface>::Register(this);
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void ProceduralPrefabSystemComponent::Deactivate()
|
||||
{
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
|
||||
AZ::Interface<ProceduralPrefabSystemComponentInterface>::Unregister(this);
|
||||
|
||||
AZStd::scoped_lock lock(m_lookupMutex);
|
||||
m_assetIdToTemplateLookup.clear();
|
||||
}
|
||||
|
||||
void ProceduralPrefabSystemComponent::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
TemplateId templateId = InvalidTemplateId;
|
||||
|
||||
{
|
||||
AZStd::scoped_lock lock(m_lookupMutex);
|
||||
auto itr = m_assetIdToTemplateLookup.find(assetId);
|
||||
|
||||
if (itr != m_assetIdToTemplateLookup.end())
|
||||
{
|
||||
templateId = itr->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (templateId != InvalidTemplateId)
|
||||
{
|
||||
auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
|
||||
if (!prefabSystemComponentInterface)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Failed to get PrefabSystemComponentInterface");
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::string assetPath;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
assetPath, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetPathById, assetId);
|
||||
|
||||
auto readResult = AZ::Utils::ReadFile(assetPath, AZStd::numeric_limits<size_t>::max());
|
||||
if (!readResult.IsSuccess())
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
"ProceduralPrefabSystemComponent::OnCatalogAssetChanged - Failed to read Prefab file from '%.*s'."
|
||||
"Error message: '%s'",
|
||||
AZ_STRING_ARG(assetPath), readResult.GetError().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::Outcome<PrefabDom, AZStd::string> readPrefabFileResult = AZ::JsonSerializationUtils::ReadJsonString(readResult.TakeValue());
|
||||
if (!readPrefabFileResult.IsSuccess())
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
"ProceduralPrefabSystemComponent::OnCatalogAssetChanged - Failed to read Prefab json from '%.*s'."
|
||||
"Error message: '%s'",
|
||||
AZ_STRING_ARG(assetPath), readPrefabFileResult.GetError().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::IO::Path relativePath = AZ::Interface<PrefabLoaderInterface>::Get()->GenerateRelativePath(assetPath.c_str());
|
||||
PrefabDomPath sourcePath = PrefabDomPath((AZStd::string("/") + PrefabDomUtils::SourceName).c_str());
|
||||
sourcePath.Set(readPrefabFileResult.GetValue(), relativePath.Native().c_str());
|
||||
|
||||
prefabSystemComponentInterface->UpdatePrefabTemplate(templateId, readPrefabFileResult.TakeValue());
|
||||
}
|
||||
}
|
||||
|
||||
void ProceduralPrefabSystemComponent::OnTemplateRemoved(TemplateId removedTemplateId)
|
||||
{
|
||||
AZStd::scoped_lock lock(m_lookupMutex);
|
||||
|
||||
for (const auto& [assetId, templateId] : m_assetIdToTemplateLookup)
|
||||
{
|
||||
if (templateId == removedTemplateId)
|
||||
{
|
||||
m_assetIdToTemplateLookup.erase(assetId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProceduralPrefabSystemComponent::OnAllTemplatesRemoved()
|
||||
{
|
||||
AZStd::scoped_lock lock(m_lookupMutex);
|
||||
|
||||
m_assetIdToTemplateLookup.clear();
|
||||
}
|
||||
|
||||
void ProceduralPrefabSystemComponent::RegisterProceduralPrefab(const AZStd::string& prefabFilePath, TemplateId templateId)
|
||||
{
|
||||
AZ::Data::AssetId assetId;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
assetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, prefabFilePath.c_str(),
|
||||
azrtti_typeid<AZ::Prefab::ProceduralPrefabAsset>(), false);
|
||||
|
||||
if (assetId.IsValid())
|
||||
{
|
||||
AZStd::scoped_lock lock(m_lookupMutex);
|
||||
m_assetIdToTemplateLookup[assetId] = templateId;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Prefab", false, "Failed to find AssetId for prefab %s", prefabFilePath.c_str());
|
||||
}
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <Prefab/ProceduralPrefabSystemComponentInterface.h>
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
class ProceduralPrefabSystemComponent
|
||||
: public AZ::Component
|
||||
, ProceduralPrefabSystemComponentInterface
|
||||
, AzFramework::AssetCatalogEventBus::Handler
|
||||
, PrefabPublicNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(ProceduralPrefabSystemComponent, "{81211818-088A-49E6-894B-7A11764106B1}");
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
protected:
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
|
||||
void OnCatalogAssetChanged(const AZ::Data::AssetId&) override;
|
||||
|
||||
void OnTemplateRemoved(TemplateId templateId) override;
|
||||
void OnAllTemplatesRemoved() override;
|
||||
|
||||
void RegisterProceduralPrefab(const AZStd::string& prefabFilePath, TemplateId templateId) override;
|
||||
|
||||
AZStd::mutex m_lookupMutex;
|
||||
AZStd::unordered_map<AZ::Data::AssetId, TemplateId> m_assetIdToTemplateLookup;
|
||||
};
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabIdTypes.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
class ProceduralPrefabSystemComponentInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(ProceduralPrefabSystemComponentInterface, "{C403B89C-63DD-418C-B821-FBCBE1EF42AE}");
|
||||
|
||||
virtual ~ProceduralPrefabSystemComponentInterface() = default;
|
||||
|
||||
// Registers a procedural prefab file + templateId so the system can track changes and handle updates
|
||||
virtual void RegisterProceduralPrefab(const AZStd::string& prefabFilePath, TemplateId templateId) = 0;
|
||||
};
|
||||
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* 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 <Utils/Utils.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
struct ProceduralPrefabSystemComponentTests
|
||||
: AllocatorsTestFixture
|
||||
, 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;
|
||||
|
||||
AllocatorsTestFixture::SetUp();
|
||||
|
||||
AZ::ComponentApplicationBus::Handler::BusConnect();
|
||||
|
||||
ASSERT_TRUE(m_temporaryDirectory.IsValid());
|
||||
|
||||
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();
|
||||
AllocatorsTestFixture::TearDown();
|
||||
|
||||
TestRunner::Instance().ResetSuppressionSettingsToDefault();
|
||||
}
|
||||
|
||||
// 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;
|
||||
ScopedTemporaryDirectory 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);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue