Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: ISXB-1085 Fast-enter play-mode #2016

Draft
wants to merge 20 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d7fdac4
Implement basic support for FEPM (ISX-1842)
timkeo Jan 23, 2024
7371ea8
Refactor InputManager and tests for cleaner init flows (ISX-1842)
timkeo Jan 26, 2024
b1bf0b8
Refactor ProjectWideActions to fix initialization with FEPM (ISX-1840)
timkeo Jan 31, 2024
c8efa00
Refactor various InputSystem members to improved separation of concer…
timkeo Feb 1, 2024
a58a65a
Fix branch after rebasing with develop (ISX-1840)
timkeo Mar 21, 2024
c534e18
Refactor DeferBindingResolution to remove statics (ISX-1840)
timkeo Apr 5, 2024
e042a1f
Refactor GlobalState usages to re-initialize statics (ISX-1840)
timkeo Apr 10, 2024
d1aba5c
Update Plugin classes to fix static usages (ISX-1840)
timkeo Apr 11, 2024
bc2d23e
Misc refactoring to clean up static fields and other small improvemen…
timkeo Apr 18, 2024
bef9515
Address InputSystem refactor PR feedback
timkeo May 23, 2024
86f3f85
Merge branch 'develop' into isxb-1085-fepm-revisited
ekcoh Sep 27, 2024
2ce3827
Merge branch 'develop' into isxb-1085-fepm-revisited
ekcoh Sep 27, 2024
53c1763
Fixed merge conflicts, exceptions throw during type registration and …
ekcoh Oct 16, 2024
b70cea0
Removed obsolete settings restore in analytics tests
ekcoh Oct 16, 2024
4abe485
Merge branch 'develop' into isxb-1085-fepm-revisited
ekcoh Oct 16, 2024
a1a4377
Resolved merge conflict
ekcoh Oct 16, 2024
bd61d0f
Backport of ISXB-937
ekcoh Oct 16, 2024
c25f851
Reverted accidental edits from previous merge
ekcoh Oct 16, 2024
657313e
Added missing statement to InputActionMap
ekcoh Oct 16, 2024
54f072a
Rerun formatter
ekcoh Oct 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 58 additions & 46 deletions Assets/Tests/InputSystem/CoreTests_Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5321,56 +5321,68 @@ public class ModificationCases : IEnumerable
[Preserve]
public ModificationCases() {}

private static readonly Modification[] ModificationAppliesToSingleActionMap =
{
Modification.AddBinding,
Modification.RemoveBinding,
Modification.ModifyBinding,
Modification.ApplyBindingOverride,
Modification.AddAction,
Modification.RemoveAction,
Modification.ChangeBindingMask,
Modification.AddDevice,
Modification.RemoveDevice,
Modification.AddDeviceGlobally,
Modification.RemoveDeviceGlobally,
// Excludes: AddMap, RemoveMap
};

private static readonly Modification[] ModificationAppliesToSingletonAction =
{
Modification.AddBinding,
Modification.RemoveBinding,
Modification.ModifyBinding,
Modification.ApplyBindingOverride,
Modification.AddDeviceGlobally,
Modification.RemoveDeviceGlobally,
};

