Skip to content

Commit 2aad9f2

Browse files
Merge branch 'develop' into input/add-focus-events-to-queue
# Conflicts: # Packages/com.unity.inputsystem/InputSystem/InputManager.cs # Packages/com.unity.inputsystem/Tests/TestFixture/InputTestFixture.cs
2 parents 5b92fe7 + dc22083 commit 2aad9f2

67 files changed

Lines changed: 1471 additions & 977 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Assets/Tests/InputSystem/APIVerificationTests.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,9 @@ public void API_MonoBehavioursHaveHelpUrls()
243243
var monoBehaviourTypes = typeof(InputSystem).Assembly.ExportedTypes.Where(t =>
244244
t.IsPublic && !t.IsAbstract && !IgnoreTypeForDocsByName(t.FullName) && !IgnoreTypeForDocsByNamespace(t.Namespace) &&
245245
typeof(MonoBehaviour).IsAssignableFrom(t));
246-
var monoBehaviourTypesHelpUrls =
247-
monoBehaviourTypes.Where(t => t.GetCustomAttribute<HelpURLAttribute>() != null)
248-
.Select(t => t.GetCustomAttribute<HelpURLAttribute>().URL);
249-
var monoBehaviourTypesWithoutHelpUrls =
250-
monoBehaviourTypes.Where(t => t.GetCustomAttribute<HelpURLAttribute>() == null);
251246

247+
var monoBehaviourTypesHelpUrls = monoBehaviourTypes.Where(t => t.GetCustomAttributes<HelpURLAttribute>().Any()).Select(t => t.GetCustomAttributes<HelpURLAttribute>().First().URL);
248+
var monoBehaviourTypesWithoutHelpUrls = monoBehaviourTypes.Where(t => !t.GetCustomAttributes<HelpURLAttribute>().Any());
252249
Assert.That(monoBehaviourTypesWithoutHelpUrls, Is.Empty);
253250
Assert.That(monoBehaviourTypesHelpUrls, Has.All.StartWith(InputSystem.kDocUrl));
254251
}

Assets/Tests/InputSystem/CoreTests_Actions.cs

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5527,56 +5527,68 @@ public class ModificationCases : IEnumerable
55275527
[Preserve]
55285528
public ModificationCases() {}
55295529

