Skip to content

Commit 8500e3e

Browse files
committed
Minor tweaks to sample, expanded test coverage, temporary avoid deserialization in Input Manager
1 parent 3191c2e commit 8500e3e

File tree

7 files changed

+124
-51
lines changed

7 files changed

+124
-51
lines changed

Assets/Samples/RebindingUI/GameManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ private void OnMenu(InputAction.CallbackContext obj)
5252

5353
private void OnExitMenu(InputAction.CallbackContext obj)
5454
{
55+
// TODO We cannot do this without first cancelling rebinding
56+
5557
if (!menu.activeInHierarchy)
5658
return;
5759

Assets/Samples/RebindingUI/RebindingMaterial.mat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Material:
7979
- _UVSec: 0
8080
- _ZWrite: 1
8181
m_Colors:
82-
- _Color: {r: 1, g: 0, b: 1.1e-44, a: 1}
82+
- _Color: {r: 0.9995672, g: 0.9212032, b: 0.016187144, a: 1}
8383
- _EmissionColor: {r: 0.27450982, g: 0.078431375, b: 0.19607843, a: 1}
8484
m_BuildTextureStacks: []
8585
m_AllowLocking: 1

Assets/Samples/RebindingUI/RebindingUISampleScene.unity

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,7 @@ MonoBehaviour:
892892
m_HorizontalOverflow: 0
893893
m_VerticalOverflow: 0
894894
m_LineSpacing: 1
895-
m_Text: Move
895+
m_Text: Navigate
896896
--- !u!222 &323438533
897897
CanvasRenderer:
898898
m_ObjectHideFlags: 0
@@ -2255,7 +2255,7 @@ MonoBehaviour:
22552255
m_Script: {fileID: 11500000, guid: b5c8f13dfafeb5445b872565802d1e44, type: 3}
22562256
m_Name:
22572257
m_EditorClassIdentifier:
2258-
action: {fileID: -4334443723673744087, guid: 100b460020a15704692cc0ec34331d8a, type: 3}
2258+
action: {fileID: -64187129634329061, guid: 100b460020a15704692cc0ec34331d8a, type: 3}
22592259
activeColor: {r: 0, g: 1, b: 0, a: 1}
22602260
inactiveColor: {r: 0, g: 0, b: 0, a: 1}
22612261
duration: 1

Assets/Tests/InputSystem/CoreTests_Events.cs

Lines changed: 104 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,14 +1216,6 @@ public void Events_CanPreventEventsFromBeingProcessed()
12161216
Assert.That(device.rightTrigger.ReadValue(), Is.EqualTo(0.0).Within(0.00001));
12171217
}
12181218

1219-
class SuppressedActionEventData
1220-
{
1221-
public bool markNextEventHandled;
1222-
public int startedCount;
1223-
public int performedCount;
1224-
public int canceledCount;
1225-
}
1226-
12271219
[Test]
12281220
[Category("Events")]
12291221
public void EventHandledPolicy_ShouldReflectUserSetting()
@@ -1245,14 +1237,40 @@ public void EventHandledPolicy_ShouldReflectUserSetting()
12451237
Assert.That(InputSystem.s_Manager.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressStateUpdates));
12461238
}
12471239