public IEnumerator GetEnumerator()
{
bool ModificationAppliesToSingletonAction(Modification modification)
// NOTE: This executes *outside* of our test fixture during test discovery.

// We cannot directly create the InputAction objects within GetEnumerator() because the underlying
// asset object might be invalid by the time the tests are actually run.
//
// That is, NUnit TestCases are generated once when the Assembly is loaded and will persist until it's unloaded,
// meaning they'll never be recreated without a Domain Reload. However, since InputActionAsset is a ScriptableObject,
// it could be deleted or otherwise invalidated between test case creation and actual test execution.
//
// So, instead we'll create a delegate to create the Actions object as the parameter for each test case, allowing
// the test case to create an Actions object itself when it actually runs.
{
switch (modification)
var actionsFromAsset = new Func<IInputActionCollection2>(() => new DefaultInputActions().asset);
foreach (var value in Enum.GetValues(typeof(Modification)))
{
case Modification.AddBinding:
case Modification.RemoveBinding:
case Modification.ModifyBinding:
case Modification.ApplyBindingOverride:
case Modification.AddDeviceGlobally:
case Modification.RemoveDeviceGlobally:
return true;
yield return new TestCaseData(value, actionsFromAsset);
}
return false;
}

bool ModificationAppliesToSingleActionMap(Modification modification)
{
switch (modification)
var actionMap = new Func<IInputActionCollection2>(CreateMap);
foreach (var value in Enum.GetValues(typeof(Modification)))
{
case Modification.AddMap:
case Modification.RemoveMap:
return false;
if (ModificationAppliesToSingleActionMap.Contains((Modification)value))
yield return new TestCaseData(value, actionMap);
}
return true;
}

// NOTE: This executes *outside* of our test fixture during test discovery.

// Creates a matrix of all permutations of Modifications combined with assets, maps, and singleton actions.
foreach (var func in new Func<IInputActionCollection2>[] { () => new DefaultInputActions().asset, CreateMap, CreateSingletonAction })
{
var singletonMap = new Func<IInputActionCollection2>(CreateSingletonAction);
foreach (var value in Enum.GetValues(typeof(Modification)))
{
var actions = func();
if (actions is InputActionMap map)
{
if (map.m_SingletonAction != null)
{
if (!ModificationAppliesToSingletonAction((Modification)value))
continue;
}
else if (!ModificationAppliesToSingleActionMap((Modification)value))
{
continue;
}
}

yield return new TestCaseData(value, actions);
if (ModificationAppliesToSingletonAction.Contains((Modification)value))
yield return new TestCaseData(value, singletonMap);
}
}
}
Expand Down Expand Up @@ -5401,14 +5413,14 @@ private InputActionMap CreateSingletonAction()
[Test]
[Category("Actions")]
[TestCaseSource(typeof(ModificationCases))]
public void Actions_CanHandleModification(Modification modification, IInputActionCollection2 actions)
public void Actions_CanHandleModification(Modification modification, Func<IInputActionCollection2> getActions)
{
#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
// Exclude project-wide actions from this test
InputSystem.actions?.Disable();
InputActionState.DestroyAllActionMapStates(); // Required for `onActionChange` to report correct number of changes
#endif

var actions = getActions();
var gamepad = InputSystem.AddDevice<Gamepad>();

if (modification == Modification.AddDevice || modification == Modification.RemoveDevice)
Expand Down Expand Up @@ -6138,12 +6150,12 @@ public void Actions_AddingSameProcessorTwice_DoesntImpactUIHideState()
InputSystem.RegisterProcessor<ConstantFloat1TestProcessor>();
Assert.That(InputSystem.TryGetProcessor("ConstantFloat1Test"), Is.Not.EqualTo(null));

bool hide = InputSystem.s_Manager.processors.ShouldHideInUI("ConstantFloat1Test");
bool hide = InputSystem.manager.processors.ShouldHideInUI("ConstantFloat1Test");
Assert.That(hide, Is.EqualTo(false));

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

Expand Down Expand Up @@ -6789,7 +6801,7 @@ public void Actions_RegisteringExistingInteractionUnderNewName_CreatesAlias()
{
InputSystem.RegisterInteraction<HoldInteraction>("TestTest");

Assert.That(InputSystem.s_Manager.interactions.aliases.Contains(new InternedString("TestTest")));
Assert.That(InputSystem.manager.interactions.aliases.Contains(new InternedString("TestTest")));
}

#endif // UNITY_EDITOR
Expand Down Expand Up @@ -9081,7 +9093,7 @@ public void Actions_RegisteringExistingCompositeUnderNewName_CreatesAlias()
{
InputSystem.RegisterBindingComposite<Vector2Composite>("TestTest");

Assert.That(InputSystem.s_Manager.composites.aliases.Contains(new InternedString("TestTest")));
Assert.That(InputSystem.manager.composites.aliases.Contains(new InternedString("TestTest")));
}

#endif // UNITY_EDITOR
Expand Down Expand Up @@ -11426,7 +11438,7 @@ public void Actions_DisablingAllActions_RemovesAllTheirStateMonitors()

// Not the most elegant test as we reach into internals here but with the
// current API, it's not possible to enumerate monitors from outside.
Assert.That(InputSystem.s_Manager.m_StateChangeMonitors,
Assert.That(InputSystem.manager.m_StateChangeMonitors,
Has.All.Matches(
(InputManager.StateChangeMonitorsForDevice x) => x.memoryRegions.All(r => r.sizeInBits == 0)));
}
Expand Down Expand Up @@ -12446,7 +12458,7 @@ public void Actions_CompositeBindingResetWhenResetDeviceCalledWhileExecutingActi
// Disable the Keyboard while action is being performed.
// This simulates an "OnFocusLost" event occurring while processing the Action, e.g. when switching primary displays or moving the main window
actionPerformed = true;
InputSystem.s_Manager.EnableOrDisableDevice(keyboard.device, false, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);
InputSystem.manager.EnableOrDisableDevice(keyboard.device, false, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);
};

