Skip to content

Commit a5c9892

Browse files
committed
restored idDictionary functionality with a deterministic id for a guid.
1 parent 7e70fa8 commit a5c9892

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

Assets/Tests/InputSystem.Editor/SelectorsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public void GetActionsAsTreeViewData_ReturnsActionsAndBindingsAsTreeViewData()
2424
var actionTwo = actionMap.AddAction("Action2", binding: "<Keyboard>/d");
2525

2626

27-
var treeViewData = Selectors.GetActionsAsTreeViewData(TestData.EditorStateWithAsset(asset).Generate());
27+
var treeViewData = Selectors.GetActionsAsTreeViewData(TestData.EditorStateWithAsset(asset).Generate(), new Dictionary<Guid, int>());
2828

2929

3030
Assert.That(treeViewData.Count, Is.EqualTo(2));

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ internal class ActionsTreeView : ViewBase<ActionsTreeView.ViewState>
2626
private bool m_RenameOnActionAdded;
2727
private readonly CollectionViewSelectionChangeFilter m_ActionsTreeViewSelectionChangeFilter;
2828

29+
//save TreeView element id's of individual input actions and bindings to ensure saving of expanded state
30+
private Dictionary<Guid, int> m_GuidToTreeViewId;
31+
2932
public ActionsTreeView(VisualElement root, StateContainer stateContainer)
3033
: base(root, stateContainer)
3134
{
@@ -35,6 +38,7 @@ public ActionsTreeView(VisualElement root, StateContainer stateContainer)
3538
m_ActionsTreeView = root.Q<TreeView>("actions-tree-view");
3639
//assign unique viewDataKey to store treeView states like expanded/collapsed items - make it unique to avoid conflicts with other TreeViews
3740
m_ActionsTreeView.viewDataKey = $"InputActionTreeView_{stateContainer.assetGUID}";
41+
m_GuidToTreeViewId = new Dictionary<Guid, int>();
3842
m_ActionsTreeView.selectionType = UIElements.SelectionType.Single;
3943
m_ActionsTreeView.makeItem = () => new InputActionsTreeViewItem();
4044
m_ActionsTreeView.reorderable = true;
@@ -143,7 +147,7 @@ public ActionsTreeView(VisualElement root, StateContainer stateContainer)
143147
CreateSelector(Selectors.GetActionsForSelectedActionMap, Selectors.GetActionMapCount,
144148
(_, count, state) =>
145149
{
146-
var treeData = Selectors.GetActionsAsTreeViewData(state);
150+
var treeData = Selectors.GetActionsAsTreeViewData(state, m_GuidToTreeViewId);
147151
return new ViewState
148152
{
149153
treeViewData = treeData,
@@ -568,7 +572,7 @@ public ActionOrBindingData(bool isAction, string name, int actionMapIndex, bool
568572

569573
internal static partial class Selectors
570574
{
571-
public static List<TreeViewItemData<ActionOrBindingData>> GetActionsAsTreeViewData(InputActionsEditorState state)
575+
public static List<TreeViewItemData<ActionOrBindingData>> GetActionsAsTreeViewData(InputActionsEditorState state, Dictionary<Guid, int> idDictionary)
572576
{
573577
var actionMapIndex = state.selectedActionMapIndex;
574578
var controlSchemes = state.serializedObject.FindProperty(nameof(InputActionAsset.m_ControlSchemes));
@@ -587,13 +591,12 @@ public static List<TreeViewItemData<ActionOrBindingData>> GetActionsAsTreeViewDa
587591
.ToList();
588592

589593
var actionItems = new List<TreeViewItemData<ActionOrBindingData>>();
590-
var treeviewItemIDCounter = 0;
591594
foreach (var action in actions)
592595
{
593596
var actionBindings = bindings.Where(spb => spb.action == action.name).ToList();
594597
var bindingItems = new List<TreeViewItemData<ActionOrBindingData>>();
595598
var actionId = new Guid(action.id);
596-
599+
597600
for (var i = 0; i < actionBindings.Count; i++)
598601
{
599602
var serializedInputBinding = actionBindings[i];
@@ -616,7 +619,7 @@ public static List<TreeViewItemData<ActionOrBindingData>> GetActionsAsTreeViewDa
616619
if (isVisible)
617620
{
618621
var name = GetHumanReadableCompositeName(nextBinding, state.selectedControlScheme, controlSchemes);
619-
compositeItems.Add(new TreeViewItemData<ActionOrBindingData>(treeviewItemIDCounter++,
622+
compositeItems.Add(new TreeViewItemData<ActionOrBindingData>(GetIdForGuid(new Guid(nextBinding.id), idDictionary),
620623
new ActionOrBindingData(isAction: false, name, actionMapIndex, isComposite: false,
621624
isPartOfComposite: true, GetControlLayout(nextBinding.path), bindingIndex: nextBinding.indexOfBinding, isCut: state.IsBindingCut(actionMapIndex, nextBinding.indexOfBinding))));
622625
}
@@ -634,26 +637,39 @@ public static List<TreeViewItemData<ActionOrBindingData>> GetActionsAsTreeViewDa
634637

635638
var shouldCompositeBeVisible = !(compositeItems.Count == 0 && hasHiddenCompositeParts); //hide composite if all parts are hidden
636639
if (shouldCompositeBeVisible)
637-
bindingItems.Add(new TreeViewItemData<ActionOrBindingData>(treeviewItemIDCounter++,
640+
bindingItems.Add(new TreeViewItemData<ActionOrBindingData>(GetIdForGuid(inputBindingId, idDictionary),
638641
new ActionOrBindingData(isAction: false, serializedInputBinding.name, actionMapIndex, isComposite: true, isPartOfComposite: false, action.expectedControlType, bindingIndex: serializedInputBinding.indexOfBinding, isCut: state.IsBindingCut(actionMapIndex, serializedInputBinding.indexOfBinding)),
639642
compositeItems.Count > 0 ? compositeItems : null));
640643
}
641644
else
642645
{
643646
var isVisible = ShouldBindingBeVisible(serializedInputBinding, state.selectedControlScheme, state.selectedDeviceRequirementIndex);
644647
if (isVisible)
645-
bindingItems.Add(new TreeViewItemData<ActionOrBindingData>(treeviewItemIDCounter++,
648+
bindingItems.Add(new TreeViewItemData<ActionOrBindingData>(GetIdForGuid(inputBindingId, idDictionary),
646649
new ActionOrBindingData(isAction: false, GetHumanReadableBindingName(serializedInputBinding, state.selectedControlScheme, controlSchemes), actionMapIndex,
647650
isComposite: false, isPartOfComposite: false, GetControlLayout(serializedInputBinding.path), bindingIndex: serializedInputBinding.indexOfBinding, isCut: state.IsBindingCut(actionMapIndex, serializedInputBinding.indexOfBinding))));
648651
}
649652
}
650653
var actionIndex = action.wrappedProperty.GetIndexOfArrayElement();
651-
actionItems.Add(new TreeViewItemData<ActionOrBindingData>(treeviewItemIDCounter++,
654+
actionItems.Add(new TreeViewItemData<ActionOrBindingData>(GetIdForGuid(actionId, idDictionary),
652655
new ActionOrBindingData(isAction: true, action.name, actionMapIndex, isComposite: false, isPartOfComposite: false, action.expectedControlType, actionIndex: actionIndex, isCut: state.IsActionCut(actionMapIndex, actionIndex)), bindingItems.Count > 0 ? bindingItems : null));
653656
}
654657
return actionItems;
655658
}
656659

660+
private static int GetIdForGuid(Guid guid, Dictionary<Guid, int> idDictionary)
661+
{
662+
//This method is used to ensure that the same Guid always gets the same id
663+
//We use getHashCode instead of a counter, as we cannot guarantee that the same Guid will always be added in the same order
664+
//There is a tiny chance of a collision, but it is it does happen it will only affect the expanded state of the tree view
665+
if (!idDictionary.TryGetValue(guid, out var id))
666+
{
667+
id = guid.GetHashCode(); //idDictionary.Values.Count > 0 ? idDictionary.Values.Max() + 1 : 0;
668+
idDictionary.Add(guid, id);
669+
}
670+
return id;
671+
}
672+
657673
private static string GetHumanReadableBindingName(SerializedInputBinding serializedInputBinding, InputControlScheme? currentControlScheme, SerializedProperty allControlSchemes)
658674
{
659675
var name = InputControlPath.ToHumanReadableString(serializedInputBinding.path);

0 commit comments

Comments
 (0)