Files
o3de/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/GenericComponentWrapper.cpp
T
Esteban Papp 1f9b284de2 Merge branch 'development' into cmake/SPEC-7179
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>

# Conflicts:
#	Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin_precompiled.h
#	Code/Editor/Plugins/EditorCommon/EditorCommon_precompiled.h
#	Code/Editor/Plugins/EditorCommon/stdafx.cpp
#	Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h
#	Code/Editor/Plugins/PerforcePlugin/PerforcePlugin_precompiled.h
#	Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsTool_precompiled.h
#	Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFramework_precompiled.h
#	Code/Tools/AssetProcessor/native/precompiled.h
#	Code/Tools/Standalone/StandaloneTools_precompiled.h
#	Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer_precompiled.h
#	Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageProcessing_precompiled.h
#	Gems/Atom/RHI/DX12/Code/Source/RHI/Atom_RHI_DX12_precompiled.h
#	Gems/Atom/RHI/Metal/Code/Include/Platform/Mac/Atom_RHI_Metal_precompiled_Platform.h
#	Gems/Atom/RHI/Metal/Code/Include/Platform/iOS/Atom_RHI_Metal_precompiled_Platform.h
#	Gems/Atom/RHI/Metal/Code/Source/Atom_RHI_Metal_precompiled.h
#	Gems/Atom/RHI/Metal/Code/atom_rhi_metal_common_files.cmake
#	Gems/Atom/RHI/Null/Code/Source/Atom_RHI_Null_precompiled.h
#	Gems/Atom/RHI/Null/Code/atom_rhi_null_common_files.cmake
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Android/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Linux/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Mac/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Windows/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Source/Atom_RHI_Vulkan_precompiled.h
#	Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp
#	Gems/Atom/RHI/Vulkan/Code/atom_rhi_vulkan_common_files.cmake
#	Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont_precompiled.h
#	Gems/Blast/Code/Source/StdAfx.cpp
#	Gems/Camera/Code/Source/Camera_precompiled.h
#	Gems/EMotionFX/Code/Source/EMotionFX_precompiled.h
#	Gems/FastNoise/Code/Source/FastNoise_precompiled.h
#	Gems/Gestures/Code/Source/Gestures_precompiled.h
#	Gems/GradientSignal/Code/Source/GradientSignal_precompiled.h
#	Gems/GraphCanvas/Code/precompiled.h
#	Gems/ImGui/Code/Source/ImGui_precompiled.h
#	Gems/InAppPurchases/Code/Source/InAppPurchases_precompiled.h
#	Gems/LmbrCentral/Code/Source/LmbrCentral_precompiled.h
#	Gems/LmbrCentral/Code/Tests/ShapeGeometryUtilTest.cpp
#	Gems/LyShine/Code/Editor/UiCanvasEditor_precompiled.h
#	Gems/LyShine/Code/Source/Animation/LyShine_precompiled.h
#	Gems/LyShine/Code/Source/LyShine_precompiled.h
#	Gems/LyShineExamples/Code/Source/LyShineExamples_precompiled.h
#	Gems/Maestro/Code/Source/Cinematics/Maestro_precompiled.h
#	Gems/Maestro/Code/Source/Maestro_precompiled.h
#	Gems/MessagePopup/Code/Source/MessagePopup_precompiled.h
#	Gems/Metastream/Code/Source/Metastream_precompiled.h
#	Gems/Microphone/Code/Source/Microphone_precompiled.h
#	Gems/Multiplayer/Code/Source/Multiplayer_precompiled.h
#	Gems/PhysX/Code/NumericalMethods/Source/NumericalMethods_precompiled.h
#	Gems/PhysX/Code/Source/PhysXUnsupported_precompiled.h
#	Gems/PhysX/Code/Source/PhysX_precompiled.h
#	Gems/PhysX/Code/physx_unsupported_files.cmake
#	Gems/PhysXDebug/Code/Source/PhysXDebugUnsupported_precompiled.h
#	Gems/PhysXDebug/Code/Source/PhysXDebug_precompiled.h
#	Gems/ScriptCanvas/Code/Editor/precompiled.h
#	Gems/ScriptCanvas/Code/Source/precompiled.h
#	Gems/ScriptCanvasDeveloper/Code/Source/precompiled.h
#	Gems/ScriptCanvasPhysics/Code/Source/ScriptCanvasPhysics_precompiled.h
#	Gems/ScriptEvents/Code/Source/precompiled.h
#	Gems/ScriptEvents/Code/Tests/Editor/EditorTests.cpp
#	Gems/ScriptedEntityTweener/Code/Source/ScriptedEntityTweener_precompiled.h
#	Gems/SliceFavorites/Code/Source/SliceFavorites_precompiled.h
#	Gems/StartingPointCamera/Code/Source/StartingPointCamera_precompiled.h
#	Gems/StartingPointInput/Code/Source/StartingPointInput_precompiled.h
#	Gems/StartingPointMovement/Code/Source/StartingPointMovement_precompiled.h
#	Gems/SurfaceData/Code/Source/SurfaceData_precompiled.h
#	Gems/TextureAtlas/Code/Source/TextureAtlas_precompiled.h
#	Gems/TickBusOrderViewer/Code/Source/TickBusOrderViewer_precompiled.h
#	Gems/Twitch/Code/Source/Twitch_precompiled.h
#	Gems/VirtualGamepad/Code/Source/VirtualGamepad_precompiled.h
#	Gems/WhiteBox/Code/Source/WhiteBoxUnsupported_precompiled.h
#	Gems/WhiteBox/Code/Source/WhiteBox_precompiled.h
2021-07-16 15:42:37 -07:00

