From 4205a69106b0be35341410c18e67b5b6f3e23bc9 Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Thu, 27 May 2021 09:34:52 +0100 Subject: [PATCH] Allow ComponentAdapter (and related types) to work with EntityComponentIdPairs as well as EntityIds (#920) * provide the ability for component adapters to support multiple components per entity * add missing explicit keywords * updates following review feedback - update how template logic works * small updats (fix typo, remove redundant includes) * add missing this-> * naming change, common -> controller * add [[maybe_unused]] --- .../AzFramework/Components/ComponentAdapter.h | 29 ++++---- .../Components/ComponentAdapter.inl | 27 ++++---- .../Components/ComponentAdapterHelpers.h | 34 +++++++-- .../ToolsComponents/EditorComponentAdapter.h | 39 +++++------ .../EditorComponentAdapter.inl | 69 +++++++++++-------- .../Utils/EditorRenderComponentAdapter.h | 30 ++++---- .../Utils/EditorRenderComponentAdapter.inl | 56 +++++++-------- 7 files changed, 159 insertions(+), 125 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.h b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.h index 682e886061..ee8b79bf06 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.h +++ b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.h @@ -1,22 +1,22 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once #include #include -#include #include #include +#include namespace AzFramework { @@ -64,15 +64,13 @@ namespace AzFramework the EditContext. TController can friend itself to the editor component to make this work if required. */ template - class ComponentAdapter - : public AZ::Component + class ComponentAdapter : public AZ::Component { public: - AZ_RTTI((ComponentAdapter, "{644A9187-4FDB-42C1-9D59-DD75304B551A}", TController, TConfiguration), AZ::Component); ComponentAdapter() = default; - ComponentAdapter(const TConfiguration& configuration); + explicit ComponentAdapter(const TConfiguration& configuration); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services); static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services); @@ -85,7 +83,6 @@ namespace AzFramework void Deactivate() override; protected: - static void Reflect(AZ::ReflectContext* context); // AZ::Component overrides ... diff --git a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.inl b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.inl index a1b0826193..5c36ff0bf7 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.inl +++ b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.inl @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include @@ -32,10 +32,12 @@ namespace AzFramework if (auto serializeContext = azrtti_cast(context)) { + // clang-format off serializeContext->Class() ->Version(1) ->Field("Controller", &ComponentAdapter::m_controller) ; + // clang-format on } } @@ -66,9 +68,6 @@ namespace AzFramework GetDependentServicesHelper(services, typename AZ::HasComponentDependentServices::type()); } - ////////////////////////////////////////////////////////////////////////// - // AZ::Component interface implementation - template void ComponentAdapter::Init() { @@ -78,7 +77,7 @@ namespace AzFramework template void ComponentAdapter::Activate() { - m_controller.Activate(GetEntityId()); + ComponentActivateHelper::Activate(m_controller, AZ::EntityComponentIdPair(GetEntityId(), GetId())); } template diff --git a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapterHelpers.h b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapterHelpers.h index 158ee95f39..f0ef262a71 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapterHelpers.h +++ b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapterHelpers.h @@ -13,6 +13,7 @@ #pragma once #include +#include namespace AzFramework { @@ -27,18 +28,43 @@ namespace AzFramework template struct ComponentInitHelper { - static void Init(T& common) + static void Init([[maybe_unused]] T& controller) { - AZ_UNUSED(common); } }; template struct ComponentInitHelper().Init())>> { - static void Init(T& common) + static void Init(T& controller) { - common.Init(); + controller.Init(); + } + }; + + template + struct ComponentActivateHelper + { + static void Activate([[maybe_unused]] T& controller, [[maybe_unused]] const AZ::EntityComponentIdPair& entityComponentIdPair) + { + } + }; + + template + struct ComponentActivateHelper().Activate(AZ::EntityId()))>> + { + static void Activate(T& controller, const AZ::EntityComponentIdPair& entityComponentIdPair) + { + controller.Activate(entityComponentIdPair.GetEntityId()); + } + }; + + template + struct ComponentActivateHelper().Activate(AZ::EntityComponentIdPair()))>> + { + static void Activate(T& controller, const AZ::EntityComponentIdPair& entityComponentIdPair) + { + controller.Activate(entityComponentIdPair); } }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentAdapter.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentAdapter.h index 6950717499..0ca5853adc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentAdapter.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentAdapter.h @@ -1,22 +1,22 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once -#include -#include -#include #include #include +#include +#include +#include namespace AzToolsFramework { @@ -31,7 +31,7 @@ namespace AzToolsFramework To use the EditorComponentAdapter, 3 classes are required: - a class that implements the functions required for TController (see below) - a configuration struct/class which extends AZ::ComponentConfig - - A runtime component that will be generated by the editor comoinent on export + - A runtime component that will be generated by the editor component on export The concrete component extends the adapter and implements behavior which is unique to the component. @@ -64,15 +64,15 @@ namespace AzToolsFramework the EditContext. TController can friend itself to the editor component to make this work if required. */ template - class EditorComponentAdapter - : public EditorComponentBase + class EditorComponentAdapter : public EditorComponentBase { public: - - AZ_RTTI((EditorComponentAdapter, "{2F5A3669-FFE9-4CD7-B9E2-7FC8100CF1A2}", TController, TRuntimeComponent, TConfiguration), EditorComponentBase); + AZ_RTTI( + (EditorComponentAdapter, "{2F5A3669-FFE9-4CD7-B9E2-7FC8100CF1A2}", TController, TRuntimeComponent, TConfiguration), + EditorComponentBase); EditorComponentAdapter() = default; - EditorComponentAdapter(const TConfiguration& configuration); + explicit EditorComponentAdapter(const TConfiguration& configuration); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services); static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services); @@ -86,7 +86,6 @@ namespace AzToolsFramework void BuildGameEntity(AZ::Entity* gameEntity) override; protected: - static void Reflect(AZ::ReflectContext* context); // AZ::Component overrides ... diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentAdapter.inl b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentAdapter.inl index 04619b079d..b8bd24589a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentAdapter.inl +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentAdapter.inl @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include @@ -28,23 +28,21 @@ namespace AzToolsFramework template void EditorComponentAdapter::Reflect(AZ::ReflectContext* context) { - if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) + if (auto serializeContext = azrtti_cast(context)) { - serializeContext->Class() - ->Version(1) - ->Field("Controller", &EditorComponentAdapter::m_controller) - ; + serializeContext->Class()->Version(1)->Field( + "Controller", &EditorComponentAdapter::m_controller); if (AZ::EditContext* editContext = serializeContext->GetEditContext()) { - editContext->Class( - "EditorComponentAdapter", "") + // clang-format off + editContext->Class("EditorComponentAdapter", "") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->DataElement(AZ::Edit::UIHandlers::Default, &EditorComponentAdapter::m_controller, "Controller", "") ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorComponentAdapter::OnConfigurationChanged) - ; + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorComponentAdapter::OnConfigurationChanged); + // clang-format on } } } @@ -53,27 +51,35 @@ namespace AzToolsFramework // Get*Services functions template - void EditorComponentAdapter::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services) + void EditorComponentAdapter::GetProvidedServices( + AZ::ComponentDescriptor::DependencyArrayType& services) { - AzFramework::Components::GetProvidedServicesHelper(services, typename AZ::HasComponentProvidedServices::type()); + AzFramework::Components::GetProvidedServicesHelper( + services, typename AZ::HasComponentProvidedServices::type()); } template - void EditorComponentAdapter::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services) + void EditorComponentAdapter::GetRequiredServices( + AZ::ComponentDescriptor::DependencyArrayType& services) { - AzFramework::Components::GetRequiredServicesHelper(services, typename AZ::HasComponentRequiredServices::type()); + AzFramework::Components::GetRequiredServicesHelper( + services, typename AZ::HasComponentRequiredServices::type()); } template - void EditorComponentAdapter::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services) + void EditorComponentAdapter::GetIncompatibleServices( + AZ::ComponentDescriptor::DependencyArrayType& services) { - AzFramework::Components::GetIncompatibleServicesHelper(services, typename AZ::HasComponentIncompatibleServices::type()); + AzFramework::Components::GetIncompatibleServicesHelper( + services, typename AZ::HasComponentIncompatibleServices::type()); } template - void EditorComponentAdapter::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& services) + void EditorComponentAdapter::GetDependentServices( + AZ::ComponentDescriptor::DependencyArrayType& services) { - AzFramework::Components::GetDependentServicesHelper(services, typename AZ::HasComponentDependentServices::type()); + AzFramework::Components::GetDependentServicesHelper( + services, typename AZ::HasComponentDependentServices::type()); } ////////////////////////////////////////////////////////////////////////// @@ -99,7 +105,8 @@ namespace AzToolsFramework if (ShouldActivateController()) { - m_controller.Activate(GetEntityId()); + AzFramework::Components::ComponentActivateHelper::Activate( + m_controller, AZ::EntityComponentIdPair(GetEntityId(), GetId())); } } @@ -122,7 +129,8 @@ namespace AzToolsFramework } template - bool EditorComponentAdapter::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const + bool EditorComponentAdapter::WriteOutConfig( + AZ::ComponentConfig* outBaseConfig) const { if (auto config = azrtti_cast(outBaseConfig)) { @@ -139,7 +147,8 @@ namespace AzToolsFramework if (ShouldActivateController()) { - m_controller.Activate(GetEntityId()); + AzFramework::Components::ComponentActivateHelper::Activate( + m_controller, AZ::EntityComponentIdPair(GetEntityId(), GetId())); } return AZ::Edit::PropertyRefreshLevels::None; diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/EditorRenderComponentAdapter.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/EditorRenderComponentAdapter.h index 101387205f..be761d8e7b 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/EditorRenderComponentAdapter.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/EditorRenderComponentAdapter.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -26,14 +26,15 @@ namespace AZ , public AzToolsFramework::EditorEntityVisibilityNotificationBus::Handler { public: - using BaseClass = AzToolsFramework::Components::EditorComponentAdapter; - AZ_RTTI((EditorRenderComponentAdapter, "{AAF38BE4-EA2F-408B-9C44-63C7FBAC6B33}", TController, TRuntimeComponent, TConfiguration), BaseClass); + AZ_RTTI( + (EditorRenderComponentAdapter, "{AAF38BE4-EA2F-408B-9C44-63C7FBAC6B33}", TController, TRuntimeComponent, TConfiguration), + BaseClass); static void Reflect(AZ::ReflectContext* context); EditorRenderComponentAdapter() = default; - EditorRenderComponentAdapter(const TConfiguration& config); + explicit EditorRenderComponentAdapter(const TConfiguration& config); // AzToolsFramework::Components::EditorComponentAdapter overrides void Activate() override; @@ -50,7 +51,8 @@ namespace AZ // Convert pre-existing EditorCompnentAdapter based serialized data to EditorRenderComponentAdapter template - static bool ConvertToEditorRenderComponentAdapter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement); + static bool ConvertToEditorRenderComponentAdapter( + AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement); }; } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/EditorRenderComponentAdapter.inl b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/EditorRenderComponentAdapter.inl index e3f7ccd44d..633ec0e0ca 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/EditorRenderComponentAdapter.inl +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/EditorRenderComponentAdapter.inl @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include #include @@ -19,11 +19,12 @@ namespace AZ { template template - bool EditorRenderComponentAdapter::ConvertToEditorRenderComponentAdapter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement) + bool EditorRenderComponentAdapter::ConvertToEditorRenderComponentAdapter( + AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement) { if (classElement.GetVersion() < TVersion) { - // Get the and remove the EditorComponentAdapter base class data that was previpously serialized + // Get the and remove the EditorComponentAdapter base class data that was previously serialized AzToolsFramework::Components::EditorComponentAdapter oldBaseClassData; if (!classElement.FindSubElementAndGetData(AZ_CRC("BaseClass1", 0xd4925735), oldBaseClassData)) @@ -41,8 +42,8 @@ namespace AZ // Replace the old base class data with EditorRenderComponentAdapter EditorRenderComponentAdapter newBaseClassData; - AZ::SerializeContext::DataElementNode& newBaseClassElement = classElement.GetSubElement( - classElement.AddElementWithData(context, "BaseClass1", newBaseClassData)); + AZ::SerializeContext::DataElementNode& newBaseClassElement = + classElement.GetSubElement(classElement.AddElementWithData(context, "BaseClass1", newBaseClassData)); // Overwrite EditorRenderComponentAdapter base class data with retrieved EditorComponentAdapter base class data if (!newBaseClassElement.RemoveElementByName(AZ_CRC("BaseClass1", 0xd4925735))) @@ -62,25 +63,24 @@ namespace AZ { BaseClass::Reflect(context); - if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) + if (auto serializeContext = azrtti_cast(context)) { - serializeContext->Class() - ->Version(0) - ; + serializeContext->Class()->Version(0); if (AZ::EditContext* editContext = serializeContext->GetEditContext()) { - editContext->Class( - "EditorRenderComponentAdapter", "") + // clang-format off + editContext->Class("EditorRenderComponentAdapter", "") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ; + ->Attribute(AZ::Edit::Attributes::AutoExpand, true); + // clang-format on } } } template - EditorRenderComponentAdapter::EditorRenderComponentAdapter(const TConfiguration& config) + EditorRenderComponentAdapter::EditorRenderComponentAdapter( + const TConfiguration& config) : BaseClass(config) { } @@ -103,7 +103,8 @@ namespace AZ bool EditorRenderComponentAdapter::IsVisible() const { bool visible = true; - AzToolsFramework::EditorEntityInfoRequestBus::EventResult(visible, this->GetEntityId(), &AzToolsFramework::EditorEntityInfoRequestBus::Events::IsVisible); + AzToolsFramework::EditorEntityInfoRequestBus::EventResult( + visible, this->GetEntityId(), &AzToolsFramework::EditorEntityInfoRequestBus::Events::IsVisible); return visible; } @@ -114,15 +115,16 @@ namespace AZ } template - void EditorRenderComponentAdapter::OnEntityVisibilityChanged([[maybe_unused]] bool visibility) + void EditorRenderComponentAdapter::OnEntityVisibilityChanged( + [[maybe_unused]] bool visibility) { this->m_controller.Deactivate(); if (this->ShouldActivateController()) { - this->m_controller.Activate(this->GetEntityId()); + AzFramework::Components::ComponentActivateHelper::Activate( + this->m_controller, AZ::EntityComponentIdPair(this->GetEntityId(), this->GetId())); } } - } // namespace Render } // namespace AZ