1240+
class SuppressedActionEventData
1241+
{
1242+
public bool MarkNextEventHandled;
1243+
public int StartedCount;
1244+
public int PerformedCount;
1245+
public int CanceledCount;
1246+
}
1247+
1248+
// Note that each element in the expected value arrays correspond to accumulated count per test step.
1249+
[TestCase(InputEventHandledPolicy.SuppressStateUpdates, // policy
1250+
null, // interactions
1251+
new int[] { 0, 0, 1, 1, 2}, // started
1252+
new int[] { 0, 0, 1, 1, 2}, // performed
1253+
new int[] {0, 0, 0, 1, 1})] // cancelled
1254+
[TestCase(InputEventHandledPolicy.SuppressActionUpdates,
1255+
null,
1256+
new int[] { 0, 0, 0, 0, 1},
1257+
new int[] { 0, 0, 0, 0, 1},
1258+
new int[] {0, 0, 0, 0, 0})]
12481259
[TestCase(InputEventHandledPolicy.SuppressStateUpdates,
1249-
new int[] { 0, 0, 1, 1}, new int[] {0, 0, 0, 1})]
1260+
"press",
1261+
new int[] { 0, 0, 1, 1, 2},
1262+
new int[] { 0, 0, 1, 1, 2},
1263+
new int[] {0, 0, 0, 1, 1})]
12501264
[TestCase(InputEventHandledPolicy.SuppressActionUpdates,
1251-
new int[] { 0, 0, 0, 0}, new int[] {0, 0, 0, 0})]
1265+
"press",
1266+
new int[] { 0, 0, 0, 0, 1},
1267+
new int[] { 0, 0, 0, 0, 1},
1268+
new int[] {0, 0, 0, 0, 0})]
12521269
[Category("Events")]
1253-
[Description("ISXB-1524 Events suppressed has side-effects on actions when based on polling")]
1254-
public void Events_ShouldRespectHandledPolicyUponUpdate(InputEventHandledPolicy policy,
1255-
int[] expectedProcessed, int[] expectedCancelled) // EDIT
1270+
[Description("ISXB-1524, ISXB-1396 Events suppressed has side-effects on actions")]
1271+
public void Events_ShouldRespectHandledPolicyUponUpdateAndSuppressedPressTransition(
1272+
InputEventHandledPolicy policy, string interactions,
1273+
int[] expectedStarted, int[] expectedPerformed, int[] expectedCancelled)
12561274
{
12571275
// Update setting to match desired scenario
12581276
InputSystem.s_Manager.inputEventHandledPolicy = policy;
@@ -1264,42 +1282,91 @@ public void Events_ShouldRespectHandledPolicyUponUpdate(InputEventHandledPolicy
12641282
(inputEvent, _) =>
12651283
{
12661284
// If we mark the event handled, the system should skip it and not
1267-
// let it go to the device.
1268-
inputEvent.handled = data.markNextEventHandled;
1285+
// let it go to the device (SuppressStateUpdates) or let it propagate
1286+
// but not fire actions (SuppressActionUpdates).
1287+
inputEvent.handled = data.MarkNextEventHandled;
12691288
};
12701289

12711290
var device = InputSystem.AddDevice<Gamepad>();
1272-
var action = new InputAction(type: InputActionType.Button, binding: "<Gamepad>/buttonNorth");
1291+
var action = new InputAction(type: InputActionType.Button,
1292+
binding: "<Gamepad>/buttonNorth",
1293+
interactions: interactions);
12731294
action.Enable();
1274-
action.started += _ => ++ data.startedCount;
1275-
action.performed += _ => ++ data.performedCount;
1276-
action.canceled += _ => ++ data.canceledCount;
1295+
action.started += _ => ++ data.StartedCount;
1296+
action.performed += _ => ++ data.PerformedCount;
1297+
action.canceled += _ => ++ data.CanceledCount;
12771298

12781299
// Ensure state is updated/initialized
12791300
InputSystem.QueueStateEvent(device, new GamepadState() { leftStick = new Vector2(0.01f, 0.0f) });
12801301
InputSystem.Update();
1281-
Assert.That(data.performedCount, Is.EqualTo(expectedProcessed[0]));
1282-
Assert.That(data.canceledCount, Is.EqualTo(expectedCancelled[0]));
1283-
1284-
// Press button north with event suppression active
1285-
data.markNextEventHandled = true;
1286-
InputSystem.QueueStateEvent(device, new GamepadState() { leftStick = new Vector2(0.00f, 0.01f) }.WithButton(GamepadButton.North));
1302+
Assert.That(data.StartedCount, Is.EqualTo(expectedStarted[0]));
1303+
Assert.That(data.PerformedCount, Is.EqualTo(expectedPerformed[0]));
1304+
Assert.That(data.CanceledCount, Is.EqualTo(expectedCancelled[0]));
1305+
var performedThisFrame = expectedPerformed[0] != 0;
1306+
Assert.That(action.WasPerformedThisFrame, Is.EqualTo(performedThisFrame));
1307+
Assert.That(action.WasPressedThisFrame, Is.EqualTo(performedThisFrame));
1308+
var releasedThisFrame = expectedCancelled[0] != 0;
1309+
Assert.That(action.WasReleasedThisFrame, Is.EqualTo(releasedThisFrame));
1310+
// TODO Assert.That(Gamepad.current.buttonNorth.wasPressedThisFrame, Is.False); <-- TODO Needs separate handling, just suppress?
1311+
1312+
// Press button north and left stick with event suppression active
1313+
data.MarkNextEventHandled = true;
1314+
InputSystem.QueueStateEvent(device, new GamepadState() { leftStick = new Vector2(1.00f, 0.01f) }
1315+
.WithButton(GamepadButton.North));
12871316
InputSystem.Update();
1288-
Assert.That(data.performedCount, Is.EqualTo(expectedProcessed[1]));
1289-
Assert.That(data.canceledCount, Is.EqualTo(expectedCancelled[1]));
1290-
1291-
// Simulate a periodic reading, this will trigger performed count
1292-
data.markNextEventHandled = false;
1293-
InputSystem.QueueStateEvent(device, new GamepadState() { leftStick = new Vector2(0.01f, 0.00f) }.WithButton(GamepadButton.North));
1317+
Assert.That(data.StartedCount, Is.EqualTo(expectedStarted[1]));
1318+
Assert.That(data.PerformedCount, Is.EqualTo(expectedPerformed[1]));
1319+
Assert.That(data.CanceledCount, Is.EqualTo(expectedCancelled[1]));
1320+
performedThisFrame = expectedPerformed[1] - expectedPerformed[0] > 0;
1321+
Assert.That(action.WasPerformedThisFrame, Is.EqualTo(performedThisFrame));
1322+
Assert.That(action.WasPressedThisFrame, Is.EqualTo(performedThisFrame));
1323+
releasedThisFrame = expectedCancelled[1] - expectedCancelled[0] > 0;
1324+
Assert.That(action.WasReleasedThisFrame, Is.EqualTo(releasedThisFrame));
1325+
// TODO Assert.That(Gamepad.current.buttonNorth.wasPressedThisFrame, Is.EqualTo(expectedPerformed[1] - expectedPerformed[0] > 0));
1326+
1327+
// Simulate a periodic reading (e.g. driven by noise or irrelevant control), this will trigger performed count.
1328+
// Note that for SuppressStateUpdates (default), this would trigger a state change since North button
1329+
// transitions from 0 to 1 which is considered a press.
1330+
data.MarkNextEventHandled = false;
1331+
InputSystem.QueueStateEvent(device, new GamepadState() { leftStick = new Vector2(0.99f, 0.00f) }
1332+
.WithButton(GamepadButton.North));
12941333
InputSystem.Update();
1295-
Assert.That(data.performedCount, Is.EqualTo(expectedProcessed[2])); // Firing without actual change
1296-
Assert.That(data.canceledCount, Is.EqualTo(expectedCancelled[2]));
1297-
1298-
// Release button north
1334+
Assert.That(data.StartedCount, Is.EqualTo(expectedStarted[2]));
1335+
Assert.That(data.PerformedCount, Is.EqualTo(expectedPerformed[2])); // Firing without actual change
1336+
Assert.That(data.CanceledCount, Is.EqualTo(expectedCancelled[2]));
1337+
performedThisFrame = expectedPerformed[2] - expectedPerformed[1] > 0;
1338+
Assert.That(action.WasPerformedThisFrame, Is.EqualTo(performedThisFrame));
1339+
Assert.That(action.WasPressedThisFrame, Is.EqualTo(performedThisFrame));
1340+
releasedThisFrame = expectedCancelled[2] - expectedCancelled[1] > 0;
1341+
Assert.That(action.WasReleasedThisFrame, Is.EqualTo(releasedThisFrame));
1342+
// TODO Assert.That(Gamepad.current.buttonNorth.wasPressedThisFrame, Is.EqualTo(expectedPerformed[2] - expectedPerformed[1] > 0));
1343+
1344+
// Release button north and stick while no longer being suppressed. This may result in a release if
1345+
// previous event was completely ignored without updating interaction state.
12991346
InputSystem.QueueStateEvent(device, new GamepadState() { leftStick = new Vector2(0.00f, 0.01f) });
13001347
InputSystem.Update();
1301-
Assert.That(data.performedCount, Is.EqualTo(expectedProcessed[3]));
1302-
Assert.That(data.canceledCount, Is.EqualTo(expectedCancelled[3]));
1348+
Assert.That(data.StartedCount, Is.EqualTo(expectedStarted[3]));
1349+
Assert.That(data.PerformedCount, Is.EqualTo(expectedPerformed[3]));
1350+
Assert.That(data.CanceledCount, Is.EqualTo(expectedCancelled[3]));
1351+
performedThisFrame = expectedPerformed[3] - expectedPerformed[2] > 0;
1352+
Assert.That(action.WasPerformedThisFrame, Is.EqualTo(performedThisFrame));
1353+
Assert.That(action.WasPressedThisFrame, Is.EqualTo(performedThisFrame));
1354+
releasedThisFrame = expectedCancelled[3] - expectedCancelled[2] > 0;
1355+
Assert.That(action.WasReleasedThisFrame, Is.EqualTo(releasedThisFrame));
1356+
// TODO Assert.That(Gamepad.current.buttonNorth.wasPressedThisFrame, Is.EqualTo(expectedPerformed[3] - expectedPerformed[2] > 0));
1357+
1358+
// Press button north and stick again while not being suppressed.
1359+
InputSystem.QueueStateEvent(device, new GamepadState() { leftStick = new Vector2(0.99f, 0.00f) }
1360+
.WithButton(GamepadButton.North));
1361+
InputSystem.Update();
1362+
Assert.That(data.StartedCount, Is.EqualTo(expectedStarted[4]));
1363+
Assert.That(data.PerformedCount, Is.EqualTo(expectedPerformed[4]));
1364+
Assert.That(data.CanceledCount, Is.EqualTo(expectedCancelled[4]));
1365+
performedThisFrame = expectedPerformed[4] - expectedPerformed[3] > 0;
1366+
Assert.That(action.WasPerformedThisFrame, Is.EqualTo(performedThisFrame));
1367+
Assert.That(action.WasPressedThisFrame, Is.EqualTo(performedThisFrame));
1368+
releasedThisFrame = expectedCancelled[4] - expectedCancelled[3] > 0;
1369+
Assert.That(action.WasReleasedThisFrame, Is.EqualTo(releasedThisFrame));
13031370
}
13041371

13051372
[StructLayout(LayoutKind.Explicit, Size = 2)]

Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,7 +1520,7 @@ private void ProcessControlStateChange(int mapIndex, int controlIndex, int bindi
15201520
}
15211521

15221522
// Check if we should suppress interaction processing
1523-
var suppressInteractionProcessing = (eventPtr != null) && eventPtr.handled &&
1523+
var suppressActionProcessing = (eventPtr != null) && eventPtr.handled &&
15241524
InputSystem.s_Manager.inputEventHandledPolicy == InputEventHandledPolicy.SuppressActionUpdates;
15251525

15261526
// Check if we have multiple concurrent actuations on the same action. This may lead us
@@ -1531,21 +1531,24 @@ private void ProcessControlStateChange(int mapIndex, int controlIndex, int bindi
15311531
var isConflictingInput = IsConflictingInput(ref trigger, actionIndex);
15321532
bindingStatePtr = &bindingStates[trigger.bindingIndex]; // IsConflictingInput may switch us to a different binding.
15331533

1534+
// TODO Potentially we need to move suppression down to indicators/callbacks, this may be too blunt
1535+
15341536
// Process button presses/releases.
1535-
if (!isConflictingInput)
1537+
if (!isConflictingInput && !suppressActionProcessing)
15361538
ProcessButtonState(ref trigger, actionIndex, bindingStatePtr);
15371539

15381540
// If we have interactions, let them do all the processing. The presence of an interaction
15391541
// essentially bypasses the default phase progression logic of an action.
15401542
var interactionCount = bindingStatePtr->interactionCount;
15411543
if (interactionCount > 0 && !bindingStatePtr->isPartOfComposite)
15421544
{
1543-
ProcessInteractions(ref trigger, bindingStatePtr->interactionStartIndex, interactionCount);
1545+
if (!suppressActionProcessing)
1546+
ProcessInteractions(ref trigger, bindingStatePtr->interactionStartIndex, interactionCount);
15441547
}
15451548
else if (!haveInteractionsOnComposite && !isConflictingInput)
15461549
{
1547-
//if (!suppressInteractionProcessing)
1548-
ProcessDefaultInteraction(ref trigger, actionIndex);
1550+
if (!suppressActionProcessing) // <-- This solves it for default interaction
1551+
ProcessDefaultInteraction(ref trigger, actionIndex);
15491552
}
15501553
}
15511554
finally
@@ -1573,6 +1576,7 @@ private void ProcessButtonState(ref TriggerState trigger, int actionIndex, Bindi
15731576
if (controlActuation <= pressPoint * ButtonControl.s_GlobalDefaultButtonReleaseThreshold)
15741577
bindingStatePtr->pressTime = 0d;
15751578

1579+
// TODO Point of interest (polled events)
15761580
var actuation = trigger.magnitude;
15771581
var actionState = &actionStates[actionIndex];
15781582
if (!actionState->isPressed && actuation >= pressPoint)
@@ -1947,7 +1951,7 @@ private void ProcessDefaultInteraction(ref TriggerState trigger, int actionIndex
19471951
var threshold = controls[trigger.controlIndex] is ButtonControl button ? button.pressPointOrDefault : ButtonControl.s_GlobalDefaultButtonPressPoint;
19481952
if (actuation >= threshold)
19491953
{
1950-
// CALLBACK HERE
1954+
// CALLBACK HERE!
19511955
ChangePhaseOfAction(InputActionPhase.Performed, ref trigger,
19521956
phaseAfterPerformedOrCanceled: InputActionPhase.Performed);
19531957
}
@@ -2365,8 +2369,8 @@ private bool ChangePhaseOfAction(InputActionPhase newPhase, ref TriggerState tri
23652369

23662370
// Ignore if action is disabled.
23672371
var actionState = &actionStates[actionIndex];
2368-
if (actionState->isDisabled)
2369-
return true;
2372+
if (actionState->isDisabled /*|| InputSystem.s_Manager.inputEventHandledPolicy == InputEventHandledPolicy.SuppressActionUpdates*/)
2373+
return true; // <--- Could be relevant
23702374

23712375
// We mark the action as in-processing while we execute its phase transitions and perform
23722376
// callbacks. The callbacks may alter system state such that the action may get disabled
@@ -2406,7 +2410,7 @@ private bool ChangePhaseOfAction(InputActionPhase newPhase, ref TriggerState tri
24062410
}
24072411
else if (actionState->phase != newPhase || newPhase == InputActionPhase.Performed) // We allow Performed to trigger repeatedly.
24082412
{
2409-
// CALLBACK HERE
2413+
// CALLBACK HERE!
24102414
ChangePhaseOfActionInternal(actionIndex, actionState, newPhase, ref trigger,
24112415
isDisablingAction: newPhase == InputActionPhase.Canceled && phaseAfterPerformedOrCanceled == InputActionPhase.Disabled);
24122416
if (!actionState->inProcessing)

Packages/com.unity.inputsystem/InputSystem/InputManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4161,7 +4161,7 @@ internal void RestoreStateWithoutDevices(SerializedState state)
41614161
scrollDeltaBehavior = state.scrollDeltaBehavior;
41624162
m_Metrics = state.metrics;
41634163
m_PollingFrequency = state.pollingFrequency;
4164-
m_InputEventHandledPolicy = state.inputEventHandledPolicy;
4164+
m_InputEventHandledPolicy = InputEventHandledPolicy.SuppressStateUpdates; // TODO Make sure we always restore: state.inputEventHandledPolicy;
41654165

41664166
if (m_Settings != null)
41674167
Object.DestroyImmediate(m_Settings);

Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ internal unsafe void FireStateChangeNotifications(int deviceIndex, double intern
426426
// Need to reset it back to false as we may have more signalled state monitors that
427427
// aren't in the same group (i.e. have independent inputs).
428428
if (eventPtr->handled)
429-
eventPtr->handled = false;
429+
eventPtr->handled = previouslyHandled;
430430

431431
signals.ClearBit(i);
432432
}

0 commit comments

Comments
 (0)