Merge pull request #4913 from aws-lumberyard-dev/cgalvan/AddFindComponentsByServiceAPI
Added API for finding components based on required/incompatible services
This commit is contained in:
@@ -36,6 +36,10 @@ namespace AzToolsFramework
|
|||||||
//! the entity type.
|
//! the entity type.
|
||||||
virtual AZStd::vector<AZ::Uuid> FindComponentTypeIdsByEntityType(const AZStd::vector<AZStd::string>& componentTypeNames, EntityType entityType) = 0;
|
virtual AZStd::vector<AZ::Uuid> FindComponentTypeIdsByEntityType(const AZStd::vector<AZStd::string>& componentTypeNames, EntityType entityType) = 0;
|
||||||
|
|
||||||
|
//! Return a list of type ids for components that match the required services filter,
|
||||||
|
//! and don't conflict with any of the incompatible services filter
|
||||||
|
virtual AZStd::vector<AZ::Uuid> FindComponentTypeIdsByService(const AZStd::vector<AZ::ComponentServiceType>& serviceFilter, const AZStd::vector<AZ::ComponentServiceType>& incompatibleServiceFilter) = 0;
|
||||||
|
|
||||||
//! Finds the component names from their type ids
|
//! Finds the component names from their type ids
|
||||||
virtual AZStd::vector<AZStd::string> FindComponentTypeNames(const AZ::ComponentTypeList& componentTypeIds) = 0;
|
virtual AZStd::vector<AZStd::string> FindComponentTypeNames(const AZ::ComponentTypeList& componentTypeIds) = 0;
|
||||||
|
|
||||||
|
|||||||
+30
@@ -15,6 +15,7 @@
|
|||||||
#include <AzToolsFramework/ToolsComponents/EditorDisabledCompositionBus.h>
|
#include <AzToolsFramework/ToolsComponents/EditorDisabledCompositionBus.h>
|
||||||
#include <AzToolsFramework/ToolsComponents/EditorPendingCompositionBus.h>
|
#include <AzToolsFramework/ToolsComponents/EditorPendingCompositionBus.h>
|
||||||
#include <AzToolsFramework/Entity/EditorEntityActionComponent.h>
|
#include <AzToolsFramework/Entity/EditorEntityActionComponent.h>
|
||||||
|
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||||
#include <AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h>
|
#include <AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h>
|
||||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||||
|
|
||||||
@@ -75,6 +76,7 @@ namespace AzToolsFramework
|
|||||||
serializeContext->Class<EditorComponentAPIComponent, AZ::Component>();
|
serializeContext->Class<EditorComponentAPIComponent, AZ::Component>();
|
||||||
|
|
||||||
serializeContext->RegisterGenericType<AZStd::vector<AZ::EntityComponentIdPair>>();
|
serializeContext->RegisterGenericType<AZStd::vector<AZ::EntityComponentIdPair>>();
|
||||||
|
serializeContext->RegisterGenericType<AZStd::vector<AZ::ComponentServiceType>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||||
@@ -99,6 +101,7 @@ namespace AzToolsFramework
|
|||||||
->Attribute(AZ::Script::Attributes::Module, "editor")
|
->Attribute(AZ::Script::Attributes::Module, "editor")
|
||||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||||
->Event("FindComponentTypeIdsByEntityType", &EditorComponentAPIRequests::FindComponentTypeIdsByEntityType)
|
->Event("FindComponentTypeIdsByEntityType", &EditorComponentAPIRequests::FindComponentTypeIdsByEntityType)
|
||||||
|
->Event("FindComponentTypeIdsByService", &EditorComponentAPIRequests::FindComponentTypeIdsByService)
|
||||||
->Event("FindComponentTypeNames", &EditorComponentAPIRequests::FindComponentTypeNames)
|
->Event("FindComponentTypeNames", &EditorComponentAPIRequests::FindComponentTypeNames)
|
||||||
->Event("BuildComponentTypeNameListByEntityType", &EditorComponentAPIRequests::BuildComponentTypeNameListByEntityType)
|
->Event("BuildComponentTypeNameListByEntityType", &EditorComponentAPIRequests::BuildComponentTypeNameListByEntityType)
|
||||||
->Event("AddComponentsOfType", &EditorComponentAPIRequests::AddComponentsOfType)
|
->Event("AddComponentsOfType", &EditorComponentAPIRequests::AddComponentsOfType)
|
||||||
@@ -216,6 +219,33 @@ namespace AzToolsFramework
|
|||||||
return foundTypeIds;
|
return foundTypeIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AZStd::vector<AZ::Uuid> EditorComponentAPIComponent::FindComponentTypeIdsByService(const AZStd::vector<AZ::ComponentServiceType>& serviceFilter, const AZStd::vector<AZ::ComponentServiceType>& incompatibleServiceFilter)
|
||||||
|
{
|
||||||
|
AZStd::vector<AZ::Uuid> foundTypeIds;
|
||||||
|
|
||||||
|
m_serializeContext->EnumerateDerived<AZ::Component>(
|
||||||
|
[&foundTypeIds, serviceFilter, incompatibleServiceFilter](const AZ::SerializeContext::ClassData* componentClass, const AZ::Uuid& knownType) -> bool
|
||||||
|
{
|
||||||
|
AZ_UNUSED(knownType);
|
||||||
|
|
||||||
|
if (componentClass->m_editData)
|
||||||
|
{
|
||||||
|
// If none of the required services are offered by this component, or the component
|
||||||
|
// can not be added by the user, skip to the next component
|
||||||
|
if (!OffersRequiredServices(componentClass, serviceFilter, incompatibleServiceFilter))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foundTypeIds.push_back(componentClass->m_typeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return foundTypeIds;
|
||||||
|
}
|
||||||
|
|
||||||
AZStd::vector<AZStd::string> EditorComponentAPIComponent::FindComponentTypeNames(const AZ::ComponentTypeList& componentTypeIds)
|
AZStd::vector<AZStd::string> EditorComponentAPIComponent::FindComponentTypeNames(const AZ::ComponentTypeList& componentTypeIds)
|
||||||
{
|
{
|
||||||
AZStd::vector<AZStd::string> foundTypeNames;
|
AZStd::vector<AZStd::string> foundTypeNames;
|
||||||
|
|||||||
+1
@@ -35,6 +35,7 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
// EditorComponentAPIBus ...
|
// EditorComponentAPIBus ...
|
||||||
AZStd::vector<AZ::Uuid> FindComponentTypeIdsByEntityType(const AZStd::vector<AZStd::string>& componentTypeNames, EditorComponentAPIRequests::EntityType entityType) override;
|
AZStd::vector<AZ::Uuid> FindComponentTypeIdsByEntityType(const AZStd::vector<AZStd::string>& componentTypeNames, EditorComponentAPIRequests::EntityType entityType) override;
|
||||||
|
AZStd::vector<AZ::Uuid> FindComponentTypeIdsByService(const AZStd::vector<AZ::ComponentServiceType>& serviceFilter, const AZStd::vector<AZ::ComponentServiceType>& incompatibleServiceFilter) override;
|
||||||
AZStd::vector<AZStd::string> FindComponentTypeNames(const AZ::ComponentTypeList& componentTypeIds) override;
|
AZStd::vector<AZStd::string> FindComponentTypeNames(const AZ::ComponentTypeList& componentTypeIds) override;
|
||||||
AZStd::vector<AZStd::string> BuildComponentTypeNameListByEntityType(EditorComponentAPIRequests::EntityType entityType) override;
|
AZStd::vector<AZStd::string> BuildComponentTypeNameListByEntityType(EditorComponentAPIRequests::EntityType entityType) override;
|
||||||
|
|
||||||
|
|||||||
@@ -271,6 +271,68 @@ namespace AzToolsFramework
|
|||||||
return editorComponentBaseComponent;
|
return editorComponentBaseComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OffersRequiredServices(
|
||||||
|
const AZ::SerializeContext::ClassData* componentClass,
|
||||||
|
const AZStd::vector<AZ::ComponentServiceType>& serviceFilter,
|
||||||
|
const AZStd::vector<AZ::ComponentServiceType>& incompatibleServiceFilter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AZ_Assert(componentClass, "Component class must not be null");
|
||||||
|
|
||||||
|
if (!componentClass)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AZ::ComponentDescriptor* componentDescriptor = nullptr;
|
||||||
|
AZ::ComponentDescriptorBus::EventResult(
|
||||||
|
componentDescriptor, componentClass->m_typeId, &AZ::ComponentDescriptor::GetDescriptor);
|
||||||
|
if (!componentDescriptor)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no services are provided, this function returns true
|
||||||
|
if (serviceFilter.empty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AZ::ComponentDescriptor::DependencyArrayType providedServices;
|
||||||
|
componentDescriptor->GetProvidedServices(providedServices, nullptr);
|
||||||
|
|
||||||
|
//reject this component if it does not offer any of the required services
|
||||||
|
if (AZStd::find_first_of(
|
||||||
|
providedServices.begin(),
|
||||||
|
providedServices.end(),
|
||||||
|
serviceFilter.begin(),
|
||||||
|
serviceFilter.end()) == providedServices.end())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//reject this component if it does offer any of the incompatible services
|
||||||
|
if (AZStd::find_first_of(
|
||||||
|
providedServices.begin(),
|
||||||
|
providedServices.end(),
|
||||||
|
incompatibleServiceFilter.begin(),
|
||||||
|
incompatibleServiceFilter.end()) != providedServices.end())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OffersRequiredServices(
|
||||||
|
const AZ::SerializeContext::ClassData* componentClass,
|
||||||
|
const AZStd::vector<AZ::ComponentServiceType>& serviceFilter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const AZStd::vector<AZ::ComponentServiceType> incompatibleServices;
|
||||||
|
return OffersRequiredServices(componentClass, serviceFilter, incompatibleServices);
|
||||||
|
}
|
||||||
|
|
||||||
bool ShouldInspectorShowComponent(const AZ::Component* component)
|
bool ShouldInspectorShowComponent(const AZ::Component* component)
|
||||||
{
|
{
|
||||||
if (!component)
|
if (!component)
|
||||||
|
|||||||
@@ -105,6 +105,16 @@ namespace AzToolsFramework
|
|||||||
AZ::ComponentDescriptor* GetComponentDescriptor(const AZ::Component* component);
|
AZ::ComponentDescriptor* GetComponentDescriptor(const AZ::Component* component);
|
||||||
Components::EditorComponentDescriptor* GetEditorComponentDescriptor(const AZ::Component* component);
|
Components::EditorComponentDescriptor* GetEditorComponentDescriptor(const AZ::Component* component);
|
||||||
Components::EditorComponentBase* GetEditorComponent(AZ::Component* component);
|
Components::EditorComponentBase* GetEditorComponent(AZ::Component* component);
|
||||||
|
// Returns true if the given component provides at least one of the services specified or no services are provided
|
||||||
|
bool OffersRequiredServices(
|
||||||
|
const AZ::SerializeContext::ClassData* componentClass,
|
||||||
|
const AZStd::vector<AZ::ComponentServiceType>& serviceFilter,
|
||||||
|
const AZStd::vector<AZ::ComponentServiceType>& incompatibleServiceFilter
|
||||||
|
);
|
||||||
|
bool OffersRequiredServices(
|
||||||
|
const AZ::SerializeContext::ClassData* componentClass,
|
||||||
|
const AZStd::vector<AZ::ComponentServiceType>& serviceFilter
|
||||||
|
);
|
||||||
|
|
||||||
/// Return true if the editor should show this component to users,
|
/// Return true if the editor should show this component to users,
|
||||||
/// false if the component should be hidden from users.
|
/// false if the component should be hidden from users.
|
||||||
|
|||||||
+1
-61
@@ -12,6 +12,7 @@
|
|||||||
#include <AzCore/Component/Component.h>
|
#include <AzCore/Component/Component.h>
|
||||||
#include <AzCore/Serialization/SerializeContext.h>
|
#include <AzCore/Serialization/SerializeContext.h>
|
||||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||||
|
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: 'QLayoutItem::align': class 'QFlags<Qt::AlignmentFlag>' needs to have dll-interface to be used by clients of class 'QLayoutItem'
|
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: 'QLayoutItem::align': class 'QFlags<Qt::AlignmentFlag>' needs to have dll-interface to be used by clients of class 'QLayoutItem'
|
||||||
#include <AzToolsFramework/UI/SearchWidget/SearchCriteriaWidget.hxx>
|
#include <AzToolsFramework/UI/SearchWidget/SearchCriteriaWidget.hxx>
|
||||||
AZ_POP_DISABLE_WARNING
|
AZ_POP_DISABLE_WARNING
|
||||||
@@ -20,67 +21,6 @@ namespace AzToolsFramework
|
|||||||
{
|
{
|
||||||
namespace ComponentPaletteUtil
|
namespace ComponentPaletteUtil
|
||||||
{
|
{
|
||||||
bool OffersRequiredServices(
|
|
||||||
const AZ::SerializeContext::ClassData* componentClass,
|
|
||||||
const AZStd::vector<AZ::ComponentServiceType>& serviceFilter,
|
|
||||||
const AZStd::vector<AZ::ComponentServiceType>& incompatibleServiceFilter
|
|
||||||
)
|
|
||||||
{
|
|
||||||
AZ_Assert(componentClass, "Component class must not be null");
|
|
||||||
|
|
||||||
if (!componentClass)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AZ::ComponentDescriptor* componentDescriptor = nullptr;
|
|
||||||
EBUS_EVENT_ID_RESULT(componentDescriptor, componentClass->m_typeId, AZ::ComponentDescriptorBus, GetDescriptor);
|
|
||||||
if (!componentDescriptor)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no services are provided, this function returns true
|
|
||||||
if (serviceFilter.empty())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
AZ::ComponentDescriptor::DependencyArrayType providedServices;
|
|
||||||
componentDescriptor->GetProvidedServices(providedServices, nullptr);
|
|
||||||
|
|
||||||
//reject this component if it does not offer any of the required services
|
|
||||||
if (AZStd::find_first_of(
|
|
||||||
providedServices.begin(),
|
|
||||||
providedServices.end(),
|
|
||||||
serviceFilter.begin(),
|
|
||||||
serviceFilter.end()) == providedServices.end())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//reject this component if it does offer any of the incompatible services
|
|
||||||
if (AZStd::find_first_of(
|
|
||||||
providedServices.begin(),
|
|
||||||
providedServices.end(),
|
|
||||||
incompatibleServiceFilter.begin(),
|
|
||||||
incompatibleServiceFilter.end()) != providedServices.end())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OffersRequiredServices(
|
|
||||||
const AZ::SerializeContext::ClassData* componentClass,
|
|
||||||
const AZStd::vector<AZ::ComponentServiceType>& serviceFilter
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const AZStd::vector<AZ::ComponentServiceType> incompatibleServices;
|
|
||||||
return OffersRequiredServices(componentClass, serviceFilter, incompatibleServices);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsAddableByUser(const AZ::SerializeContext::ClassData* componentClass)
|
bool IsAddableByUser(const AZ::SerializeContext::ClassData* componentClass)
|
||||||
{
|
{
|
||||||
AZ_Assert(componentClass, "component class must not be null");
|
AZ_Assert(componentClass, "component class must not be null");
|
||||||
|
|||||||
-12
@@ -26,18 +26,6 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
using ComponentIconTable = AZStd::map<const AZ::SerializeContext::ClassData*, QString>;
|
using ComponentIconTable = AZStd::map<const AZ::SerializeContext::ClassData*, QString>;
|
||||||
|
|
||||||
// Returns true if the given component provides at least one of the services specified or no services are provided
|
|
||||||
bool OffersRequiredServices(
|
|
||||||
const AZ::SerializeContext::ClassData* componentClass,
|
|
||||||
const AZStd::vector<AZ::ComponentServiceType>& serviceFilter,
|
|
||||||
const AZStd::vector<AZ::ComponentServiceType>& incompatibleServiceFilter
|
|
||||||
);
|
|
||||||
|
|
||||||
bool OffersRequiredServices(
|
|
||||||
const AZ::SerializeContext::ClassData* componentClass,
|
|
||||||
const AZStd::vector<AZ::ComponentServiceType>& serviceFilter
|
|
||||||
);
|
|
||||||
|
|
||||||
// Returns true if the given component is addable by the user
|
// Returns true if the given component is addable by the user
|
||||||
bool IsAddableByUser(const AZ::SerializeContext::ClassData* componentClass);
|
bool IsAddableByUser(const AZ::SerializeContext::ClassData* componentClass);
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <AzToolsFramework/Application/ToolsApplication.h>
|
#include <AzToolsFramework/Application/ToolsApplication.h>
|
||||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||||
|
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||||
#include <AzToolsFramework/UnitTest/ToolsTestApplication.h>
|
#include <AzToolsFramework/UnitTest/ToolsTestApplication.h>
|
||||||
|
|
||||||
// Inspector Test Includes
|
// Inspector Test Includes
|
||||||
@@ -313,17 +314,17 @@ namespace UnitTest
|
|||||||
AZ_TEST_ASSERT(testComponent1_ProvidedServices.size() == 1);
|
AZ_TEST_ASSERT(testComponent1_ProvidedServices.size() == 1);
|
||||||
const AZ::SerializeContext::ClassData* testComponent1_ClassData = context->FindClassData(testComponent1_typeId);
|
const AZ::SerializeContext::ClassData* testComponent1_ClassData = context->FindClassData(testComponent1_typeId);
|
||||||
|
|
||||||
EXPECT_TRUE(AzToolsFramework::ComponentPaletteUtil::OffersRequiredServices(testComponent1_ClassData, testComponent1_ProvidedServices));
|
EXPECT_TRUE(AzToolsFramework::OffersRequiredServices(testComponent1_ClassData, testComponent1_ProvidedServices));
|
||||||
|
|
||||||
// Verify that OffersRequiredServices returns when given services provided by a different component
|
// Verify that OffersRequiredServices returns when given services provided by a different component
|
||||||
AZ::ComponentDescriptor::DependencyArrayType testComponent2_ProvidedServices;
|
AZ::ComponentDescriptor::DependencyArrayType testComponent2_ProvidedServices;
|
||||||
Inspector_TestComponent2::GetProvidedServices(testComponent2_ProvidedServices);
|
Inspector_TestComponent2::GetProvidedServices(testComponent2_ProvidedServices);
|
||||||
AZ_TEST_ASSERT(testComponent2_ProvidedServices.size() == 1);
|
AZ_TEST_ASSERT(testComponent2_ProvidedServices.size() == 1);
|
||||||
AZ_TEST_ASSERT(testComponent1_ProvidedServices != testComponent2_ProvidedServices);
|
AZ_TEST_ASSERT(testComponent1_ProvidedServices != testComponent2_ProvidedServices);
|
||||||
EXPECT_FALSE(AzToolsFramework::ComponentPaletteUtil::OffersRequiredServices(testComponent1_ClassData, testComponent2_ProvidedServices));
|
EXPECT_FALSE(AzToolsFramework::OffersRequiredServices(testComponent1_ClassData, testComponent2_ProvidedServices));
|
||||||
|
|
||||||
// verify that OffersRequiredServices returns true when provided with an empty list of services
|
// verify that OffersRequiredServices returns true when provided with an empty list of services
|
||||||
EXPECT_TRUE(AzToolsFramework::ComponentPaletteUtil::OffersRequiredServices(testComponent1_ClassData, AZ::ComponentDescriptor::DependencyArrayType()));
|
EXPECT_TRUE(AzToolsFramework::OffersRequiredServices(testComponent1_ClassData, AZ::ComponentDescriptor::DependencyArrayType()));
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// TEST IsAddableByUser()
|
// TEST IsAddableByUser()
|
||||||
|
|||||||
Reference in New Issue
Block a user