Prevent read-only entities from being duplicated via prefab workflows (#7076)

* Refactor the sanitation of the selection for prefab operations to prevent read-only entities from being deleted or duplicated.

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>

* Fix comment.

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>
monroegm-disable-blank-issue-2
Danilo Aimini 4 years ago committed by GitHub
parent a8d97cf8aa
commit 86a0be2561
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1063,7 +1063,7 @@ namespace AzToolsFramework
return AZ::Failure(AZStd::string("No entities to duplicate."));
}
const EntityIdList entityIdsNoFocusContainer = GenerateEntityIdListWithoutFocusedInstanceContainer(entityIds);
const EntityIdList entityIdsNoFocusContainer = SanitizeEntityIdList(entityIds);
if (entityIdsNoFocusContainer.empty())
{
return AZ::Failure(AZStd::string("No entities to duplicate because only instance selected is the container entity of the focused instance."));
@ -1202,7 +1202,7 @@ namespace AzToolsFramework
PrefabOperationResult PrefabPublicHandler::DeleteFromInstance(const EntityIdList& entityIds, bool deleteDescendants)
{
// Remove the container entity of the focused prefab from the list, if it is included.
const EntityIdList entityIdsNoFocusContainer = GenerateEntityIdListWithoutFocusedInstanceContainer(entityIds);
const EntityIdList entityIdsNoFocusContainer = SanitizeEntityIdList(entityIds);
if (entityIdsNoFocusContainer.empty())
{
@ -1236,27 +1236,6 @@ namespace AzToolsFramework
return AZ::Failure(AZStd::string("Cannot delete entities belonging to an instance that is not being edited."));
}
// None of the specified entities can be marked as read only, otherwise this operation is invalid.
if (auto readOnlyEntityPublicInterface = AZ::Interface<ReadOnlyEntityPublicInterface>::Get())
{
AZ::EntityId readOnlyEntityId;
for (const auto& entityId : entityIdsNoFocusContainer)
{
if (readOnlyEntityPublicInterface->IsReadOnly(entityId))
{
readOnlyEntityId = entityId;
break;
}
}
if (readOnlyEntityId.IsValid())
{
return AZ::Failure(AZStd::string::format(
"Cannot delete entities because entity (id '%llu') is marked as read only.",
static_cast<AZ::u64>(readOnlyEntityId)));
}
}
// Retrieve entityList from entityIds
EntityList inputEntityList = EntityIdListToEntityList(entityIdsNoFocusContainer);
@ -1680,10 +1659,24 @@ namespace AzToolsFramework
return AZ::Success();
}
EntityIdList PrefabPublicHandler::GenerateEntityIdListWithoutFocusedInstanceContainer(
const EntityIdList& entityIds) const
EntityIdList PrefabPublicHandler::SanitizeEntityIdList(const EntityIdList& entityIds) const
{
EntityIdList outEntityIds(entityIds);
EntityIdList outEntityIds;
if (auto readOnlyEntityPublicInterface = AZ::Interface<ReadOnlyEntityPublicInterface>::Get())
{
std::copy_if(
entityIds.begin(), entityIds.end(), AZStd::back_inserter(outEntityIds),
[readOnlyEntityPublicInterface](const AZ::EntityId& entityId)
{
return !readOnlyEntityPublicInterface->IsReadOnly(entityId);
}
);
}
else
{
outEntityIds = entityIds;
}
AzFramework::EntityContextId editorEntityContextId = AzToolsFramework::GetEntityContextId();
AZ::EntityId focusedInstanceContainerEntityId = m_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId);

@ -75,7 +75,10 @@ namespace AzToolsFramework
Instance& commonRootEntityOwningInstance,
EntityList& outEntities,
AZStd::vector<Instance*>& outInstances) const;
EntityIdList GenerateEntityIdListWithoutFocusedInstanceContainer(const EntityIdList& entityIds) const;
//! Sanitizes an EntityIdList to remove entities that should not be affected by prefab operations.
//! It will identify and exclude the container entity of the root prefab instance, and all read-only entities.
EntityIdList SanitizeEntityIdList(const EntityIdList& entityIds) const;
InstanceOptionalReference GetOwnerInstanceByEntityId(AZ::EntityId entityId) const;
bool EntitiesBelongToSameInstance(const EntityIdList& entityIds) const;

Loading…
Cancel
Save