Skip to content

Commit 3b7340f

Browse files
FIX: out of range exception when pressing undo after creating and editing a new control scheme (ISXB-1607) (#2237)
Co-authored-by: Håkan Sidenvall <hakan.sidenvall@unity3d.com>
1 parent ad95eca commit 3b7340f

5 files changed

Lines changed: 56 additions & 14 deletions

File tree

Assets/Tests/InputSystem.Editor/InputActionsEditorTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public override void OneTimeSetUp()
1919
{
2020
base.OneTimeSetUp();
2121
m_Asset = AssetDatabaseUtils.CreateAsset<InputActionAsset>();
22+
m_Asset.AddControlScheme(new InputControlScheme("test"));
2223
var actionMap = m_Asset.AddActionMap("First Name");
2324
m_Asset.AddActionMap("Second Name");
2425
m_Asset.AddActionMap("Third Name");
@@ -234,5 +235,28 @@ public IEnumerator CanRenameAction()
234235
// Check on the asset side
235236
Assert.That(m_Window.currentAssetInEditor.actionMaps[0].actions[1].name, Is.EqualTo("New Name"));
236237
}
238+
239+
/// <summary>
240+
/// <see href="https://jira.unity3d.com/browse/ISXB-1607">ISXB-1607</see>
241+
/// Fix an out of range exception when pressing undo after creating and editing a new control scheme.
242+
/// </summary>
243+
/// <returns></returns>
244+
[UnityTest]
245+
[Ignore("Currently this is difficult to test, Darren - re-visit once we have converted the advanced dropdown to UIToolkit")]
246+
public IEnumerator CanUndoActionMap_ControlSchemeEdit()
247+
{
248+
var controlSchemeToolbarMenu = m_Window.rootVisualElement.Q("control-schemes-toolbar-menu");
249+
250+
// changing the selection triggers a state change, wait for the scheduler to process the frame
251+
yield return WaitForSchedulerLoop();
252+
yield return WaitForNotDirty();
253+
254+
SimulateClickOn(controlSchemeToolbarMenu);
255+
256+
yield return WaitForSchedulerLoop();
257+
yield return WaitForNotDirty();
258+
259+
yield return WaitForFocus(m_Window.rootVisualElement.Q("control-schemes-toolbar-menu"));
260+
}
237261
}
238262
#endif

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ however, it has to be formatted properly to pass verification tests.
8484
- Fixed the compilation warnings when used with Unity 6.4 (ISX-2349).
8585
- Fixed an issue where `InputSystemUIInputModule.localMultiPlayerRoot` could not be set to `null` when using `MultiplayerEventSystem`. [ISXB-1610](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1610)
8686
- Fixed an issue in `Keyboard` where the sub-script operator would return a `null` key control for the deprecated key `Key.IMESelected`. Now, an aliased `KeyControl`mapping to the IMESelected bit is returned for compability reasons. It is still strongly advised to not rely on this key since `IMESelected` bit isn't strictly a key and will be removed from the `Key` enumeration type in a future major revision. [ISXB-1541](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1541).
87+
- Fixed an ArgumentOutOfRangeException that was thrown when pressing the undo shortcut while changing a control scheme name. [ISXB-1607](https://issuetracker.unity3d.com/issues/argumentoutofrangeexception-error-is-thrown-when-pressing-the-undo-shortcut-while-changing-the-control-scheme-name)
8788
- Fixed an issue where the onAnyButtonPress callback would be triggered multiple times during unrelated events when a button is held down. See [ISXB-1005](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1005).
8889
- Fixed InputControl picker not updating correctly when the Input Actions Window was dirty. [ISXB-1221](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1221)
8990
- Fixed formatting issues on processor documentation page.

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/ControlSchemeCommands.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,16 @@ public static Command ResetSelectedControlScheme()
145145
{
146146
return (in InputActionsEditorState state) =>
147147
{
148-
var controlSchemeSerializedProperty = state.selectedControlSchemeIndex == -1 ? null :
149-
state.serializedObject
150-
.FindProperty(nameof(InputActionAsset.m_ControlSchemes))
151-
.GetArrayElementAtIndex(state.selectedControlSchemeIndex);
148+
SerializedProperty controlSchemeSerializedProperty = null;
149+
var serializedProperty = state.serializedObject
150+
.FindProperty(nameof(InputActionAsset.m_ControlSchemes));
151+
152+
if (state.selectedControlSchemeIndex < serializedProperty.arraySize)
153+
{
154+
controlSchemeSerializedProperty = state.selectedControlSchemeIndex == -1 ? null :
155+
serializedProperty
156+
.GetArrayElementAtIndex(state.selectedControlSchemeIndex);
157+
}
152158

153159
if (controlSchemeSerializedProperty == null)
154160
{

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ private void RemoveDeviceRequirement()
108108
public override void RedrawUI(InputControlScheme viewState)
109109
{
110110
rootElement.Q<TextField>(kControlSchemeNameTextField).value = string.IsNullOrEmpty(m_NewName) ? viewState.name : m_NewName;
111-
112111
m_ListView.itemsSource?.Clear();
113112
m_ListView.itemsSource = viewState.deviceRequirements.Count > 0 ?
114113
viewState.deviceRequirements.Select(r => (r.controlPath, r.isOptional)).ToList() :
@@ -128,7 +127,7 @@ private void SaveAndClose()
128127
CloseView();
129128
}
130129

131-
private void Cancel()
130+
internal void Cancel()
132131
{
133132
// Reload the selected ControlScheme values from the SerilaizedProperty and throw away any changes
134133
Dispatch(ControlSchemeCommands.ResetSelectedControlScheme());

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ internal class InputActionsEditorView : ViewBase<InputActionsEditorView.ViewStat
2424

2525
private readonly Action m_SaveAction;
2626

27+
private ControlSchemesView m_ControlSchemesView;
28+
2729
public InputActionsEditorView(VisualElement root, StateContainer stateContainer, bool isProjectSettings,
2830
Action saveAction)
2931
: base(root, stateContainer)
@@ -104,6 +106,13 @@ public InputActionsEditorView(VisualElement root, StateContainer stateContainer,
104106
});
105107

106108
s_OnPasteCutElements.Add(this);
109+
110+
Undo.undoRedoPerformed += CloseControlSchemeView;
111+
}
112+
113+
private void CloseControlSchemeView()
114+
{
115+
m_ControlSchemesView?.Cancel();
107116
}
108117

109118
private void OnReset()
@@ -156,9 +165,8 @@ private void SetUpControlSchemesMenu(ViewState viewState)
156165

157166
if (viewState.controlSchemes.Any())
158167
{
159-
m_ControlSchemesToolbar.text = viewState.selectedControlSchemeIndex == -1
160-
? "All Control Schemes"
161-
: viewState.controlSchemes.ElementAt(viewState.selectedControlSchemeIndex).name;
168+
var elementAtOrDefault = viewState.controlSchemes.ElementAtOrDefault(viewState.selectedControlSchemeIndex);
169+
m_ControlSchemesToolbar.text = elementAtOrDefault == default ? "All Control Schemes" : elementAtOrDefault.name;
162170

163171
m_ControlSchemesToolbar.menu.AppendAction("All Control Schemes", _ => SelectControlScheme(-1),
164172
viewState.selectedControlSchemeIndex == -1 ? DropdownMenuAction.Status.Checked : DropdownMenuAction.Status.Normal);
@@ -186,7 +194,7 @@ private void SetUpDevicesMenu(ViewState viewState)
186194
return;
187195
}
188196
m_DevicesToolbar.SetEnabled(true);
189-
var currentControlScheme = viewState.controlSchemes.ElementAt(viewState.selectedControlSchemeIndex);
197+
var currentControlScheme = viewState.controlSchemes.ElementAtOrDefault(viewState.selectedControlSchemeIndex);
190198
if (viewState.selectedDeviceIndex == -1)
191199
m_DevicesToolbar.text = "All Devices";
192200

@@ -228,10 +236,13 @@ private void DeleteControlScheme(DropdownMenuAction obj)
228236

229237
private void ShowControlSchemeEditor(VisualElement parent, bool updateExisting = false)
230238
{
231-
var controlSchemesView = CreateChildView(new ControlSchemesView(parent, stateContainer, updateExisting));
232-
controlSchemesView.UpdateView(stateContainer.GetState());
233-
234-
controlSchemesView.OnClosing += _ => DestroyChildView(controlSchemesView);
239+
m_ControlSchemesView = CreateChildView(new ControlSchemesView(parent, stateContainer, updateExisting));
240+
m_ControlSchemesView.UpdateView(stateContainer.GetState());
241+
m_ControlSchemesView.OnClosing += _ =>
242+
{
243+
DestroyChildView(m_ControlSchemesView);
244+
m_ControlSchemesView = null;
245+
};
235246
}
236247

237248
private void SelectControlScheme(int controlSchemeIndex)
@@ -258,6 +269,7 @@ public override void DestroyView()
258269
{
259270
base.DestroyView();
260271
s_OnPasteCutElements.Remove(this);
272+
Undo.undoRedoPerformed -= CloseControlSchemeView;
261273
}
262274

263275
public void OnPaste(InputActionsEditorState state)

0 commit comments

Comments
 (0)