Files
o3de/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake
T
nvsickle f0e6841ca8 Fix issues with invalid Outliner entries
The EntityOutlinerListModel was violating the QAbstractItemModel contract in a few cases, as reported by `QAbstractItemModelTester`. The important ones causing issues were:
- Entry order was not guaranteed, leading to model indices pointing at invalid data
- Parent/child relationships could be temporarily invalid due to a change I made in EditorEntityModel::RemoveEntity to try to avoid an unnecessary reparent operation - as it turned out, the parent/child data was being cached even for recreated entities and not clearing child data could cause issues
- `EntityOutlinerListModel::ProcessEntityUpdates` was emitting data changed between two indices that didn't necessarily share a parent, which is [undefined behavior](https://doc.qt.io/qt-5/qabstractitemmodel.html#dataChanged)

The other reported issues (that weren't really causing issues with `QTreeView`) were:
- The root index had flags other than `Qt::ItemIsDropEnabled`
- `rowCount` showed all columns as having children
- `parent` showed indices as being parented to a non-0 column

This change introduces fixes for the above issues, namely:
- Reverts my change to `EditorEntityModel::RemoveEntity` to ensure we don't have invalid parent/child references sitting in the cache
- Ensures `EditorEntityModelEntry` child ordering is guaranteed sorted by EntityId, to prevent the `EntityOutlinerListModel` from having indices pointed at invalid data*.
- Fixes various model sanity issues, such as `rowCount` being 0 for indices with a non-0 column

Two unit tests were added to reproduce the invalid behavior and validate the fix: TestCreateFlatHierarchyUndoAndRedoWorks and TestCreateNestedHierarchyUndoAndRedoWorks
This change focuses on correctness over performance. My subjective in-Editor outliner experience is about the same, but it may be worthwhile to expand the test coverage with a benchmarking suite to look into areas for optimization.

*As a rough illustration of the previous child ordering behavior, consider the following entity hierarchy:
```
Root (EID 9999)
|_ Child1 (EID 2)
|_ Child2 (EID 3)
|_ Child3 (EID 4)
```
With an representations like the following pseudocode:
```
// EditorEntityModel representation
EditorEntityModelEntry root;
root.children[0] = 2;
root.children[1] = 3;
root.children[2] = 4;

// EditorOutlinerListModel representation
// row, column, user data (64 bit uint)
child1 = QModelIndex(0, 0, 2)
child2 = QModelIndex(1, 0, 3)
child3 = QModelIndex(2, 0, 4)
```

When removing a child, the `EditorEntityModel` used to do roughly the following:
```
// Swap and pop the last child
int indexToRemove = 0;
swap(root.children[indexToRemove], root.children[root.children.size() - 1]);
root.children.resize(root.children.size() - 1);
model.notifyRemoved(root, indexToRemove); // model removes the row indicated

// Leading to this EditorEntityModel state
root.children[0] = 4;
root.children[1] = 3;

// And this EntityOutlinerListModel state, note that the row indices are swapped from the indices in the backing storage
child2 = QModelIndex(0, 0, 3)
child3 = QModelIndex(1, 0, 4)
```

A QModelIndex having a row that doesn't match its underlying data is undefined behavior, and was the source of an intermittent crash in our `QSortFilterProxyModel` as subsequent updates to the wrong row led to an invalid proxy state.

Signed-off-by: nvsickle <nvsickle@amazon.com>
2021-10-17 18:38:15 -07:00

136 lines
4.8 KiB
CMake

#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
set(FILES
Main.cpp
ArchiveTests.cpp
AssetFileInfoListComparison.cpp
AssetSeedManager.cpp
AssetSystemMocks.h
BoundsTestComponent.cpp
BoundsTestComponent.h
ComponentAdapterTests.cpp
ComponentAddRemove.cpp
ComponentModeTestDoubles.cpp
ComponentModeTestDoubles.h
ComponentModeTestFixture.cpp
ComponentModeTestFixture.h
ComponentModeTests.cpp
EditorTransformComponentSelectionTests.cpp
EditorVertexSelectionTests.cpp
Entity/EditorEntityContextComponentTests.cpp
Entity/EditorEntityHelpersTests.cpp
Entity/EditorEntitySearchComponentTests.cpp
Entity/EditorEntitySelectionTests.cpp
Entity/EntityUtilityComponentTests.cpp
EntityIdQLabelTests.cpp
EntityInspectorTests.cpp
EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp
EntityOwnershipService/EntityOwnershipServiceTestFixture.h
EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp
EntityOwnershipService/SliceEntityOwnershipTests.cpp
EntityTestbed.h
FileFunc.cpp
FingerprintingTests.cpp
FocusMode/ContainerEntitySelectionTests.cpp
FocusMode/ContainerEntityTests.cpp
FocusMode/EditorFocusModeFixture.cpp
FocusMode/EditorFocusModeFixture.h
FocusMode/EditorFocusModeSelectionFixture.h
FocusMode/EditorFocusModeSelectionTests.cpp
FocusMode/EditorFocusModeTests.cpp
GenericComponentWrapperTest.cpp
InstanceDataHierarchy.cpp
IntegerPrimtitiveTestConfig.h
LogLines.cpp
ManipulatorBoundsTests.cpp
ManipulatorCoreTests.cpp
ManipulatorViewTests.cpp
PerforceComponentTests.cpp
PlatformAddressedAssetCatalogTests.cpp
Prefab/Benchmark/PrefabBenchmarkFixture.cpp
Prefab/Benchmark/PrefabBenchmarkFixture.h
Prefab/Benchmark/PrefabCreateBenchmarks.cpp
Prefab/Benchmark/PrefabInstantiateBenchmarks.cpp
Prefab/Benchmark/PrefabLoadBenchmarks.cpp
Prefab/Benchmark/PrefabUpdateInstancesBenchmarks.cpp
Prefab/Benchmark/SpawnableCreateBenchmarks.cpp
Prefab/PrefabFocus/PrefabFocusTests.cpp
Prefab/MockPrefabFileIOActionValidator.cpp
Prefab/MockPrefabFileIOActionValidator.h
Prefab/PrefabDuplicateTests.cpp
Prefab/PrefabEntityAliasTests.cpp
Prefab/PrefabInstanceToTemplatePropagatorTests.cpp
Prefab/PrefabInstantiateTests.cpp
Prefab/PrefabInstantiateTests.cpp
Prefab/PrefabLoadTemplateTests.cpp
Prefab/PrefabTestComponent.cpp
Prefab/PrefabTestComponent.h
Prefab/PrefabTestData.cpp
Prefab/PrefabTestData.h
Prefab/PrefabTestDataUtils.cpp
Prefab/PrefabTestDataUtils.h
Prefab/PrefabTestDomUtils.cpp
Prefab/PrefabTestDomUtils.h
Prefab/PrefabTestFixture.cpp
Prefab/PrefabTestFixture.h
Prefab/PrefabTestUndoFixture.cpp
Prefab/PrefabTestUndoFixture.h
Prefab/PrefabTestUtils.h
Prefab/PrefabUndoLinkTests.cpp
Prefab/PrefabUndoTests.cpp
Prefab/PrefabUpdateInstancesTests.cpp
Prefab/PrefabUpdateTemplateTests.cpp
Prefab/PrefabUpdateWithPatchesTests.cpp
Prefab/Spawnable/SpawnableMetaDataTests.cpp
Prefab/SpawnableCreateTests.cpp
Prefab/SpawnableRemoveEditorInfoTestFixture.cpp
Prefab/SpawnableRemoveEditorInfoTestFixture.h
Prefab/SpawnableRemoveEditorInfoTests.cpp
Prefab/SpawnableSortEntitiesTestFixture.cpp
Prefab/SpawnableSortEntitiesTestFixture.h
Prefab/SpawnableSortEntitiesTests.cpp
Prefab/PrefabScriptingTests.cpp
Prefab/ProceduralPrefabAssetTests.cpp
PropertyIntCtrlCommonTests.h
PropertyIntSliderCtrlTests.cpp
PropertyIntSpinCtrlTests.cpp
PropertyTreeEditorTests.cpp
PythonBindingTests.cpp
QtWidgetLimitsTests.cpp
Script/ScriptComponentTests.cpp
Script/ScriptEntityTests.cpp
Slice.cpp
Slices.cpp
SliceStabilityTests/SliceStabilityCreateTests.cpp
SliceStabilityTests/SliceStabilityPushTests.cpp
SliceStabilityTests/SliceStabilityReParentTests.cpp
SliceStabilityTests/SliceStabilityTestFramework.cpp
SliceStabilityTests/SliceStabilityTestFramework.h
SliceUpgradeTests.cpp
SliceUpgradeTestsData.h
SpinBoxTests.cpp
SQLiteConnectionTests.cpp
ThumbnailerTests.cpp
ToolsComponents/EditorLayerComponentTests.cpp
ToolsComponents/EditorTransformComponentTests.cpp
TransformComponent.cpp
UI/EntityIdQLineEditTests.cpp
UI/EntityOutlinerTests.cpp
UI/EntityPropertyEditorTests.cpp
UndoStack.cpp
Viewport/ClusterTests.cpp
Viewport/ViewportEditorModeTests.cpp
Viewport/ViewportScreenTests.cpp
Viewport/ViewportUiClusterTests.cpp
Viewport/ViewportUiDisplayTests.cpp
Viewport/ViewportUiManagerTests.cpp
Viewport/ViewportUiWidgetManagerTests.cpp
Visibility/EditorVisibilityTests.cpp
)