5530+
private static readonly Modification[] ModificationAppliesToSingleActionMap =
5531+
{
5532+
Modification.AddBinding,
5533+
Modification.RemoveBinding,
5534+
Modification.ModifyBinding,
5535+
Modification.ApplyBindingOverride,
5536+
Modification.AddAction,
5537+
Modification.RemoveAction,
5538+
Modification.ChangeBindingMask,
5539+
Modification.AddDevice,
5540+
Modification.RemoveDevice,
5541+
Modification.AddDeviceGlobally,
5542+
Modification.RemoveDeviceGlobally,
5543+
// Excludes: AddMap, RemoveMap
5544+
};
5545+
5546+
private static readonly Modification[] ModificationAppliesToSingletonAction =
5547+
{
5548+
Modification.AddBinding,
5549+
Modification.RemoveBinding,
5550+
Modification.ModifyBinding,
5551+
Modification.ApplyBindingOverride,
5552+
Modification.AddDeviceGlobally,
5553+
Modification.RemoveDeviceGlobally,
5554+
};
5555+
55305556
public IEnumerator GetEnumerator()
55315557
{
5532-
bool ModificationAppliesToSingletonAction(Modification modification)
5558+
// NOTE: This executes *outside* of our test fixture during test discovery.
5559+
5560+
// We cannot directly create the InputAction objects within GetEnumerator() because the underlying
5561+
// asset object might be invalid by the time the tests are actually run.
5562+
//
5563+
// That is, NUnit TestCases are generated once when the Assembly is loaded and will persist until it's unloaded,
5564+
// meaning they'll never be recreated without a Domain Reload. However, since InputActionAsset is a ScriptableObject,
5565+
// it could be deleted or otherwise invalidated between test case creation and actual test execution.
5566+
//
5567+
// So, instead we'll create a delegate to create the Actions object as the parameter for each test case, allowing
5568+
// the test case to create an Actions object itself when it actually runs.
55335569
{
5534-
switch (modification)
5570+
var actionsFromAsset = new Func<IInputActionCollection2>(() => new DefaultInputActions().asset);
5571+
foreach (var value in Enum.GetValues(typeof(Modification)))
55355572
{
5536-
case Modification.AddBinding:
5537-
case Modification.RemoveBinding:
5538-
case Modification.ModifyBinding:
5539-
case Modification.ApplyBindingOverride:
5540-
case Modification.AddDeviceGlobally:
5541-
case Modification.RemoveDeviceGlobally:
5542-
return true;
5573+
yield return new TestCaseData(value, actionsFromAsset);
55435574
}
5544-
return false;
55455575
}
55465576

5547-
bool ModificationAppliesToSingleActionMap(Modification modification)
55485577
{
5549-
switch (modification)
5578+
var actionMap = new Func<IInputActionCollection2>(CreateMap);
5579+
foreach (var value in Enum.GetValues(typeof(Modification)))
55505580
{
5551-
case Modification.AddMap:
5552-
case Modification.RemoveMap:
5553-
return false;
5581+
if (ModificationAppliesToSingleActionMap.Contains((Modification)value))
5582+
yield return new TestCaseData(value, actionMap);
55545583
}
5555-
return true;
55565584
}
55575585

5558-
// NOTE: This executes *outside* of our test fixture during test discovery.
5559-
5560-
// Creates a matrix of all permutations of Modifications combined with assets, maps, and singleton actions.
5561-
foreach (var func in new Func<IInputActionCollection2>[] { () => new DefaultInputActions().asset, CreateMap, CreateSingletonAction })
55625586
{
5587+
var singletonMap = new Func<IInputActionCollection2>(CreateSingletonAction);
55635588
foreach (var value in Enum.GetValues(typeof(Modification)))
55645589
{
5565-
var actions = func();
5566-
if (actions is InputActionMap map)
5567-
{
5568-
if (map.m_SingletonAction != null)
5569-
{
5570-
if (!ModificationAppliesToSingletonAction((Modification)value))
5571-
continue;
5572-
}
5573-
else if (!ModificationAppliesToSingleActionMap((Modification)value))
5574-
{
5575-
continue;
5576-
}
5577-
}
5578-
5579-
yield return new TestCaseData(value, actions);
5590+
if (ModificationAppliesToSingletonAction.Contains((Modification)value))
5591+
yield return new TestCaseData(value, singletonMap);
55805592
}
55815593
}
55825594
}
@@ -5607,12 +5619,13 @@ private InputActionMap CreateSingletonAction()
56075619
[Test]
56085620
[Category("Actions")]
56095621
[TestCaseSource(typeof(ModificationCases))]
5610-
public void Actions_CanHandleModification(Modification modification, IInputActionCollection2 actions)
5622+
public void Actions_CanHandleModification(Modification modification, Func<IInputActionCollection2> getActions)
56115623
{
56125624
// Exclude project-wide actions from this test
56135625
InputSystem.actions?.Disable();
56145626
InputActionState.DestroyAllActionMapStates(); // Required for `onActionChange` to report correct number of changes
56155627

5628+
var actions = getActions();
56165629
var gamepad = InputSystem.AddDevice<Gamepad>();
56175630

56185631
if (modification == Modification.AddDevice || modification == Modification.RemoveDevice)
@@ -6342,12 +6355,12 @@ public void Actions_AddingSameProcessorTwice_DoesntImpactUIHideState()
63426355
InputSystem.RegisterProcessor<ConstantFloat1TestProcessor>();
63436356
Assert.That(InputSystem.TryGetProcessor("ConstantFloat1Test"), Is.Not.EqualTo(null));
63446357

6345-
bool hide = InputSystem.s_Manager.processors.ShouldHideInUI("ConstantFloat1Test");
6358+
bool hide = InputSystem.manager.processors.ShouldHideInUI("ConstantFloat1Test");
63466359
Assert.That(hide, Is.EqualTo(false));
63476360

63486361
InputSystem.RegisterProcessor<ConstantFloat1TestProcessor>();
63496362
// Check we haven't caused this to alias with itself and cause it to be hidden in the UI
6350-
hide = InputSystem.s_Manager.processors.ShouldHideInUI("ConstantFloat1Test");
6363+
hide = InputSystem.manager.processors.ShouldHideInUI("ConstantFloat1Test");
63516364
Assert.That(hide, Is.EqualTo(false));
63526365
}
63536366

