Skip to content

Commit 1e3782e

Browse files
K-TonetimkeoekcohPauliusd01MorganHoarau
authored
NEW: Support entering playmode with Domain Reload disabled ("Faster Enter Playmode") (#2343)
Co-authored-by: Tim Keosababian <36088732+timkeo@users.noreply.github.com> Co-authored-by: Håkan Sidenvall <hakan.sidenvall@unity3d.com> Co-authored-by: Paulius Dervinis <54306142+Pauliusd01@users.noreply.github.com> Co-authored-by: Morgan Hoarau <122548697+MorganHoarau@users.noreply.github.com>
1 parent afb1c33 commit 1e3782e

61 files changed

Lines changed: 1381 additions & 933 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/CoreTests_Actions.cs

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5524,56 +5524,68 @@ public class ModificationCases : IEnumerable
55245524
[Preserve]
55255525
public ModificationCases() {}
55265526

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

5544-
bool ModificationAppliesToSingleActionMap(Modification modification)
55455574
{
5546-
switch (modification)
5575+
var actionMap = new Func<IInputActionCollection2>(CreateMap);
5576+
foreach (var value in Enum.GetValues(typeof(Modification)))
55475577
{
5548-
case Modification.AddMap:
5549-
case Modification.RemoveMap:
5550-
return false;
5578+
if (ModificationAppliesToSingleActionMap.Contains((Modification)value))
5579+
yield return new TestCaseData(value, actionMap);
55515580
}
5552-
return true;
55535581
}
55545582

5555-
// NOTE: This executes *outside* of our test fixture during test discovery.
5556-
5557-
// Creates a matrix of all permutations of Modifications combined with assets, maps, and singleton actions.
5558-
foreach (var func in new Func<IInputActionCollection2>[] { () => new DefaultInputActions().asset, CreateMap, CreateSingletonAction })
55595583
{
5584+
var singletonMap = new Func<IInputActionCollection2>(CreateSingletonAction);
55605585
foreach (var value in Enum.GetValues(typeof(Modification)))
55615586
{
5562-
var actions = func();
5563-
if (actions is InputActionMap map)
5564-
{
5565-
if (map.m_SingletonAction != null)
5566-
{
5567-
if (!ModificationAppliesToSingletonAction((Modification)value))
5568-
continue;
5569-
}
5570-
else if (!ModificationAppliesToSingleActionMap((Modification)value))
5571-
{
5572-
continue;
5573-
}
5574-
}
5575-
5576-
yield return new TestCaseData(value, actions);
5587+
if (ModificationAppliesToSingletonAction.Contains((Modification)value))
5588+
yield return new TestCaseData(value, singletonMap);
55775589
}
55785590
}
55795591
}
@@ -5604,12 +5616,13 @@ private InputActionMap CreateSingletonAction()
56045616
[Test]
56055617
[Category("Actions")]
56065618
[TestCaseSource(typeof(ModificationCases))]
5607-
public void Actions_CanHandleModification(Modification modification, IInputActionCollection2 actions)
5619+
public void Actions_CanHandleModification(Modification modification, Func<IInputActionCollection2> getActions)
56085620
{
56095621
// Exclude project-wide actions from this test
56105622
InputSystem.actions?.Disable();
56115623
InputActionState.DestroyAllActionMapStates(); // Required for `onActionChange` to report correct number of changes
56125624

5625+
var actions = getActions();
56135626
var gamepad = InputSystem.AddDevice<Gamepad>();
56145627

56155628
if (modification == Modification.AddDevice || modification == Modification.RemoveDevice)
@@ -6339,12 +6352,12 @@ public void Actions_AddingSameProcessorTwice_DoesntImpactUIHideState()
63396352
InputSystem.RegisterProcessor<ConstantFloat1TestProcessor>();
63406353
Assert.That(InputSystem.TryGetProcessor("ConstantFloat1Test"), Is.Not.EqualTo(null));
63416354

6342-
bool hide = InputSystem.s_Manager.processors.ShouldHideInUI("ConstantFloat1Test");
6355+
bool hide = InputSystem.manager.processors.ShouldHideInUI("ConstantFloat1Test");
63436356
Assert.That(hide, Is.EqualTo(false));
63446357

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

@@ -6980,7 +6993,7 @@ public void Actions_RegisteringExistingInteractionUnderNewName_CreatesAlias()
69806993
{
69816994
InputSystem.RegisterInteraction<HoldInteraction>("TestTest");
69826995

6983-
Assert.That(InputSystem.s_Manager.interactions.aliases.Contains(new InternedString("TestTest")));
6996+
Assert.That(InputSystem.manager.interactions.aliases.Contains(new InternedString("TestTest")));
69846997
}
69856998

69866999
#endif // UNITY_EDITOR
@@ -9299,7 +9312,7 @@ public void Actions_RegisteringExistingCompositeUnderNewName_CreatesAlias()
92999312
{
93009313
InputSystem.RegisterBindingComposite<Vector2Composite>("TestTest");
93019314

9302-
Assert.That(InputSystem.s_Manager.composites.aliases.Contains(new InternedString("TestTest")));
9315+
Assert.That(InputSystem.manager.composites.aliases.Contains(new InternedString("TestTest")));
93039316
}
93049317

93059318
#endif // UNITY_EDITOR
@@ -11607,7 +11620,7 @@ public void Actions_DisablingAllActions_RemovesAllTheirStateMonitors()
1160711620

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

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
@@ -572,11 +572,11 @@ public void Devices_AddingDeviceThatUsesBeforeRenderUpdates_CausesBeforeRenderUp
572572

573573
InputSystem.RegisterLayout(deviceJson);
574574

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

577577
InputSystem.AddDevice("CustomGamepad");
578578

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

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

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

601601
InputSystem.RemoveDevice(device1);
602602

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

605605
InputSystem.RemoveDevice(device2);
606606

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

610610
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]
@@ -2961,16 +2964,16 @@ public void Editor_LeavingPlayMode_DestroysAllActionStates()
29612964
action.Enable();
29622965

29632966
Assert.That(InputActionState.s_GlobalState.globalList.length, Is.EqualTo(1));
2964-
Assert.That(InputSystem.s_Manager.m_StateChangeMonitors.Length, Is.GreaterThan(0));
2965-
Assert.That(InputSystem.s_Manager.m_StateChangeMonitors[0].count, Is.EqualTo(1));
2967+
Assert.That(InputSystem.manager.m_StateChangeMonitors.Length, Is.GreaterThan(0));
2968+
Assert.That(InputSystem.manager.m_StateChangeMonitors[0].count, Is.EqualTo(1));
29662969

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

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

29762979
[Test]

0 commit comments

Comments
 (0)