Skip to content

Commit f9f4f5d

Browse files
author
Rene Damm
authored
FIX: Errors when matching fields in InputDeviceDescription.capabilities (#1103).
1 parent 612623a commit f9f4f5d

File tree

7 files changed

+114
-13
lines changed

7 files changed

+114
-13
lines changed

Assets/Tests/InputSystem/CoreTests_Devices.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3285,6 +3285,7 @@ private struct TestDeviceCapabilities
32853285
public string stringCap;
32863286
public int intCap;
32873287
public float floatCap;
3288+
public float floatCapWithExponent;
32883289
public bool boolCap;
32893290
public NestedCaps nestedCap;
32903291
public string[] arrayCap;
@@ -3335,6 +3336,8 @@ public void Devices_CanMatchDeviceDescriptions_WithCapabilities()
33353336
.WithCapability("intCap", "1234");
33363337
var matchFloatCapWithString = new InputDeviceMatcher()
33373338
.WithCapability("floatCap", "1.234");
3339+
var matchFloatWithExponentCapWithString = new InputDeviceMatcher()
3340+
.WithCapability("floatCapWithExponent", "1.234e-10");
33383341
var matchBoolCapWithString = new InputDeviceMatcher()
33393342
.WithCapability("boolCap", "true");
33403343
var matchNone = new InputDeviceMatcher()
@@ -3348,6 +3351,7 @@ public void Devices_CanMatchDeviceDescriptions_WithCapabilities()
33483351
stringCap = "string",
33493352
intCap = 1234,
33503353
floatCap = 1.234f,
3354+
floatCapWithExponent = 1.234e-10f,
33513355
boolCap = true,
33523356
nestedCap = new TestDeviceCapabilities.NestedCaps
33533357
{
@@ -3368,6 +3372,7 @@ public void Devices_CanMatchDeviceDescriptions_WithCapabilities()
33683372
Assert.That(matchIntCapWithRegex.MatchPercentage(description), Is.EqualTo(1 / 2.0).Within(0.0001));
33693373
Assert.That(matchIntCapWithString.MatchPercentage(description), Is.EqualTo(1 / 2.0).Within(0.0001));
33703374
Assert.That(matchFloatCapWithString.MatchPercentage(description), Is.EqualTo(1 / 2.0).Within(0.0001));
3375+
Assert.That(matchFloatWithExponentCapWithString.MatchPercentage(description), Is.EqualTo(1 / 2.0).Within(0.0001));
33713376
Assert.That(matchBoolCapWithString.MatchPercentage(description), Is.EqualTo(1 / 2.0).Within(0.0001));
33723377
Assert.That(matchNone.MatchPercentage(description), Is.EqualTo(0).Within(0.0001));
33733378
}

Assets/Tests/InputSystem/Plugins/HIDTests.cs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,60 @@ public void Devices_DevicesNotAllowedBySupportedHIDUsagesAreSkipped()
106106

107107
Assert.That(InputSystem.devices, Has.Count.EqualTo(0));
108108
Assert.That(InputSystem.GetDeviceById(deviceId), Is.Null);
109+
Assert.That(InputSystem.GetUnsupportedDevices(), Has.Count.EqualTo(1));
110+
Assert.That(InputSystem.GetUnsupportedDevices()[0].product, Is.EqualTo("TestHID"));
109111

110112
HIDSupport.supportedHIDUsages = new ReadOnlyArray<HIDSupport.HIDPageUsage>(
111113
new[] {new HIDSupport.HIDPageUsage((HID.UsagePage) 5678, 1234)}
112114
);
113115

114-
runtime.ReportNewInputDevice(descriptionJson, deviceId);
115-
InputSystem.Update();
116+
Assert.That(InputSystem.devices, Has.Count.EqualTo(1));
117+
Assert.That(InputSystem.GetDeviceById(deviceId), Is.Not.Null);
118+
Assert.That(InputSystem.devices[0], Is.TypeOf<HID>());
119+
Assert.That(InputSystem.devices[0].description.product, Is.EqualTo("TestHID"));
120+
Assert.That(((HID)InputSystem.devices[0]).hidDescriptor.usagePage, Is.EqualTo((HID.UsagePage) 5678));
121+
Assert.That(((HID)InputSystem.devices[0]).hidDescriptor.usage, Is.EqualTo(1234));
116122

123+
HIDSupport.supportedHIDUsages = new ReadOnlyArray<HIDSupport.HIDPageUsage>(
124+
new[] {new HIDSupport.HIDPageUsage((HID.UsagePage) 5678, 1234)}
125+
);
126+
127+
// No change.
117128
Assert.That(InputSystem.devices, Has.Count.EqualTo(1));
118129
Assert.That(InputSystem.GetDeviceById(deviceId), Is.Not.Null);
130+
Assert.That(InputSystem.devices[0], Is.TypeOf<HID>());
131+
Assert.That(InputSystem.devices[0].description.product, Is.EqualTo("TestHID"));
132+
Assert.That(((HID)InputSystem.devices[0]).hidDescriptor.usagePage, Is.EqualTo((HID.UsagePage) 5678));
133+
Assert.That(((HID)InputSystem.devices[0]).hidDescriptor.usage, Is.EqualTo(1234));
134+
135+
// Add another.
136+
var descriptionJson2 = new InputDeviceDescription
137+
{
138+
interfaceName = HID.kHIDInterface,
139+
manufacturer = "TestVendor",
140+
product = "OtherTestHID",
141+
capabilities = hidDescriptor.ToJson()
142+
}.ToJson();
143+
var deviceId2 = runtime.AllocateDeviceId();
144+
145+
runtime.ReportNewInputDevice(descriptionJson2, deviceId2);
146+
InputSystem.Update();
147+
148+
Assert.That(InputSystem.devices, Has.Count.EqualTo(2));
149+
Assert.That(InputSystem.GetDeviceById(deviceId2), Is.Not.Null);
150+
Assert.That(InputSystem.devices[1], Is.TypeOf<HID>());
151+
Assert.That(InputSystem.devices[1].description.product, Is.EqualTo("OtherTestHID"));
152+
Assert.That(((HID)InputSystem.devices[1]).hidDescriptor.usagePage, Is.EqualTo((HID.UsagePage) 5678));
153+
Assert.That(((HID)InputSystem.devices[1]).hidDescriptor.usage, Is.EqualTo(1234));
154+
155+
HIDSupport.supportedHIDUsages = new ReadOnlyArray<HIDSupport.HIDPageUsage>();
156+
157+
Assert.That(InputSystem.devices, Is.Empty);
158+
Assert.That(InputSystem.GetDeviceById(deviceId), Is.Null);
159+
Assert.That(InputSystem.GetDeviceById(deviceId2), Is.Null);
160+
Assert.That(InputSystem.GetUnsupportedDevices(), Has.Count.EqualTo(2));
161+
Assert.That(InputSystem.GetUnsupportedDevices(), Has.Exactly(1).With.Property("product").EqualTo("TestHID"));
162+
Assert.That(InputSystem.GetUnsupportedDevices(), Has.Exactly(1).With.Property("product").EqualTo("OtherTestHID"));
119163
}
120164

