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.
o3de/Gems/LmbrCentral/Code/Source/LmbrCentral.cpp

442 lines
20 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 "LmbrCentral.h"
#include <AzCore/Component/Entity.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/std/containers/list.h>
#include <AzCore/Memory/AllocatorScope.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/Asset/AssetCatalogBus.h>
#include <AzFramework/Metrics/MetricsPlainTextNameRegistration.h>
// Component descriptors
#include "Audio/AudioAreaEnvironmentComponent.h"
#include "Audio/AudioEnvironmentComponent.h"
#include "Audio/AudioListenerComponent.h"
#include "Audio/AudioMultiPositionComponent.h"
#include "Audio/AudioPreloadComponent.h"
#include "Audio/AudioProxyComponent.h"
#include "Audio/AudioRtpcComponent.h"
#include "Audio/AudioSwitchComponent.h"
#include "Audio/AudioSystemComponent.h"
#include "Audio/AudioTriggerComponent.h"
#include "Bundling/BundlingSystemComponent.h"
#include "Ai/NavigationComponent.h"
#include "Scripting/TagComponent.h"
#include "Scripting/SimpleStateComponent.h"
#include "Scripting/SpawnerComponent.h"
#include "Scripting/LookAtComponent.h"
#include "Scripting/RandomTimedSpawnerComponent.h"
#include "Ai/NavigationSystemComponent.h"
#include "Geometry/GeometrySystemComponent.h"
#include <Asset/AssetSystemDebugComponent.h>
// Other
#include "Unhandled/Other/AudioAssetTypeInfo.h"
#include "Unhandled/Other/CharacterPhysicsAssetTypeInfo.h"
#include "Unhandled/Other/GroupAssetTypeInfo.h"
#include "Unhandled/Other/PrefabsLibraryAssetTypeInfo.h"
#include "Unhandled/Other/GameTokenAssetTypeInfo.h"
#include "Unhandled/Other/EntityPrototypeLibraryAssetTypeInfo.h"
// Texture
#include "Unhandled/Texture/SubstanceAssetTypeInfo.h"
#include "Unhandled/Texture/TextureAssetTypeInfo.h"
// Hidden
#include "Unhandled/Hidden/TextureMipmapAssetTypeInfo.h"
//UI
#include <Unhandled/UI/EntityIconAssetTypeInfo.h>
#include "Unhandled/UI/FontAssetTypeInfo.h"
#include "Unhandled/UI/UICanvasAssetTypeInfo.h"
// Asset types
#include <AzCore/Slice/SliceAsset.h>
#include <LmbrCentral/Rendering/MaterialAsset.h>
#include <LmbrCentral/Rendering/MeshAsset.h>
#include <LmbrCentral/Rendering/MaterialHandle.h>
// Scriptable Ebus Registration
#include "Events/ReflectScriptableEvents.h"
// Shape components
#include "Shape/SphereShapeComponent.h"
#include "Shape/DiskShapeComponent.h"
#include "Shape/AxisAlignedBoxShapeComponent.h"
#include "Shape/BoxShapeComponent.h"
#include "Shape/QuadShapeComponent.h"
#include "Shape/CylinderShapeComponent.h"
#include "Shape/CapsuleShapeComponent.h"
#include "Shape/TubeShapeComponent.h"
#include "Shape/CompoundShapeComponent.h"
#include "Shape/SplineComponent.h"
#include "Shape/PolygonPrismShapeComponent.h"
namespace LmbrCentral
{
using LmbrCentralAllocatorScope = AZ::AllocatorScope<AZ::LegacyAllocator>;
// This component boots the required allocators for LmbrCentral everywhere but AssetBuilders
class LmbrCentralAllocatorComponent
: public AZ::Component
, protected LmbrCentralAllocatorScope
{
public:
AZ_COMPONENT(LmbrCentralAllocatorComponent, "{B0512A75-AC4A-423A-BB55-C3355C0B186A}", AZ::Component);
LmbrCentralAllocatorComponent() = default;
~LmbrCentralAllocatorComponent() override = default;
void Activate() override
{
LmbrCentralAllocatorScope::ActivateAllocators();
}
void Deactivate() override
{
LmbrCentralAllocatorScope::DeactivateAllocators();
}
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("MemoryAllocators", 0xd59acbcc));
}
static void Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<LmbrCentralAllocatorComponent, AZ::Component>()->Version(1);
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<LmbrCentralAllocatorComponent>(
"LmbrCentral Allocator Component", "Manages initialization of memory allocators required by LmbrCentral")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "Engine")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
;
}
}
}
};
// This component is opted in to AssetBuilders
class LmbrCentralAssetBuilderAllocatorComponent
: public LmbrCentralAllocatorComponent
{
public:
AZ_COMPONENT(LmbrCentralAssetBuilderAllocatorComponent, "{030B63DE-7DC1-4E08-9AAF-1D089D3D0C46}", LmbrCentralAllocatorComponent);
LmbrCentralAssetBuilderAllocatorComponent() = default;
~LmbrCentralAssetBuilderAllocatorComponent() override = default;
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("MemoryAllocators", 0xd59acbcc));
}
static void Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<LmbrCentralAssetBuilderAllocatorComponent, LmbrCentralAllocatorComponent>()->Version(1)
->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector<AZ::Crc32>({ AZ_CRC("AssetBuilder", 0xc739c7d7) }));
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<LmbrCentralAssetBuilderAllocatorComponent>(
"LmbrCentral Asset Builder Allocator Component", "Manages initialization of memory allocators required by LmbrCentral during asset building")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "Engine")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
;
}
}
}
};
////////////////////////////////////////////////////////////////////////////
// LmbrCentral::LmbrCentralModule
////////////////////////////////////////////////////////////////////////////
//! Create ComponentDescriptors and add them to the list.
//! The descriptors will be registered at the appropriate time.
//! The descriptors will be destroyed (and thus unregistered) at the appropriate time.
LmbrCentralModule::LmbrCentralModule()
: AZ::Module()
{
m_descriptors.insert(m_descriptors.end(), {
AudioAreaEnvironmentComponent::CreateDescriptor(),
AudioEnvironmentComponent::CreateDescriptor(),
AudioListenerComponent::CreateDescriptor(),
AudioMultiPositionComponent::CreateDescriptor(),
AudioPreloadComponent::CreateDescriptor(),
AudioProxyComponent::CreateDescriptor(),
AudioRtpcComponent::CreateDescriptor(),
AudioSwitchComponent::CreateDescriptor(),
AudioSystemComponent::CreateDescriptor(),
AudioTriggerComponent::CreateDescriptor(),
BundlingSystemComponent::CreateDescriptor(),
LmbrCentralAllocatorComponent::CreateDescriptor(),
LmbrCentralAssetBuilderAllocatorComponent::CreateDescriptor(),
LmbrCentralSystemComponent::CreateDescriptor(),
NavigationComponent::CreateDescriptor(),
SimpleStateComponent::CreateDescriptor(),
SpawnerComponent::CreateDescriptor(),
LookAtComponent::CreateDescriptor(),
TagComponent::CreateDescriptor(),
SphereShapeComponent::CreateDescriptor(),
DiskShapeComponent::CreateDescriptor(),
BoxShapeComponent::CreateDescriptor(),
AxisAlignedBoxShapeComponent::CreateDescriptor(),
QuadShapeComponent::CreateDescriptor(),
CylinderShapeComponent::CreateDescriptor(),
CapsuleShapeComponent::CreateDescriptor(),
TubeShapeComponent::CreateDescriptor(),
CompoundShapeComponent::CreateDescriptor(),
SplineComponent::CreateDescriptor(),
PolygonPrismShapeComponent::CreateDescriptor(),
NavigationSystemComponent::CreateDescriptor(),
GeometrySystemComponent::CreateDescriptor(),
RandomTimedSpawnerComponent::CreateDescriptor(),
SphereShapeDebugDisplayComponent::CreateDescriptor(),
DiskShapeDebugDisplayComponent::CreateDescriptor(),
BoxShapeDebugDisplayComponent::CreateDescriptor(),
AxisAlignedBoxShapeDebugDisplayComponent::CreateDescriptor(),
QuadShapeDebugDisplayComponent::CreateDescriptor(),
CapsuleShapeDebugDisplayComponent::CreateDescriptor(),
CylinderShapeDebugDisplayComponent::CreateDescriptor(),
PolygonPrismShapeDebugDisplayComponent::CreateDescriptor(),
TubeShapeDebugDisplayComponent::CreateDescriptor(),
AssetSystemDebugComponent::CreateDescriptor(),
#if AZ_LOADSCREENCOMPONENT_ENABLED
LoadScreenComponent::CreateDescriptor(),
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
});
// This is an internal Amazon gem, so register it's components for metrics tracking, otherwise the name of the component won't get sent back.
// IF YOU ARE A THIRDPARTY WRITING A GEM, DO NOT REGISTER YOUR COMPONENTS WITH EditorMetricsComponentRegistrationBus
AZStd::vector<AZ::Uuid> typeIds;
typeIds.reserve(m_descriptors.size());
for (AZ::ComponentDescriptor* descriptor : m_descriptors)
{
typeIds.emplace_back(descriptor->GetUuid());
}
EBUS_EVENT(AzFramework::MetricsPlainTextNameRegistrationBus, RegisterForNameSending, typeIds);
}
//! Request system components on the system entity.
//! These components' memory is owned by the system entity.
AZ::ComponentTypeList LmbrCentralModule::GetRequiredSystemComponents() const
{
return {
azrtti_typeid<LmbrCentralAllocatorComponent>(),
azrtti_typeid<LmbrCentralAssetBuilderAllocatorComponent>(),
azrtti_typeid<LmbrCentralSystemComponent>(),
azrtti_typeid<NavigationSystemComponent>(),
azrtti_typeid<GeometrySystemComponent>(),
azrtti_typeid<AudioSystemComponent>(),
azrtti_typeid<BundlingSystemComponent>(),
azrtti_typeid<AssetSystemDebugComponent>(),
#if AZ_LOADSCREENCOMPONENT_ENABLED
azrtti_typeid<LoadScreenComponent>(),
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
};
}
////////////////////////////////////////////////////////////////////////////
// LmbrCentralSystemComponent
void LmbrCentralSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
// Allow loading of Material and Texture Assets which explicitly specialized AzTypeInfo instead of using
// the AZ_RTTI Uuid from SimpleAssetReference<T>
serializeContext->ClassDeprecate("SimpleAssetReference_MaterialAsset", "{B7B8ECC7-FF89-4A76-A50E-4C6CA2B6E6B4}",
[](AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& rootElement)
{
AZStd::vector<AZ::SerializeContext::DataElementNode> childNodeElements;
for (int index = 0; index < rootElement.GetNumSubElements(); ++index)
{
childNodeElements.push_back(rootElement.GetSubElement(index));
}
// Convert the rootElement now, the existing child DataElmentNodes are now removed
rootElement.Convert<AzFramework::SimpleAssetReference<MaterialAsset>>(context);
for (AZ::SerializeContext::DataElementNode& childNodeElement : childNodeElements)
{
rootElement.AddElement(AZStd::move(childNodeElement));
}
return true;
});
serializeContext->ClassDeprecate("SimpleAssetReference_TextureAsset", "{68E92460-5C0C-4031-9620-6F1A08763243}",
[](AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& rootElement)
{
AZStd::vector<AZ::SerializeContext::DataElementNode> childNodeElements;
for (int index = 0; index < rootElement.GetNumSubElements(); ++index)
{
childNodeElements.push_back(rootElement.GetSubElement(index));
}
// Convert the rootElement now, the existing child DataElmentNodes are now removed
rootElement.Convert<AzFramework::SimpleAssetReference<TextureAsset>>(context);
for (AZ::SerializeContext::DataElementNode& childNodeElement : childNodeElements)
{
rootElement.AddElement(AZStd::move(childNodeElement));
}
return true;
});
AzFramework::SimpleAssetReference<MaterialAsset>::Register(*serializeContext);
AzFramework::SimpleAssetReference<TextureAsset>::Register(*serializeContext);
serializeContext->Class<LmbrCentralSystemComponent, AZ::Component>()
->Version(1)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<LmbrCentralSystemComponent>(
"LmbrCentral", "Coordinates initialization of systems within LmbrCentral")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "Game")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
;
}
}
ReflectScriptableEvents::Reflect(context);
}
void LmbrCentralSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("LmbrCentralService", 0xc3a02410));
}
void LmbrCentralSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("LmbrCentralService", 0xc3a02410));
}
void LmbrCentralSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC("AssetDatabaseService", 0x3abf5601));
}
void LmbrCentralSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
dependent.push_back(AZ_CRC("MemoryAllocators", 0xd59acbcc));
dependent.push_back(AZ_CRC("AssetCatalogService", 0xc68ffc57));
}
void LmbrCentralSystemComponent::Activate()
{
if (!AZ::AllocatorInstance<AZ::LegacyAllocator>::IsReady())
{
AZ::AllocatorInstance<AZ::LegacyAllocator>::Create();
m_allocatorShutdowns.push_back([]() { AZ::AllocatorInstance<AZ::LegacyAllocator>::Destroy(); });
}
// Register asset handlers. Requires "AssetDatabaseService"
AZ_Assert(AZ::Data::AssetManager::IsReady(), "Asset manager isn't ready!");
// Add asset types and extensions to AssetCatalog. Uses "AssetCatalogService".
if (auto assetCatalog = AZ::Data::AssetCatalogRequestBus::FindFirstHandler(); assetCatalog)
{
assetCatalog->EnableCatalogForAsset(AZ::AzTypeInfo<MeshAsset>::Uuid());
assetCatalog->EnableCatalogForAsset(AZ::AzTypeInfo<CharacterDefinitionAsset>::Uuid());
assetCatalog->AddExtension("cgf");
assetCatalog->AddExtension("chr");
assetCatalog->AddExtension("cdf");
assetCatalog->AddExtension("dds");
assetCatalog->AddExtension("caf");
assetCatalog->AddExtension("xml");
assetCatalog->AddExtension("sprite");
assetCatalog->AddExtension("cax");
}
AZ::Data::AssetManagerNotificationBus::Handler::BusConnect();
// Other
auto audioAssetTypeInfo = aznew AudioAssetTypeInfo();
audioAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(audioAssetTypeInfo);
auto characterPhysicsAssetTypeInfo = aznew CharacterPhysicsAssetTypeInfo();
characterPhysicsAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(characterPhysicsAssetTypeInfo);
auto groupAssetTypeInfo = aznew GroupAssetTypeInfo();
groupAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(groupAssetTypeInfo);
auto prefabsLibraryAssetTypeInfo = aznew PrefabsLibraryAssetTypeInfo();
prefabsLibraryAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(prefabsLibraryAssetTypeInfo);
auto entityPrototypeAssetTypeInfo = aznew EntityPrototypeLibraryAssetTypeInfo();
entityPrototypeAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(entityPrototypeAssetTypeInfo);
auto gameTokenAssetTypeInfo = aznew GameTokenAssetTypeInfo();
gameTokenAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(gameTokenAssetTypeInfo);
// Texture
auto substanceAssetTypeInfo = aznew SubstanceAssetTypeInfo();
substanceAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(substanceAssetTypeInfo);
auto textureAssetTypeInfo = aznew TextureAssetTypeInfo();
textureAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(textureAssetTypeInfo);
// Hidden
auto textureMipmapAssetTypeInfo = aznew TextureMipmapAssetTypeInfo();
textureMipmapAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(textureMipmapAssetTypeInfo);
// UI
auto fontAssetTypeInfo = aznew FontAssetTypeInfo();
fontAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(fontAssetTypeInfo);
auto uiCanvasAssetTypeInfo = aznew UICanvasAssetTypeInfo();
uiCanvasAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(uiCanvasAssetTypeInfo);
auto entityIconAssetTypeInfo = aznew EntityIconAssetTypeInfo();
entityIconAssetTypeInfo->Register();
m_unhandledAssetInfo.emplace_back(entityIconAssetTypeInfo);
}
void LmbrCentralSystemComponent::Deactivate()
{
// AssetTypeInfo's destructor calls Unregister()
m_unhandledAssetInfo.clear();
AZ::Data::AssetManagerNotificationBus::Handler::BusDisconnect();
// AssetHandler's destructor calls Unregister()
m_assetHandlers.clear();
for (auto allocatorIt = m_allocatorShutdowns.rbegin(); allocatorIt != m_allocatorShutdowns.rend(); ++allocatorIt)
{
(*allocatorIt)();
}
m_allocatorShutdowns.clear();
}
} // namespace LmbrCentral
#if !defined(LMBR_CENTRAL_EDITOR)
AZ_DECLARE_MODULE_CLASS(Gem_LmbrCentral, LmbrCentral::LmbrCentralModule)
#endif