@@ -6983,7 +6996,7 @@ public void Actions_RegisteringExistingInteractionUnderNewName_CreatesAlias()
69836996
{
69846997
InputSystem.RegisterInteraction<HoldInteraction>("TestTest");
69856998

6986-
Assert.That(InputSystem.s_Manager.interactions.aliases.Contains(new InternedString("TestTest")));
6999+
Assert.That(InputSystem.manager.interactions.aliases.Contains(new InternedString("TestTest")));
69877000
}
69887001

69897002
#endif // UNITY_EDITOR
@@ -9302,7 +9315,7 @@ public void Actions_RegisteringExistingCompositeUnderNewName_CreatesAlias()
93029315
{
93039316
InputSystem.RegisterBindingComposite<Vector2Composite>("TestTest");
93049317

9305-
Assert.That(InputSystem.s_Manager.composites.aliases.Contains(new InternedString("TestTest")));
9318+
Assert.That(InputSystem.manager.composites.aliases.Contains(new InternedString("TestTest")));
93069319
}
93079320

93089321
#endif // UNITY_EDITOR
@@ -11610,7 +11623,7 @@ public void Actions_DisablingAllActions_RemovesAllTheirStateMonitors()
1161011623

1161111624
// Not the most elegant test as we reach into internals here but with the
1161211625
// current API, it's not possible to enumerate monitors from outside.
11613-
Assert.That(InputSystem.s_Manager.m_StateChangeMonitors,
11626+
Assert.That(InputSystem.manager.m_StateChangeMonitors,
1161411627
Has.All.Matches(
1161511628
(InputManager.StateChangeMonitorsForDevice x) => x.memoryRegions.All(r => r.sizeInBits == 0)));
1161611629
}

Assets/Tests/InputSystem/CoreTests_Analytics.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,6 @@ public void Analytics_ShouldReportBuildAnalytics_WhenNotHavingSettingsAsset()
409409
{
410410
CollectAnalytics(InputBuildAnalytic.kEventName);
411411

412-
var storedSettings = InputSystem.s_Manager.settings;
413412
InputSettings defaultSettings = null;
414413

415414
try
@@ -462,7 +461,6 @@ public void Analytics_ShouldReportBuildAnalytics_WhenNotHavingSettingsAsset()
462461
}
463462
finally
464463
{
465-
InputSystem.s_Manager.settings = storedSettings;
466464
if (defaultSettings != null)
467465
Object.DestroyImmediate(defaultSettings);
468466
}
@@ -474,7 +472,6 @@ public void Analytics_ShouldReportBuildAnalytics_WhenHavingSettingsAssetWithCust
474472
{
475473
CollectAnalytics(InputBuildAnalytic.kEventName);
476474

477-
var storedSettings = InputSystem.s_Manager.settings;
478475
InputSettings customSettings = null;
479476

480477
try
@@ -558,7 +555,6 @@ public void Analytics_ShouldReportBuildAnalytics_WhenHavingSettingsAssetWithCust
558555
}
559556
finally
560557
{
561-
InputSystem.s_Manager.settings = storedSettings;
562558
if (customSettings != null)
563559
Object.DestroyImmediate(customSettings);
564560
}

Assets/Tests/InputSystem/CoreTests_Devices.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -573,11 +573,11 @@ public void Devices_AddingDeviceThatUsesBeforeRenderUpdates_CausesBeforeRenderUp
573573

574574
InputSystem.RegisterLayout(deviceJson);
575575

576-
Assert.That(InputSystem.s_Manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo((InputUpdateType)0));
576+
Assert.That(InputSystem.manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo((InputUpdateType)0));
577577

578578
InputSystem.AddDevice("CustomGamepad");
579579

580-
Assert.That(InputSystem.s_Manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo(InputUpdateType.BeforeRender));
580+
Assert.That(InputSystem.manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo(InputUpdateType.BeforeRender));
581581
}
582582

583583
[Test]
@@ -597,15 +597,15 @@ public void Devices_RemovingLastDeviceThatUsesBeforeRenderUpdates_CausesBeforeRe
597597
var device1 = InputSystem.AddDevice("CustomGamepad");
598598
var device2 = InputSystem.AddDevice("CustomGamepad");
599599

600-
Assert.That(InputSystem.s_Manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo(InputUpdateType.BeforeRender));
600+
Assert.That(InputSystem.manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo(InputUpdateType.BeforeRender));
601601

602602
InputSystem.RemoveDevice(device1);
603603

