From a692ae1567f7c8435832c2ad4e8884e75a6d984d Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Tue, 28 Sep 2021 14:57:09 -0700 Subject: [PATCH] Restore event listening behavior in EntityOutlinerListModel (#4254) Disables a problematic child reparenting code path in EditorEntityModel that led to the series of remove -> add -> remove notifications for reparented entities that led to unnecessary updates and a sporadic QSortFilterProxyModel crash Signed-off-by: nvsickle --- .../Entity/EditorEntityModel.cpp | 20 ++++++++++++++----- .../UI/Outliner/EntityOutlinerListModel.cpp | 7 +++++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp index 8d96cc42fe..ce1bf84db0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp @@ -381,12 +381,22 @@ namespace AzToolsFramework return; } - //orphan any children that remain attached to the entity - auto children = entityInfo.GetChildren(); - for (auto childId : children) + bool isPrefabSystemEnabled = false; + AzFramework::ApplicationRequests::Bus::BroadcastResult( + isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled); + + // For slices, orphan any children that remain attached to the entity + // For prefabs, this is an unneeded operation because the prefab system handles the orphans + // and the extra reparenting operation can be problematic for consumers subscribed to entity + // events, such as the entity outliner. + if (!isPrefabSystemEnabled) { - ReparentChild(childId, AZ::EntityId(), entityId); - m_entityOrphanTable[entityId].insert(childId); + auto children = entityInfo.GetChildren(); + for (auto childId : children) + { + ReparentChild(childId, AZ::EntityId(), entityId); + m_entityOrphanTable[entityId].insert(childId); + } } m_savedOrderInfo[entityId] = AZStd::make_pair(entityInfo.GetParent(), entityInfo.GetIndexForSorting()); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp index b3ac8b4c73..2872c1bce3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp @@ -1344,7 +1344,10 @@ namespace AzToolsFramework //add/remove operations trigger selection change signals which assert and break undo/redo operations in progress in inspector etc. //so disallow selection updates until change is complete emit EnableSelectionUpdates(false); - beginResetModel(); + + auto parentIndex = GetIndexFromEntity(parentId); + auto childIndex = GetIndexFromEntity(childId); + beginRemoveRows(parentIndex, childIndex.row(), childIndex.row()); } void EntityOutlinerListModel::OnEntityInfoUpdatedRemoveChildEnd(AZ::EntityId parentId, AZ::EntityId childId) @@ -1352,7 +1355,7 @@ namespace AzToolsFramework (void)childId; AZ_PROFILE_FUNCTION(AzToolsFramework); - endResetModel(); + endRemoveRows(); //must refresh partial lock/visibility of parents m_isFilterDirty = true;