121165
[Test]

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ however, it has to be formatted properly to pass verification tests.
1515
- Can now override built-in Android gamepad layouts. Previously, the input system would always choose its default defaults even after registering more specific layouts using `InputSystem.RegisterLayout`.
1616
- `InputControlPath.TryGetControlLayout` no longer throws `NotImplementedException` for `<Mouse>/scroll/x` and similar paths where the layout is modifying a control it inherited from its base layout ([thread](https://forum.unity.com/threads/notimplementedexception-when-using-inputcontrolpath-trygetcontrollayout-on-mouse-controls.847129/)).
1717
- Fixed compilation errors when disabling built-in VR and XR packages. ([case 1214248](https://issuetracker.unity3d.com/issues/enable-input-system-symbol-is-not-being-updated-when-the-input-system-is-changed-in-player-settings/)).
18+
- No longer throws `NotImplementedException` when matching against a field of `InputDeviceDescription.capabilities` when the value of the field used scientific notation.
19+
- No longer incorrectly matches fields of `InputDeviceDescription.capabilities` by prefix only (i.e. previously it would find the field "foo" when actually looking for "foobar").
1820

1921
#### Actions
2022

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,7 +2292,7 @@ internal void ApplySettings()
22922292
m_SettingsChangedListeners[i]();
22932293
}
22942294

2295-
private void AddAvailableDevicesThatAreNowRecognized()
2295+
internal void AddAvailableDevicesThatAreNowRecognized()
22962296
{
22972297
for (var i = 0; i < m_AvailableDeviceCount; ++i)
22982298
{
@@ -3319,10 +3319,12 @@ internal void RestoreDevicesAfterDomainReload()
33193319
using (InputDeviceBuilder.Ref())
33203320
{
33213321
DeviceState[] retainedDeviceStates = null;
3322+
var deviceStates = m_SavedDeviceStates;
33223323
var deviceCount = m_SavedDeviceStates.LengthSafe();
3324+
m_SavedDeviceStates = null; // Prevent layout matcher registering themselves on the fly from picking anything off this list.
33233325
for (var i = 0; i < deviceCount; ++i)
33243326
{
3325-
ref var deviceState = ref m_SavedDeviceStates[i];
3327+
ref var deviceState = ref deviceStates[i];
33263328

33273329
var device = TryGetDeviceById(deviceState.deviceId);
33283330
if (device != null)
@@ -3425,7 +3427,7 @@ private bool RestoreDeviceFromSavedState(ref DeviceState deviceState, InternedSt
34253427
catch (Exception exception)
34263428
{
34273429
Debug.LogError(
3428-
$"Could not re-recreate input device '{deviceState.description}' with layout '{deviceState.layout}' and variants '{deviceState.variants}' after domain reload");
3430+
$"Could not recreate input device '{deviceState.description}' with layout '{deviceState.layout}' and variants '{deviceState.variants}' after domain reload");
34293431
Debug.LogException(exception);
34303432
return true; // Don't try again.
34313433
}

Packages/com.unity.inputsystem/InputSystem/Plugins/HID/HID.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ internal static string OnFindLayoutForDevice(ref InputDeviceDescription descript
114114
if (!hasUsableElements)
115115
return null;
116116

117-
118117
////TODO: we should be able to differentiate a HID joystick from other joysticks in bindings alone
119118
// Determine base layout.
120119
var baseType = typeof(HID);

Packages/com.unity.inputsystem/InputSystem/Plugins/HID/HIDSupport.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Linq;
12
using UnityEngine.InputSystem.Utilities;
23
#if UNITY_EDITOR
34
using UnityEditor;
@@ -88,7 +89,25 @@ public HIDPageUsage(HID.GenericDesktop usage)
8889
public static ReadOnlyArray<HIDPageUsage> supportedHIDUsages
8990
{
9091
get => s_SupportedHIDUsages;
91-
set => s_SupportedHIDUsages = value.ToArray();
92+
set
93+
{
94+
s_SupportedHIDUsages = value.ToArray();
95+
96+
// Add HIDs we now support.
97+
InputSystem.s_Manager.AddAvailableDevicesThatAreNowRecognized();
98+
99+
// Remove HIDs we no longer support.
100+
for (var i = 0; i < InputSystem.devices.Count; ++i)
101+
{
102+
var device = InputSystem.devices[i];
103+
if (device is HID hid && !s_SupportedHIDUsages.Contains(new HIDPageUsage(hid.hidDescriptor.usagePage, hid.hidDescriptor.usage)))
104+
{
105+
// Remove the entire generated layout. This will also remove all devices based on it.
106+
InputSystem.RemoveLayout(device.layout);
107+
--i;
108+
}
109+
}
110+
}
92111
}
93112

94113
/// <summary>

Packages/com.unity.inputsystem/InputSystem/Utilities/JsonParser.cs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,15 @@ public bool NavigateToProperty(string path)
8787
}
8888

8989
// See if we have a match.
90-
if (m_Position < m_Length && m_Text[m_Position] == '"')
90+
if (m_Position < m_Length && m_Text[m_Position] == '"' && (pathPosition >= pathLength || path[pathPosition] == '/' || path[pathPosition] == '['))
9191
{
9292
// Have matched a property name. Navigate to value.
9393
++m_Position;
9494
if (!SkipToValue())
9595
return false;
9696

9797
// Check if we have matched everything in the path.
98-
if (pathPosition == pathLength)
98+
if (pathPosition >= pathLength)
9999
return true;
100100
if (path[pathPosition] == '/')
101101
{
@@ -374,6 +374,7 @@ public bool ParseNumber(out JsonValue result)
374374
var integralPart = 0L;
375375
var fractionalPart = 0.0;
376376
var fractionalDivisor = 10.0;
377+
var exponent = 0;
377378

378379
// Parse sign.
379380
if (m_Text[m_Position] == '-')
@@ -416,11 +417,36 @@ public bool ParseNumber(out JsonValue result)
416417
}
417418

418419
if (m_Position < m_Length && (m_Text[m_Position] == 'e' || m_Text[m_Position] == 'E'))
419-
throw new NotImplementedException("exponents");
420+
{
421+
++m_Position;
422+
var isNegative = false;
423+
if (m_Position < m_Length && m_Text[m_Position] == '-')
424+
{
425+
isNegative = true;
426+
++m_Position;
427+
}
428+
else if (m_Position < m_Length && m_Text[m_Position] == '+')
429+
{
430+
++m_Position;
431+
}
432+
433+
var multiplier = 1;
434+
while (m_Position < m_Length && char.IsDigit(m_Text[m_Position]))
435+
{
436+
var digit = m_Text[m_Position] - '0';
437+
exponent *= multiplier;
438+
exponent += digit;
439+
multiplier *= 10;
440+
++m_Position;
441+
}
442+
443+
if (isNegative)
444+
exponent *= -1;
445+
}
420446

421447
if (!m_DryRun)
422448
{
423-
if (!haveFractionalPart)
449+
if (!haveFractionalPart && exponent == 0)
424450
{
425451
if (negative)
426452
result = -integralPart;
@@ -429,10 +455,14 @@ public bool ParseNumber(out JsonValue result)
429455
}
430456
else
431457
{
458+
float value;
432459
if (negative)
433-
result = (float)-(integralPart + fractionalPart);
460+
value = (float)-(integralPart + fractionalPart);
434461
else
435-
result = (float)(integralPart + fractionalPart);
462+
value = (float)(integralPart + fractionalPart);
463+
if (exponent != 0)
464+
value *= Mathf.Pow(10, exponent);
465+
result = value;
436466
}
437467
}
438468

0 commit comments

Comments
 (0)