374 lines
14 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 <AzCore/Serialization/EditContext.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Component/ComponentExport.h>
#include <AzCore/Slice/SliceComponent.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzFramework/Components/EditorEntityEvents.h>
#include <AzToolsFramework/ToolsComponents/GenericComponentWrapper.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
namespace AzToolsFramework
{
namespace Components
{
/**
* Custom export callback for GenericComponentWrapper, invoked by the slice compiler.
* The Wrapper component simply exports the inner template, which is the runtime/non-editor component.
*/
AZ::ExportedComponent ExportTemplateComponent(AZ::Component* thisComponent, const AZ::PlatformTagSet& /*platformTags*/)
{
GenericComponentWrapper* wrapper = static_cast<GenericComponentWrapper*>(thisComponent);
return AZ::ExportedComponent(wrapper->GetTemplate(), false);
}
////////////////////////////////////////////////////////////////////////
// GenericComponentWrapper
////////////////////////////////////////////////////////////////////////
void GenericComponentWrapper::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<GenericComponentWrapper, EditorComponentBase>()
->Field("m_template", &GenericComponentWrapper::m_template);
AZ::EditContext* editContext = serializeContext->GetEditContext();
if (editContext)
{
editContext->Class<GenericComponentWrapper>("GenericComponentWrapper", "This should be hidden!")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &GenericComponentWrapper::GetDisplayName)
->Attribute(AZ::Edit::Attributes::DescriptionTextOverride, &GenericComponentWrapper::GetDisplayDescription)
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::RuntimeExportCallback, &ExportTemplateComponent)
->DataElement("", &GenericComponentWrapper::m_template, "m_template", "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ_CRC("PropertyVisibility_ShowChildrenOnly", 0xef428f20));
}
}
}
GenericComponentWrapper::GenericComponentWrapper()
{
}
GenericComponentWrapper::GenericComponentWrapper(const AZ::SerializeContext::ClassData* templateClassData)
{
EBUS_EVENT_ID_RESULT(m_template, templateClassData->m_typeId, AZ::ComponentDescriptorBus, CreateComponent);
}
GenericComponentWrapper::GenericComponentWrapper(AZ::Component* templateClassInstance)
{
if (templateClassInstance)
{
if (templateClassInstance->GetEntity())
{
AZ_Error("GenericComponentWrapper", false, "Component must be detached from entity before placing inside GenericComponentWrapper.");
}
else
{
m_id = templateClassInstance->GetId();
m_template = templateClassInstance;
}
}
}
GenericComponentWrapper::~GenericComponentWrapper()
{
if (m_template)
{
delete m_template;
}
}
GenericComponentWrapper::GenericComponentWrapper(const GenericComponentWrapper& RHS)
: m_displayName(RHS.m_displayName)
, m_displayDescription(RHS.m_displayDescription)
{
if (GetEntity())
{
AZ_Assert(GetEntity()->GetState() <= AZ::Entity::State::Init, "Entity should not be activated when copying components");
}
AZ::SerializeContext* context = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
m_template = context->CloneObject<AZ::Component>(RHS.m_template);
m_templateEvents = azrtti_cast<AzFramework::EditorEntityEvents*>(m_template);
}
GenericComponentWrapper::GenericComponentWrapper(GenericComponentWrapper&& RHS)
: m_displayName(AZStd::move(RHS.m_displayName))
, m_displayDescription(AZStd::move(RHS.m_displayDescription))
{
if (GetEntity())
{
AZ_Assert(GetEntity()->GetState() <= AZ::Entity::State::Init, "Entity should not be activated when copying components");
}
m_template = AZStd::move(RHS.m_template);
RHS.m_template = nullptr;
m_templateEvents = azrtti_cast<AzFramework::EditorEntityEvents*>(m_template);
}
GenericComponentWrapper& GenericComponentWrapper::operator=(const GenericComponentWrapper& RHS)
{
if (GetEntity())
{
AZ_Assert(GetEntity()->GetState() <= AZ::Entity::State::Init, "Entity should not be activated when copying components");
}
AZ::SerializeContext* context = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
m_template = context->CloneObject<AZ::Component>(RHS.m_template);
m_templateEvents = azrtti_cast<AzFramework::EditorEntityEvents*>(m_template);
m_displayName = RHS.m_displayName;
m_displayDescription = RHS.m_displayDescription;
return *this;
}
GenericComponentWrapper& GenericComponentWrapper::operator=(GenericComponentWrapper&& RHS)
{
if (GetEntity())
{
AZ_Assert(GetEntity()->GetState() <= AZ::Entity::State::Init, "Entity should not be activated when copying components");
}
m_template = AZStd::move(RHS.m_template);
RHS.m_template = nullptr;
m_templateEvents = azrtti_cast<AzFramework::EditorEntityEvents*>(m_template);
m_displayName = AZStd::move(RHS.m_displayName);
m_displayDescription = AZStd::move(RHS.m_displayDescription);
return *this;
}
const char* GenericComponentWrapper::GetDisplayName()
{
if (m_displayName.empty())
{
if (m_template)
{
m_displayName = GetFriendlyComponentName(m_template);
}
}
return m_displayName.c_str();
}
const char* GenericComponentWrapper::GetDisplayDescription()
{
if (m_displayDescription.empty())
{
if (m_template)
{
m_displayDescription = GetFriendlyComponentDescription(m_template);
}
}
return m_displayDescription.c_str();
}
void GenericComponentWrapper::Init()
{
EditorComponentBase::Init();
if (m_template)
{
m_displayName = GetFriendlyComponentName(m_template);
m_displayDescription = GetFriendlyComponentDescription(m_template);
if (m_displayDescription.empty())
{
m_displayDescription = m_displayName;
}
m_templateEvents = azrtti_cast<AzFramework::EditorEntityEvents*>(m_template);
if (m_templateEvents)
{
m_templateEvents->EditorInit(GetEntityId());
}
}
}
void GenericComponentWrapper::Activate()
{
EditorComponentBase::Activate();
if (m_templateEvents)
{
m_templateEvents->EditorActivate(GetEntityId());
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(GetEntityId());
}
}
void GenericComponentWrapper::Deactivate()
{
EditorComponentBase::Deactivate();
if (m_templateEvents)
{
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
m_templateEvents->EditorDeactivate(GetEntityId());
}
}
const AZ::TypeId& GenericComponentWrapper::GetUnderlyingComponentType() const
{
if (m_template)
{
return m_template->RTTI_GetType();
}
return RTTI_GetType();
}
void GenericComponentWrapper::BuildGameEntity(AZ::Entity* gameEntity)
{
if (m_template)
{
AZ::SerializeContext* context = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
if (!context)
{
AZ_Error("GenericComponentWrapper", false, "Can't get serialize context from component application.");
return;
}
gameEntity->AddComponent(context->CloneObject(m_template));
}
}
AZ::ComponentValidationResult GenericComponentWrapper::ValidateComponentRequirements(
const AZ::ImmutableEntityVector& sliceEntities, const AZStd::unordered_set<AZ::Crc32>& platformTags) const
{
AZ::ComponentValidationResult baseClassResult = EditorComponentBase::ValidateComponentRequirements(sliceEntities, platformTags);
if (!baseClassResult.IsSuccess())
{
return baseClassResult;
}
if (m_template)
{
return m_template->ValidateComponentRequirements(sliceEntities, platformTags);
}
return AZ::Success();
}
void GenericComponentWrapper::DisplayEntityViewport(
const AzFramework::ViewportInfo& /*viewportInfo*/,
AzFramework::DebugDisplayRequests& debugDisplay)
{
if (m_templateEvents)
{
m_templateEvents->EditorDisplay(GetEntityId(), debugDisplay, GetWorldTM());
}
}
void GenericComponentWrapper::SetPrimaryAsset(const AZ::Data::AssetId& assetId)
{
if (m_templateEvents)
{
m_templateEvents->EditorSetPrimaryAsset(assetId);
}
}
AZ::Component* GenericComponentWrapper::ReleaseTemplate()
{
AZ::Component* component = m_template;
m_template = nullptr;
return component;
}
class GenericComponentWrapperDescriptor
: public AZ::ComponentDescriptorHelper<GenericComponentWrapper>
{
public:
AZ_CLASS_ALLOCATOR(GenericComponentWrapperDescriptor, AZ::SystemAllocator, 0);
AZ_TYPE_INFO(GenericComponentWrapperDescriptor, "{3326B218-282B-4985-AEDE-39A77D48AD57}");
AZ::ComponentDescriptor* GetTemplateDescriptor(const AZ::Component* instance) const
{
AZ::ComponentDescriptor* templateDescriptor = nullptr;
const GenericComponentWrapper* wrapper = azrtti_cast<const GenericComponentWrapper*>(instance);
if (wrapper && wrapper->GetTemplate())
{
EBUS_EVENT_ID_RESULT(
templateDescriptor, wrapper->GetTemplate()->RTTI_GetType(),
AZ::ComponentDescriptorBus, GetDescriptor);
}
return templateDescriptor;
}
void Reflect(AZ::ReflectContext* reflection) const override
{
GenericComponentWrapper::Reflect(reflection);
}
void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided, const AZ::Component* instance) const override
{
const AZ::ComponentDescriptor* templateDescriptor = GetTemplateDescriptor(instance);
if (templateDescriptor)
{
templateDescriptor->GetProvidedServices(provided, instance);
}
}
void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent, const AZ::Component* instance) const override
{
const AZ::ComponentDescriptor* templateDescriptor = GetTemplateDescriptor(instance);
if (templateDescriptor)
{
templateDescriptor->GetDependentServices(dependent, instance);
}
}
void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required, const AZ::Component* instance) const override
{
const AZ::ComponentDescriptor* templateDescriptor = GetTemplateDescriptor(instance);
if (templateDescriptor)
{
templateDescriptor->GetRequiredServices(required, instance);
}
}
void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible, const AZ::Component* instance) const override
{
const AZ::ComponentDescriptor* templateDescriptor = GetTemplateDescriptor(instance);
if (templateDescriptor)
{
templateDescriptor->GetIncompatibleServices(incompatible, instance);
}
}
};
AZ::ComponentDescriptor* GenericComponentWrapper::CreateDescriptor()
{
AZ::ComponentDescriptor* descriptor = nullptr;
EBUS_EVENT_ID_RESULT(descriptor, GenericComponentWrapper::RTTI_Type(), AZ::ComponentDescriptorBus, GetDescriptor);
return descriptor ? descriptor : aznew GenericComponentWrapperDescriptor();
}
} // namespace Components
const AZ::Uuid& GetUnderlyingComponentType(const AZ::Component& component)
{
return component.GetUnderlyingComponentType();
}
} // namespace AzToolsFramework