map.Enable();
Expand All @@ -12459,7 +12471,7 @@ public void Actions_CompositeBindingResetWhenResetDeviceCalledWhileExecutingActi
Assert.IsTrue(actionPerformed);

// Re enable the Keyboard (before keys are released) and execute Action again
InputSystem.s_Manager.EnableOrDisableDevice(keyboard.device, true, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);
InputSystem.manager.EnableOrDisableDevice(keyboard.device, true, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);

actionPerformed = false;
Release(keyboard.leftShiftKey);
Expand All @@ -12478,7 +12490,7 @@ public void Actions_CompositeBindingResetWhenResetDeviceCalledWhileExecutingActi
Release(keyboard.f1Key);

// Re enable the Keyboard (after keys are released) and execute Action one more time
InputSystem.s_Manager.EnableOrDisableDevice(keyboard.device, true, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);
InputSystem.manager.EnableOrDisableDevice(keyboard.device, true, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);

Press(keyboard.leftCtrlKey);
Press(keyboard.leftShiftKey);
Expand All @@ -12492,7 +12504,7 @@ public void Actions_CompositeBindingResetWhenResetDeviceCalledWhileExecutingActi
Press(keyboard.f1Key);

// Re enable the Keyboard (before keys are released) and verify Action isn't triggered when Key pressed first
InputSystem.s_Manager.EnableOrDisableDevice(keyboard.device, true, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);
InputSystem.manager.EnableOrDisableDevice(keyboard.device, true, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);

Press(keyboard.f1Key);
Press(keyboard.leftCtrlKey);
Expand Down
4 changes: 0 additions & 4 deletions Assets/Tests/InputSystem/CoreTests_Analytics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,6 @@ public void Analytics_ShouldReportBuildAnalytics_WhenNotHavingSettingsAsset()
{
CollectAnalytics(InputBuildAnalytic.kEventName);

var storedSettings = InputSystem.s_Manager.settings;
InputSettings defaultSettings = null;

try
Expand Down Expand Up @@ -470,7 +469,6 @@ public void Analytics_ShouldReportBuildAnalytics_WhenNotHavingSettingsAsset()
}
finally
{
InputSystem.s_Manager.settings = storedSettings;
if (defaultSettings != null)
Object.DestroyImmediate(defaultSettings);
}
Expand All @@ -482,7 +480,6 @@ public void Analytics_ShouldReportBuildAnalytics_WhenHavingSettingsAssetWithCust
{
CollectAnalytics(InputBuildAnalytic.kEventName);

var storedSettings = InputSystem.s_Manager.settings;
InputSettings customSettings = null;

try
Expand Down Expand Up @@ -576,7 +573,6 @@ public void Analytics_ShouldReportBuildAnalytics_WhenHavingSettingsAssetWithCust
}
finally
{
InputSystem.s_Manager.settings = storedSettings;
if (customSettings != null)
Object.DestroyImmediate(customSettings);
}
Expand Down
10 changes: 5 additions & 5 deletions Assets/Tests/InputSystem/CoreTests_Devices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -572,11 +572,11 @@ public void Devices_AddingDeviceThatUsesBeforeRenderUpdates_CausesBeforeRenderUp

InputSystem.RegisterLayout(deviceJson);

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

InputSystem.AddDevice("CustomGamepad");

Assert.That(InputSystem.s_Manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo(InputUpdateType.BeforeRender));
Assert.That(InputSystem.manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo(InputUpdateType.BeforeRender));
}

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

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

InputSystem.RemoveDevice(device1);

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

InputSystem.RemoveDevice(device2);

Assert.That(InputSystem.s_Manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo((InputUpdateType)0));
Assert.That(InputSystem.manager.updateMask & InputUpdateType.BeforeRender, Is.EqualTo((InputUpdateType)0));
}

private class TestDeviceReceivingAddAndRemoveNotification : Mouse
Expand Down
Loading