Added a CriticalAssetsCompiled Lifecycle event (#6469)

The CriticalAssetsCompiled event can be handled to detect when the
AssetProcessor has finished processing Critical Assets

Also with the new event, an audit has been performed over all the
locations where the AssetCatalogEventBus OnCatalogLoaded event was being
handle to make sure it was the proper event to use.
If the handler was actually examing the enumerating over the full
catalog or querying all assets within the catalog, then it was a proper
use.
For handlers that were interested in a particular asset it was not

Moreover added implementations of `OnCatalogAssetChanged` and
`OnCatalogAssetAdded` to the FileTagComponent and the MaterialViewportComponent.

Any applications which uses the AtomToolsApplication
class(MaterialEditor, AtomSampleViewerStandalone,
ShaderMangementConsole) now signals a "CriticalAssetsCompiled" lifecycle
event as well as loads the "assetcatalog.xml" if it exists.

The Launcher application signals the "CrticalAssetsCompiled" event and
reloads the "assetcatalog.xml" for the ${project}.GameLauncher and
${project}.ServerLauncher in Launcher.cpp

Finally the Editor signals the "CriticalAssetsCompiled" and reloads the
"assetcatalog.xml" in CryEdit.cpp

resolves #6093

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
lumberyard-employee-dm
2022-01-10 15:21:04 -06:00
committed by GitHub
parent df7a2fbd9d
commit 18ea4ba6a8
19 changed files with 233 additions and 113 deletions
+21 -2
View File
@@ -1352,8 +1352,27 @@ void CCryEditApp::CompileCriticalAssets() const
}
}
assetsInQueueNotifcation.BusDisconnect();
CCryEditApp::OutputStartupMessage(QString("Asset Processor is now ready."));
// Signal the "CriticalAssetsCompiled" lifecycle event
// Also reload the "assetcatalog.xml" if it exists
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
{
AZ::ComponentApplicationLifecycle::SignalEvent(*settingsRegistry, "CriticalAssetsCompiled", R"({})");
// Reload the assetcatalog.xml at this point again
// Start Monitoring Asset changes over the network and load the AssetCatalog
auto LoadCatalog = [settingsRegistry](AZ::Data::AssetCatalogRequests* assetCatalogRequests)
{
if (AZ::IO::FixedMaxPath assetCatalogPath;
settingsRegistry->Get(assetCatalogPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder))
{
assetCatalogPath /= "assetcatalog.xml";
assetCatalogRequests->LoadCatalog(assetCatalogPath.c_str());
}
};
AZ::Data::AssetCatalogRequestBus::Broadcast(AZStd::move(LoadCatalog));
}
CCryEditApp::OutputStartupMessage(QString("Asset Processor is now ready."));
}
bool CCryEditApp::ConnectToAssetProcessor() const
@@ -1669,7 +1688,7 @@ bool CCryEditApp::InitInstance()
return false;
}
if (AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get())
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
{
AZ::ComponentApplicationLifecycle::SignalEvent(*settingsRegistry, "LegacySystemInterfaceCreated", R"({})");
}
@@ -97,19 +97,38 @@ namespace AzFramework
AZStd::vector<AZStd::string> registeredAssetPaths;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(registeredAssetPaths, &AZ::Data::AssetCatalogRequests::GetRegisteredAssetPaths);
const char* dependencyXmlPattern = "*_dependencies.xml";
constexpr const char* dependencyXmlPattern = "_dependencies.xml";
for (const AZStd::string& assetPath : registeredAssetPaths)
{
if (!AZStd::wildcard_match(dependencyXmlPattern, assetPath.c_str()))
if (assetPath.ends_with(dependencyXmlPattern))
{
continue;
}
if (!m_excludeFileQueryManager.get()->LoadEngineDependencies(assetPath))
{
AZ_Error("ExcludeFileComponent", false, "Failed to add assets referenced from %s to the blocked list", assetPath.c_str());
AZ_VerifyError("ExcludeFileComponent", m_excludeFileQueryManager.get()->LoadEngineDependencies(assetPath),
"Failed to add assets referenced from %s to the blocked list", assetPath.c_str());
}
}
}
void ExcludeFileComponent::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId)
{
// Reload any modified "<name>_dependencies.xml" files
AZ::IO::Path assetPath;
auto GetAssetPath = [&assetId, &assetPath](AZ::Data::AssetCatalogRequests* assetCatalogRequests)
{
assetPath = assetCatalogRequests->GetAssetPathById(assetId);
};
AZ::Data::AssetCatalogRequestBus::Broadcast(AZStd::move(GetAssetPath));
constexpr const char* dependencyXmlPattern = "_dependencies.xml";
if (assetPath.Native().ends_with(dependencyXmlPattern))
{
AZ_VerifyError("ExcludeFileComponent", m_excludeFileQueryManager.get()->LoadEngineDependencies(assetPath.Native()),
"Failed to add assets referenced from %s to the blocked list", assetPath.c_str());
}
}
void ExcludeFileComponent::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
{
OnCatalogAssetChanged(assetId);
}
}
}
@@ -65,6 +65,8 @@ namespace AzFramework
void Deactivate() override;
void OnCatalogLoaded(const char* catalogFile) override;
void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override;
void OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) override;
static void Reflect(AZ::ReflectContext* context);
@@ -8,6 +8,7 @@
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/Asset/AssetSerializer.h>
#include <AzCore/Component/ComponentApplicationLifecycle.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/Spawnable/SpawnableMetaData.h>
@@ -61,15 +62,6 @@ namespace AzFramework
m_entitiesManager.ProcessQueue(SpawnableEntitiesManager::CommandQueuePriority::High);
}
void SpawnableSystemComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile)
{
if (!m_catalogAvailable)
{
m_catalogAvailable = true;
LoadRootSpawnableFromSettingsRegistry();
}
}
uint64_t SpawnableSystemComponent::AssignRootSpawnable(AZ::Data::Asset<Spawnable> rootSpawnable)
{
uint32_t generation = 0;
@@ -157,20 +149,29 @@ namespace AzFramework
// Register with AssetDatabase
AZ_Assert(AZ::Data::AssetManager::IsReady(), "Spawnables can't be registered because the Asset Manager is not ready yet.");
AZ::Data::AssetManager::Instance().RegisterHandler(&m_assetHandler, AZ::AzTypeInfo<Spawnable>::Uuid());
// Register with AssetCatalog
AZ::Data::AssetCatalogRequestBus::Broadcast(
&AZ::Data::AssetCatalogRequestBus::Events::EnableCatalogForAsset, AZ::AzTypeInfo<Spawnable>::Uuid());
AZ::Data::AssetCatalogRequestBus::Broadcast(
&AZ::Data::AssetCatalogRequestBus::Events::AddExtension, Spawnable::FileExtension);
AssetCatalogEventBus::Handler::BusConnect();
// Register for the CriticalAssetsCompiled lifecycle event to trigger the loading of the root spawnable
auto settingsRegistry = AZ::SettingsRegistry::Get();
AZ_Assert(settingsRegistry, "Unable to change root spawnable callback because Settings Registry is not available.");
auto LifecycleCallback = [this](AZStd::string_view, AZ::SettingsRegistryInterface::Type)
{
LoadRootSpawnableFromSettingsRegistry();
};
AZ::ComponentApplicationLifecycle::RegisterHandler(*settingsRegistry, m_criticalAssetsHandler,
AZStd::move(LifecycleCallback), "CriticalAssetsCompiled");
RootSpawnableNotificationBus::Handler::BusConnect();
AZ::TickBus::Handler::BusConnect();
auto registry = AZ::SettingsRegistry::Get();
AZ_Assert(registry, "Unable to change root spawnable callback because Settings Registry is not available.");
m_registryChangeHandler = registry->RegisterNotifier([this](AZStd::string_view path, AZ::SettingsRegistryInterface::Type /*type*/)
m_registryChangeHandler = settingsRegistry->RegisterNotifier([this](AZStd::string_view path, AZ::SettingsRegistryInterface::Type /*type*/)
{
if (path.starts_with(RootSpawnableRegistryKey))
{
@@ -187,13 +188,14 @@ namespace AzFramework
AZ::TickBus::Handler::BusDisconnect();
RootSpawnableNotificationBus::Handler::BusDisconnect();
AssetCatalogEventBus::Handler::BusDisconnect();
// Unregister Lifecycle event handler
m_criticalAssetsHandler = {};
if (m_catalogAvailable)
if (m_rootSpawnableId.IsValid())
{
ReleaseRootSpawnable();
// The SpawnalbleSystemComponent needs to guarantee there's no more processing left to do by the
// The SpawnableSystemComponent needs to guarantee there's no more processing left to do by the
// entity manager before it can safely destroy it on shutdown, but also to make sure that are no
// more calls to the callback registered to the root spawnable as that accesses this component.
m_rootSpawnableContainer.Clear();
@@ -210,8 +212,6 @@ namespace AzFramework
void SpawnableSystemComponent::LoadRootSpawnableFromSettingsRegistry()
{
AZ_Assert(m_catalogAvailable, "Attempting to load root spawnable while the catalog is not available yet.");
auto registry = AZ::SettingsRegistry::Get();
AZ_Assert(registry, "Unable to check for root spawnable because the Settings Registry is not available.");
@@ -12,7 +12,6 @@
#include <AzCore/Component/TickBus.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzCore/std/parallel/atomic.h>
#include <AzFramework/Asset/AssetCatalogBus.h>
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
#include <AzFramework/Spawnable/Spawnable.h>
#include <AzFramework/Spawnable/SpawnableAssetHandler.h>
@@ -25,7 +24,6 @@ namespace AzFramework
: public AZ::Component
, public AZ::TickBus::Handler
, public AZ::SystemTickBus::Handler
, public AssetCatalogEventBus::Handler
, public RootSpawnableInterface::Registrar
, public RootSpawnableNotificationBus::Handler
{
@@ -63,12 +61,6 @@ namespace AzFramework
void OnSystemTick() override;
//
// AssetCatalogEventBus
//
void OnCatalogLoaded(const char* catalogFile) override;
//
// RootSpawnableInterface
//
@@ -97,6 +89,6 @@ namespace AzFramework
AZ::SettingsRegistryInterface::NotifyEventHandler m_registryChangeHandler;
AZ::Data::AssetId m_rootSpawnableId;
bool m_catalogAvailable{ false };
AZ::SettingsRegistryInterface::NotifyEventHandler m_criticalAssetsHandler;
};
} // namespace AzFramework
+62 -34
View File
@@ -229,33 +229,65 @@ namespace O3DELauncher
void CreateRemoteFileIO();
bool ConnectToAssetProcessor()
// This function make sure the launcher has signaled the "CriticalAssetsCompiled"
// lifecycle event as well as to load the "assetcatalog.xml" file if it exists
void CompileCriticalAssets()
{
bool connectedToAssetProcessor{};
// When the AssetProcessor is already launched it should take less than a second to perform a connection
// but when the AssetProcessor needs to be launch it could take up to 15 seconds to have the AssetProcessor initialize
// and able to negotiate a connection when running a debug build
// and to negotiate a connection
// Setting the connectTimeout to 3 seconds if not set within the settings registry
AzFramework::AssetSystem::ConnectionSettings connectionSettings;
AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings);
connectionSettings.m_launchAssetProcessorOnFailedConnection = true;
connectionSettings.m_connectionIdentifier = AzFramework::AssetSystem::ConnectionIdentifiers::Game;
connectionSettings.m_loggingCallback = []([[maybe_unused]] AZStd::string_view logData)
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
{
AZ_TracePrintf("Launcher", "%.*s", aznumeric_cast<int>(logData.size()), logData.data());
};
AZ::ComponentApplicationLifecycle::SignalEvent(*settingsRegistry, "CriticalAssetsCompiled", R"({})");
// Reload the assetcatalog.xml at this point again
// Start Monitoring Asset changes over the network and load the AssetCatalog
auto LoadCatalog = [settingsRegistry](AZ::Data::AssetCatalogRequests* assetCatalogRequests)
{
if (AZ::IO::FixedMaxPath assetCatalogPath;
settingsRegistry->Get(assetCatalogPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder))
{
assetCatalogPath /= "assetcatalog.xml";
assetCatalogRequests->LoadCatalog(assetCatalogPath.c_str());
}
};
AZ::Data::AssetCatalogRequestBus::Broadcast(AZStd::move(LoadCatalog));
}
}
AzFramework::AssetSystemRequestBus::BroadcastResult(connectedToAssetProcessor, &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, connectionSettings);
if (connectedToAssetProcessor)
// If the connect option is false, this function will return true
// to make sure the Launcher passes the connected to AP check
// If REMOTE_ASSET_PROCESSOR is not defined, then the launcher doesn't need
// to connect to the AssetProcessor and therefore this function returns true
bool ConnectToAssetProcessor([[maybe_unused]] bool connect)
{
bool connectedToAssetProcessor = true;
#if defined(REMOTE_ASSET_PROCESSOR)
if (connect)
{
AZ_TracePrintf("Launcher", "Connected to Asset Processor\n");
CreateRemoteFileIO();
// When the AssetProcessor is already launched it should take less than a second to perform a connection
// but when the AssetProcessor needs to be launch it could take up to 15 seconds to have the AssetProcessor initialize
// and able to negotiate a connection when running a debug build
// and to negotiate a connection
// Setting the connectTimeout to 3 seconds if not set within the settings registry
AzFramework::AssetSystem::ConnectionSettings connectionSettings;
AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings);
connectionSettings.m_launchAssetProcessorOnFailedConnection = true;
connectionSettings.m_connectionIdentifier = AzFramework::AssetSystem::ConnectionIdentifiers::Game;
connectionSettings.m_loggingCallback = []([[maybe_unused]] AZStd::string_view logData)
{
AZ_TracePrintf("Launcher", "%.*s", aznumeric_cast<int>(logData.size()), logData.data());
};
AzFramework::AssetSystemRequestBus::BroadcastResult(connectedToAssetProcessor, &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, connectionSettings);
if (connectedToAssetProcessor)
{
AZ_TracePrintf("Launcher", "Connected to Asset Processor\n");
CreateRemoteFileIO();
}
}
#endif
CompileCriticalAssets();
return connectedToAssetProcessor;
}
@@ -403,25 +435,21 @@ namespace O3DELauncher
gameApplication.Start({}, gameApplicationStartupParams);
#if defined(REMOTE_ASSET_PROCESSOR)
bool allowedEngineConnection = !systemInitParams.bToolMode && !systemInitParams.bTestMode && bg_ConnectToAssetProcessor;
//connect to the asset processor using the bootstrap values
if (allowedEngineConnection)
const bool allowedEngineConnection = !systemInitParams.bToolMode && !systemInitParams.bTestMode && bg_ConnectToAssetProcessor;
if (!ConnectToAssetProcessor(allowedEngineConnection))
{
if (!ConnectToAssetProcessor())
AZ::s64 waitForConnect{};
AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, waitForConnect,
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, "wait_for_connect");
if (waitForConnect != 0)
{
AZ::s64 waitForConnect{};
AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, waitForConnect,
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, "wait_for_connect");
if (waitForConnect != 0)
{
AZ_Error("Launcher", false, "Failed to connect to AssetProcessor.");
return ReturnCode::ErrAssetProccessor;
}
AZ_Error("Launcher", false, "Failed to connect to AssetProcessor.");
return ReturnCode::ErrAssetProccessor;
}
}
#endif
AZ_Assert(AZ::AllocatorInstance<AZ::SystemAllocator>::IsReady(), "System allocator was not created or creation failed.");
//Initialize the Debug trace instance to create necessary environment variables
AZ::Debug::Trace::Instance().Init();
@@ -79,10 +79,6 @@ namespace AZ
return false;
}
// Load the asset catalog so that we can find any nested assets successfully. We also need to tick the tick bus
// so that the OnCatalogLoaded event gets processed now, instead of during application shutdown.
application.Tick();
AZStd::string logggingScratchBuffer;
SetupLogging(logggingScratchBuffer, convertSettings.m_reporting, *commandLine);
@@ -155,7 +155,7 @@ namespace AZ
{
Initialize();
},
"LegacySystemInterfaceCreated");
"CriticalAssetsCompiled");
}
}
@@ -34,8 +34,7 @@ namespace AZ
RPISystemInterface() = default;
virtual ~RPISystemInterface() = default;
//! Pre-load some system assets. This should be called once the asset catalog is ready and before create any RPI instances.
//! Note: can't rely on the AzFramework::AssetCatalogEventBus's OnCatalogLoaded since the order of calling handlers is undefined.
//! Pre-load some system assets. This should be called once Critical Asset have compiled ready and before create any RPI instances.
virtual void InitializeSystemAssets() = 0;
//! Was the RPI system initialized properly
@@ -12,6 +12,7 @@
#include <AtomToolsFramework/Window/AtomToolsMainWindowFactoryRequestBus.h>
#include <AtomToolsFramework/Window/AtomToolsMainWindowRequestBus.h>
#include <AzCore/Component/ComponentApplicationLifecycle.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/Utils/Utils.h>
@@ -295,10 +296,24 @@ namespace AtomToolsFramework
QMessageBox::critical(
activeWindow(), QString("Failed to compile critical assets"),
QString("Failed to compile the following critical assets:\n%1\n%2")
.arg(failedAssets.join(",\n"))
.arg("Make sure this is an Atom project."));
.arg(failedAssets.join(",\n"))
.arg("Make sure this is an Atom project."));
ExitMainLoop();
}
AZ::ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "CriticalAssetsCompiled", R"({})");
// Reload the assetcatalog.xml at this point again
// Start Monitoring Asset changes over the network and load the AssetCatalog
auto LoadCatalog = [settingsRegistry = m_settingsRegistry.get()](AZ::Data::AssetCatalogRequests* assetCatalogRequests)
{
if (AZ::IO::FixedMaxPath assetCatalogPath;
settingsRegistry->Get(assetCatalogPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder))
{
assetCatalogPath /= "assetcatalog.xml";
assetCatalogRequests->LoadCatalog(assetCatalogPath.c_str());
}
};
AZ::Data::AssetCatalogRequestBus::Broadcast(AZStd::move(LoadCatalog));
}
void AtomToolsApplication::SaveSettings()
@@ -18,7 +18,7 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/Asset/AssetSystemBus.h>
#include <AzFramework/IO/LocalFileIO.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <Viewport/MaterialViewportComponent.h>
@@ -165,12 +165,12 @@ namespace MaterialEditor
// AssetCatalogRequestBus::EnumerateAssets can lead to deadlocked)
AZ::Data::AssetCatalogRequests::AssetEnumerationCB enumerateCB = [this]([[maybe_unused]] const AZ::Data::AssetId id, const AZ::Data::AssetInfo& info)
{
if (AzFramework::StringFunc::EndsWith(info.m_relativePath.c_str(), ".lightingpreset.azasset"))
if (AZ::StringFunc::EndsWith(info.m_relativePath.c_str(), ".lightingpreset.azasset"))
{
m_lightingPresetAssets[info.m_assetId] = { info.m_assetId, info.m_assetType };
AZ::Data::AssetBus::MultiHandler::BusConnect(info.m_assetId);
}
else if (AzFramework::StringFunc::EndsWith(info.m_relativePath.c_str(), ".modelpreset.azasset"))
else if (AZ::StringFunc::EndsWith(info.m_relativePath.c_str(), ".modelpreset.azasset"))
{
m_modelPresetAssets[info.m_assetId] = { info.m_assetId, info.m_assetType };
AZ::Data::AssetBus::MultiHandler::BusConnect(info.m_assetId);
@@ -429,4 +429,51 @@ namespace MaterialEditor
ReloadContent();
});
}
void MaterialViewportComponent::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId)
{
auto ReloadLightingAndModelPresets = [this, &assetId](AZ::Data::AssetCatalogRequests* assetCatalogRequests)
{
AZ::Data::AssetInfo assetInfo = assetCatalogRequests->GetAssetInfoById(assetId);
AZ::Data::Asset<AZ::RPI::AnyAsset>* modifiedPresetAsset{};
if (AZ::StringFunc::EndsWith(assetInfo.m_relativePath.c_str(), ".lightingpreset.azasset"))
{
m_lightingPresetAssets[assetInfo.m_assetId] = { assetInfo.m_assetId, assetInfo.m_assetType };
AZ::Data::AssetBus::MultiHandler::BusConnect(assetInfo.m_assetId);
modifiedPresetAsset = &m_lightingPresetAssets[assetInfo.m_assetId];
}
else if (AzFramework::StringFunc::EndsWith(assetInfo.m_relativePath.c_str(), ".modelpreset.azasset"))
{
m_modelPresetAssets[assetInfo.m_assetId] = { assetInfo.m_assetId, assetInfo.m_assetType };
AZ::Data::AssetBus::MultiHandler::BusConnect(assetInfo.m_assetId);
modifiedPresetAsset = &m_modelPresetAssets[assetInfo.m_assetId];
}
// Queue a load on the changed asset
if (modifiedPresetAsset != nullptr)
{
modifiedPresetAsset->QueueLoad();
}
};
AZ::Data::AssetCatalogRequestBus::Broadcast(AZStd::move(ReloadLightingAndModelPresets));
}
void MaterialViewportComponent::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
{
OnCatalogAssetChanged(assetId);
}
void MaterialViewportComponent::OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& assetInfo)
{
if (AZ::StringFunc::EndsWith(assetInfo.m_relativePath.c_str(), ".lightingpreset.azasset"))
{
AZ::Data::AssetBus::MultiHandler::BusDisconnect(assetInfo.m_assetId);
m_lightingPresetAssets.erase(assetId);
}
if (AZ::StringFunc::EndsWith(assetInfo.m_relativePath.c_str(), ".modelpreset.azasset"))
{
AZ::Data::AssetBus::MultiHandler::BusDisconnect(assetInfo.m_assetId);
m_modelPresetAssets.erase(assetId);
}
}
}
@@ -95,6 +95,9 @@ namespace MaterialEditor
////////////////////////////////////////////////////////////////////////
// AzFramework::AssetCatalogEventBus::Handler overrides ...
void OnCatalogLoaded(const char* catalogFile) override;
void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override;
void OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) override;
void OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& assetInfo) override;
////////////////////////////////////////////////////////////////////////
AZStd::unordered_map<AZ::Data::AssetId, AZ::Data::Asset<AZ::RPI::AnyAsset>> m_lightingPresetAssets;
@@ -6,6 +6,7 @@
*
*/
#include <AzCore/Component/ComponentApplicationLifecycle.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/EditContextConstants.inl>
#include <AzCore/Serialization/SerializeContext.h>
@@ -88,14 +89,22 @@ namespace AZ
AzToolsFramework::EditorLevelNotificationBus::Handler::BusConnect();
AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler::BusConnect();
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
if (auto settingsRegistry{ AZ::SettingsRegistry::Get() }; settingsRegistry != nullptr)
{
auto LifecycleCallback = [this](AZStd::string_view, AZ::SettingsRegistryInterface::Type)
{
SetupThumbnails();
};
AZ::ComponentApplicationLifecycle::RegisterHandler(*settingsRegistry, m_criticalAssetsHandler,
AZStd::move(LifecycleCallback), "CriticalAssetsCompiled");
}
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect();
}
void EditorCommonFeaturesSystemComponent::Deactivate()
{
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusDisconnect();
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
m_criticalAssetsHandler = {};
AzToolsFramework::EditorLevelNotificationBus::Handler::BusDisconnect();
AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler::BusDisconnect();
@@ -192,13 +201,6 @@ namespace AZ
}
}
void EditorCommonFeaturesSystemComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile)
{
AZ::TickBus::QueueFunction([this](){
SetupThumbnails();
});
}
const AzToolsFramework::AssetBrowser::PreviewerFactory* EditorCommonFeaturesSystemComponent::GetPreviewerFactory(
const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const
{
@@ -28,7 +28,6 @@ namespace AZ
, public AzToolsFramework::EditorLevelNotificationBus::Handler
, public AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler
, public AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler
, public AzFramework::AssetCatalogEventBus::Handler
, public AzFramework::ApplicationLifecycleEvents::Bus::Handler
{
public:
@@ -58,9 +57,6 @@ namespace AZ
const AZ::Data::AssetId&, AZ::SliceComponent::SliceInstanceAddress&, const AzFramework::SliceInstantiationTicket&) override;
void OnSliceInstantiationFailed(const AZ::Data::AssetId&, const AzFramework::SliceInstantiationTicket&) override;
// AzFramework::AssetCatalogEventBus::Handler overrides ...
void OnCatalogLoaded(const char* catalogFile) override;
// AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler overrides...
const AzToolsFramework::AssetBrowser::PreviewerFactory* GetPreviewerFactory(
const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const override;
@@ -80,6 +76,7 @@ namespace AZ
AZStd::unique_ptr<AZ::LyIntegration::SharedThumbnailRenderer> m_thumbnailRenderer;
AZStd::unique_ptr<LyIntegration::SharedPreviewerFactory> m_previewerFactory;
AZ::SettingsRegistryInterface::NotifyEventHandler m_criticalAssetsHandler;
};
} // namespace Render
} // namespace AZ
@@ -58,7 +58,7 @@ namespace Multiplayer
{
ActivateDedicatedEditorServer();
},
"LegacySystemInterfaceCreated");
"CriticalAssetsCompiled");
}
}
}
@@ -8,6 +8,7 @@
#include <Source/NetworkEntity/NetworkSpawnableLibrary.h>
#include <AzCore/Asset/AssetManagerBus.h>
#include <AzCore/Component/ComponentApplicationLifecycle.h>
#include <AzFramework/Spawnable/Spawnable.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Interface/Interface.h>
@@ -17,12 +18,20 @@ namespace Multiplayer
NetworkSpawnableLibrary::NetworkSpawnableLibrary()
{
AZ::Interface<INetworkSpawnableLibrary>::Register(this);
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
if (auto settingsRegistry{ AZ::SettingsRegistry::Get() }; settingsRegistry != nullptr)
{
auto LifecycleCallback = [this](AZStd::string_view, AZ::SettingsRegistryInterface::Type)
{
BuildSpawnablesList();
};
AZ::ComponentApplicationLifecycle::RegisterHandler(*settingsRegistry, m_criticalAssetsHandler,
AZStd::move(LifecycleCallback), "CriticalAssetsCompiled");
}
}
NetworkSpawnableLibrary::~NetworkSpawnableLibrary()
{
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
m_criticalAssetsHandler = {};
AZ::Interface<INetworkSpawnableLibrary>::Unregister(this);
}
@@ -50,11 +59,6 @@ namespace Multiplayer
m_spawnablesReverseLookup[id] = name;
}
void NetworkSpawnableLibrary::OnCatalogLoaded([[maybe_unused]] const char* catalogFile)
{
BuildSpawnablesList();
}
AZ::Name NetworkSpawnableLibrary::GetSpawnableNameFromAssetId(AZ::Data::AssetId assetId)
{
if (assetId.IsValid())
@@ -9,14 +9,13 @@
#pragma once
#include <Multiplayer/INetworkSpawnableLibrary.h>
#include <AzFramework/Asset/AssetCatalogBus.h>
#include <AzCore/Settings/SettingsRegistry.h>
namespace Multiplayer
{
/// Implementation of the network prefab library interface.
class NetworkSpawnableLibrary final
: public INetworkSpawnableLibrary
, private AzFramework::AssetCatalogEventBus::Handler
{
public:
AZ_RTTI(NetworkSpawnableLibrary, "{65E15F33-E893-49C2-A8E2-B6A8A6EF31E0}", INetworkSpawnableLibrary);
@@ -30,11 +29,10 @@ namespace Multiplayer
AZ::Name GetSpawnableNameFromAssetId(AZ::Data::AssetId assetId) override;
AZ::Data::AssetId GetAssetIdByName(AZ::Name name) override;
/// AssetCatalogEventBus overrides.
void OnCatalogLoaded(const char* catalogFile) override;
private:
AZStd::unordered_map<AZ::Name, AZ::Data::AssetId> m_spawnables;
AZStd::unordered_map<AZ::Data::AssetId, AZ::Name> m_spawnablesReverseLookup;
AZ::SettingsRegistryInterface::NotifyEventHandler m_criticalAssetsHandler;
};
}
@@ -103,15 +103,13 @@ namespace PhysX
if (auto* settingsRegistry = AZ::SettingsRegistry::Get();
settingsRegistry != nullptr)
{
// Automatically register the event if it's not registered, because
// this system is initialized before the settings registry has loaded the event list.
AZ::ComponentApplicationLifecycle::RegisterHandler(
*settingsRegistry, m_componentApplicationLifecycleHandler,
[this]([[maybe_unused]] AZStd::string_view path, [[maybe_unused]] AZ::SettingsRegistryInterface::Type type)
{
InitializeMaterialLibrary();
},
"LegacySystemInterfaceCreated"); // LegacySystemInterfaceCreated is signaled after critical assets have been processed
"CriticalAssetsCompiled");
}
m_state = State::Initialized;
+2 -1
View File
@@ -23,7 +23,8 @@
"GemsUnloaded": {},
"FileIOAvailable": {},
"FileIOUnavailable": {},
"LegacySystemInterfaceCreated": {}
"LegacySystemInterfaceCreated": {},
"CriticalAssetsCompiled": {}
}
}
}