Added API for finding components based on required/incompatible services.
Signed-off-by: Chris Galvan <chgalvan@amazon.com>
This commit is contained in:
@@ -36,6 +36,10 @@ namespace AzToolsFramework
|
||||
//! the entity type.
|
||||
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
|
||||
virtual AZStd::vector<AZStd::string> FindComponentTypeNames(const AZ::ComponentTypeList& componentTypeIds) = 0;
|
||||
|
||||
|
||||
+30
@@ -15,6 +15,7 @@
|
||||
#include <AzToolsFramework/ToolsComponents/EditorDisabledCompositionBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorPendingCompositionBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityActionComponent.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
|
||||
@@ -75,6 +76,7 @@ namespace AzToolsFramework
|
||||
serializeContext->Class<EditorComponentAPIComponent, AZ::Component>();
|
||||
|
||||
serializeContext->RegisterGenericType<AZStd::vector<AZ::EntityComponentIdPair>>();
|
||||
serializeContext->RegisterGenericType<AZStd::vector<AZ::ComponentServiceType>>();
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
@@ -99,6 +101,7 @@ namespace AzToolsFramework
|
||||
->Attribute(AZ::Script::Attributes::Module, "editor")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("FindComponentTypeIdsByEntityType", &EditorComponentAPIRequests::FindComponentTypeIdsByEntityType)
|
||||
->Event("FindComponentTypeIdsByService", &EditorComponentAPIRequests::FindComponentTypeIdsByService)
|
||||
->Event("FindComponentTypeNames", &EditorComponentAPIRequests::FindComponentTypeNames)
|
||||
->Event("BuildComponentTypeNameListByEntityType", &EditorComponentAPIRequests::BuildComponentTypeNameListByEntityType)
|
||||
->Event("AddComponentsOfType", &EditorComponentAPIRequests::AddComponentsOfType)
|
||||
@@ -216,6 +219,33 @@ namespace AzToolsFramework
|
||||
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> foundTypeNames;
|
||||
|
||||
+1
@@ -35,6 +35,7 @@ namespace AzToolsFramework
|
||||
|
||||
// EditorComponentAPIBus ...
|
||||
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> BuildComponentTypeNameListByEntityType(EditorComponentAPIRequests::EntityType entityType) override;
|
||||
|
||||
|
||||
@@ -271,6 +271,68 @@ namespace AzToolsFramework
|
||||
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)
|
||||
{
|
||||
if (!component)
|
||||
|
||||
@@ -105,6 +105,16 @@ namespace AzToolsFramework
|
||||
AZ::ComponentDescriptor* GetComponentDescriptor(const AZ::Component* component);
|
||||
Components::EditorComponentDescriptor* GetEditorComponentDescriptor(const 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,
|
||||
/// false if the component should be hidden from users.
|
||||
|
||||
+1
-61
@@ -12,6 +12,7 @@
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Serialization/SerializeContext.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'
|
||||
#include <AzToolsFramework/UI/SearchWidget/SearchCriteriaWidget.hxx>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
@@ -20,67 +21,6 @@ namespace AzToolsFramework
|
||||
{
|
||||
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)
|
||||
{
|
||||
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>;
|
||||
|
||||
// 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
|
||||
bool IsAddableByUser(const AZ::SerializeContext::ClassData* componentClass);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <AzToolsFramework/Application/ToolsApplication.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/UnitTest/ToolsTestApplication.h>
|
||||
|
||||
// Inspector Test Includes
|
||||
@@ -313,17 +314,17 @@ namespace UnitTest
|
||||
AZ_TEST_ASSERT(testComponent1_ProvidedServices.size() == 1);
|
||||
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
|
||||
AZ::ComponentDescriptor::DependencyArrayType testComponent2_ProvidedServices;
|
||||
Inspector_TestComponent2::GetProvidedServices(testComponent2_ProvidedServices);
|
||||
AZ_TEST_ASSERT(testComponent2_ProvidedServices.size() == 1);
|
||||
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
|
||||
EXPECT_TRUE(AzToolsFramework::ComponentPaletteUtil::OffersRequiredServices(testComponent1_ClassData, AZ::ComponentDescriptor::DependencyArrayType()));
|
||||
EXPECT_TRUE(AzToolsFramework::OffersRequiredServices(testComponent1_ClassData, AZ::ComponentDescriptor::DependencyArrayType()));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TEST IsAddableByUser()
|
||||
|
||||
Reference in New Issue
Block a user