604-
Assert.That(InputSystem.s_Manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo(InputUpdateType.BeforeRender));
604+
Assert.That(InputSystem.manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo(InputUpdateType.BeforeRender));
605605

606606
InputSystem.RemoveDevice(device2);
607607

608-
Assert.That(InputSystem.s_Manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo((InputUpdateType)0));
608+
Assert.That(InputSystem.manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo((InputUpdateType)0));
609609
}
610610

611611
private class TestDeviceReceivingAddAndRemoveNotification : Mouse

Assets/Tests/InputSystem/CoreTests_Editor.cs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ public void Editor_CanSaveAndRestoreState()
147147
}.ToJson());
148148
InputSystem.Update();
149149

150-
InputSystem.SaveAndReset();
150+
m_StateManager.SaveAndReset(enableRemoting: false, runtime: null);
151151

152152
Assert.That(InputSystem.devices, Has.Count.EqualTo(0));
153153

154-
InputSystem.Restore();
154+
m_StateManager.Restore();
155155

156156
Assert.That(InputSystem.devices,
157157
Has.Exactly(1).With.Property("layout").EqualTo("MyDevice").And.TypeOf<Gamepad>());
@@ -165,6 +165,7 @@ public void Editor_CanSaveAndRestoreState()
165165
Assert.That(unsupportedDevices[0].interfaceName, Is.EqualTo("Test"));
166166
}
167167

168+
#if !ENABLE_CORECLR
168169
// onFindLayoutForDevice allows dynamically injecting new layouts into the system that
169170
// are custom-tailored at runtime for the discovered device. Make sure that our domain
170171
// reload can restore these.
@@ -195,12 +196,12 @@ public void Editor_DomainReload_CanRestoreDevicesBuiltWithDynamicallyGeneratedLa
195196

196197
Assert.That(InputSystem.devices, Has.Exactly(1).TypeOf<HID>());
197198

198-
InputSystem.SaveAndReset();
199+
m_StateManager.SaveAndReset(false, null);
199200

200201
Assert.That(InputSystem.devices, Is.Empty);
201202

202-
var state = InputSystem.GetSavedState();
203-
var manager = InputSystem.s_Manager;
203+
var state = m_StateManager.GetSavedState();
204+
var manager = InputSystem.manager;
204205

205206
manager.m_SavedAvailableDevices = state.managerState.availableDevices;
206207
manager.m_SavedDeviceStates = state.managerState.devices;
@@ -209,7 +210,7 @@ public void Editor_DomainReload_CanRestoreDevicesBuiltWithDynamicallyGeneratedLa
209210

210211
Assert.That(InputSystem.devices, Has.Exactly(1).TypeOf<HID>());
211212

212-
InputSystem.Restore();
213+
m_StateManager.Restore();
213214
}
214215

215216
[Test]
@@ -219,7 +220,7 @@ public void Editor_DomainReload_PreservesUsagesOnDevices()
219220
var device = InputSystem.AddDevice<Gamepad>();
220221
InputSystem.SetDeviceUsage(device, CommonUsages.LeftHand);
221222

222-
SimulateDomainReload();
223+
InputSystem.TestHook_SimulateDomainReload(runtime);
223224

224225
var newDevice = InputSystem.devices[0];
225226

@@ -239,7 +240,7 @@ public void Editor_DomainReload_PreservesEnabledState()
239240

240241
Assert.That(device.enabled, Is.False);
241242

242-
SimulateDomainReload();
243+
InputSystem.TestHook_SimulateDomainReload(runtime);
243244

244245
var newDevice = InputSystem.devices[0];
245246

@@ -252,7 +253,7 @@ public void Editor_DomainReload_InputSystemInitializationCausesDevicesToBeRecrea
252253
{
253254
InputSystem.AddDevice<Gamepad>();
254255

255-
SimulateDomainReload();
256+
InputSystem.TestHook_SimulateDomainReload(runtime);
256257

257258
Assert.That(InputSystem.devices, Has.Count.EqualTo(1));
258259
Assert.That(InputSystem.devices[0], Is.TypeOf<Gamepad>());
@@ -289,7 +290,7 @@ public void Editor_DomainReload_CustomDevicesAreRestoredAsLayoutsBecomeAvailable
289290
InputSystem.RegisterLayout(kLayout);
290291
InputSystem.AddDevice("CustomDevice");
291292

292-
SimulateDomainReload();
293+
InputSystem.TestHook_SimulateDomainReload(runtime);
293294

294295
Assert.That(InputSystem.devices, Is.Empty);
295296

@@ -310,7 +311,7 @@ public void Editor_DomainReload_RetainsUnsupportedDevices()
310311
});
311312
InputSystem.Update();
312313

313-
SimulateDomainReload();
314+
InputSystem.TestHook_SimulateDomainReload(runtime);
314315

315316
Assert.That(InputSystem.GetUnsupportedDevices(), Has.Count.EqualTo(1));
316317
Assert.That(InputSystem.GetUnsupportedDevices()[0].interfaceName, Is.EqualTo("SomethingUnknown"));
@@ -346,19 +347,21 @@ public void Editor_DomainReload_CanRemoveDevicesDuringDomainReload()
346347
Assert.That(InputSystem.devices[0], Is.AssignableTo<Keyboard>());
347348
}
348349

350+
#endif // !ENABLE_CORECLR
351+
349352
[Test]
350353
[Category("Editor")]
351354
public void Editor_RestoringStateWillCleanUpEventHooks()
352355
{
353-
InputSystem.SaveAndReset();
356+
m_StateManager.SaveAndReset(false, null);
354357

355358
var receivedOnEvent = 0;
356359
var receivedOnDeviceChange = 0;
357360

358361
InputSystem.onEvent += (e, d) => ++ receivedOnEvent;
359362
InputSystem.onDeviceChange += (c, d) => ++ receivedOnDeviceChange;
360363

361-
InputSystem.Restore();
364+
m_StateManager.Restore();
362365

363366
var device = InputSystem.AddDevice("Gamepad");
364367
InputSystem.QueueStateEvent(device, new GamepadState());
@@ -375,8 +378,8 @@ public void Editor_RestoringStateWillRestoreObjectsOfLayoutBuilder()
375378
var builder = new TestLayoutBuilder {layoutToLoad = "Gamepad"};
376379
InputSystem.RegisterLayoutBuilder(() => builder.DoIt(), "TestLayout");
377380

378-
InputSystem.SaveAndReset();
379-
InputSystem.Restore();
381+
m_StateManager.SaveAndReset(false, null);
382+
m_StateManager.Restore();
380383

381384
var device = InputSystem.AddDevice("TestLayout");
382385

@@ -2504,7 +2507,7 @@ public void TODO_Editor_SettingsModifiedInPlayMode_AreRestoredWhenReEnteringEdit
25042507
[Category("Editor")]
25052508
public void Editor_AlwaysKeepsEditorUpdatesEnabled()
25062509
{
2507-
Assert.That(InputSystem.s_Manager.updateMask & InputUpdateType.Editor, Is.EqualTo(InputUpdateType.Editor));
2510+
Assert.That(InputSystem.manager.updateMask & InputUpdateType.Editor, Is.EqualTo(InputUpdateType.Editor));
25082511
}
25092512

25102513
[Test]
@@ -2962,16 +2965,16 @@ public void Editor_LeavingPlayMode_DestroysAllActionStates()
29622965
action.Enable();
29632966

29642967
Assert.That(InputActionState.s_GlobalState.globalList.length, Is.EqualTo(1));
2965-
Assert.That(InputSystem.s_Manager.m_StateChangeMonitors.Length, Is.GreaterThan(0));
2966-
Assert.That(InputSystem.s_Manager.m_StateChangeMonitors[0].count, Is.EqualTo(1));
2968+
Assert.That(InputSystem.manager.m_StateChangeMonitors.Length, Is.GreaterThan(0));
2969+
Assert.That(InputSystem.manager.m_StateChangeMonitors[0].count, Is.EqualTo(1));
29672970

29682971
// Exit play mode.
29692972
InputSystem.OnPlayModeChange(PlayModeStateChange.ExitingPlayMode);
29702973
InputSystem.OnPlayModeChange(PlayModeStateChange.EnteredEditMode);
29712974

29722975
Assert.That(InputActionState.s_GlobalState.globalList.length, Is.Zero);
29732976
// Won't get removed, just cleared.
2974-
Assert.That(InputSystem.s_Manager.m_StateChangeMonitors[0].listeners[0].control, Is.Null);
2977+
Assert.That(InputSystem.manager.m_StateChangeMonitors[0].listeners[0].control, Is.Null);
29752978
}
29762979

29772980
[Test]

0 commit comments

Comments
 (0)