UnityGame/Library/PackageCache/com.unity.inputsystem/InputSystem/Plugins/HID/HIDSupport.cs
2024-10-27 10:53:47 +03:00

155 lines
5.9 KiB
C#

using System.Linq;
using UnityEngine.InputSystem.Utilities;
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine.InputSystem.Editor;
using UnityEngine.InputSystem.HID.Editor;
#endif
namespace UnityEngine.InputSystem.HID
{
using ShouldCreateHIDCallback = System.Func<HID.HIDDeviceDescriptor, bool?>;
/// <summary>
/// Adds support for generic HID devices to the input system.
/// </summary>
/// <remarks>
/// Even without this module, HIDs can be used on platforms where we
/// support HID has a native backend (Windows and OSX, at the moment).
/// However, each supported HID requires a layout specifically targeting
/// it as a product.
///
/// What this module adds is the ability to turn any HID with usable
/// controls into an InputDevice. It will make a best effort to figure
/// out a suitable class for the device and will use the HID elements
/// present in the HID report descriptor to populate the device.
///
/// If there is an existing product-specific layout for a HID, it will
/// take precedence and HIDSupport will leave the device alone.
/// </remarks>
public static class HIDSupport
{
/// <summary>
/// A pair of HID usage page and HID usage number.
/// </summary>
/// <remarks>
/// Used to describe a HID usage for the <see cref="supportedHIDUsages"/> property.
/// </remarks>
public struct HIDPageUsage
{
/// <summary>
/// The usage page.
/// </summary>
public HID.UsagePage page;
/// <summary>
/// A number specifying the usage on the usage page.
/// </summary>
public int usage;
/// <summary>
/// Create a HIDPageUsage struct by specifying a page and usage.
/// </summary>
public HIDPageUsage(HID.UsagePage page, int usage)
{
this.page = page;
this.usage = usage;
}
/// <summary>
/// Create a HIDPageUsage struct from the GenericDesktop usage page by specifying the usage.
/// </summary>
public HIDPageUsage(HID.GenericDesktop usage)
{
page = HID.UsagePage.GenericDesktop;
this.usage = (int)usage;
}
}
private static HIDPageUsage[] s_SupportedHIDUsages;
/// <summary>
/// An array of HID usages the input is configured to support.
/// </summary>
/// <remarks>
/// The input system will only create <see cref="InputDevice"/>s for HIDs with usages
/// listed in this array. Any other HID will be ignored. This saves the input system from
/// spending resources on creating layouts and devices for HIDs which are not supported or
/// not usable for game input.
///
/// By default, this includes only <see cref="HID.GenericDesktop.Joystick"/>,
/// <see cref="HID.GenericDesktop.Gamepad"/> and <see cref="HID.GenericDesktop.MultiAxisController"/>,
/// but you can set this property to include any other HID usages.
///
/// Note that currently on macOS, the only HID usages which can be enabled are
/// <see cref="HID.GenericDesktop.Joystick"/>, <see cref="HID.GenericDesktop.Gamepad"/>,
/// <see cref="HID.GenericDesktop.MultiAxisController"/>, <see cref="HID.GenericDesktop.TabletPCControls"/>,
/// and <see cref="HID.GenericDesktop.AssistiveControl"/>.
/// </remarks>
public static ReadOnlyArray<HIDPageUsage> supportedHIDUsages
{
get => s_SupportedHIDUsages;
set
{
s_SupportedHIDUsages = value.ToArray();
// Add HIDs we now support.
InputSystem.s_Manager.AddAvailableDevicesThatAreNowRecognized();
// Remove HIDs we no longer support.
for (var i = 0; i < InputSystem.devices.Count; ++i)
{
var device = InputSystem.devices[i];
if (device is HID hid && !s_SupportedHIDUsages.Contains(new HIDPageUsage(hid.hidDescriptor.usagePage, hid.hidDescriptor.usage)))
{
// Remove the entire generated layout. This will also remove all devices based on it.
InputSystem.RemoveLayout(device.layout);
--i;
}
}
}
}
/// <summary>
/// Add support for generic HIDs to InputSystem.
/// </summary>
#if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION
public
#else
internal
#endif
static void Initialize()
{
s_SupportedHIDUsages = new[]
{
new HIDPageUsage(HID.GenericDesktop.Joystick),
new HIDPageUsage(HID.GenericDesktop.Gamepad),
new HIDPageUsage(HID.GenericDesktop.MultiAxisController),
};
InputSystem.RegisterLayout<HID>();
InputSystem.onFindLayoutForDevice += HID.OnFindLayoutForDevice;
// Add toolbar button to any devices using the "HID" interface. Opens
// a windows to browse the HID descriptor of the device.
#if UNITY_EDITOR
InputDeviceDebuggerWindow.onToolbarGUI +=
device =>
{
if (device.description.interfaceName == HID.kHIDInterface)
{
if (GUILayout.Button(s_HIDDescriptor, EditorStyles.toolbarButton))
{
HIDDescriptorWindow.CreateOrShowExisting(device.deviceId, device.description);
}
}
};
#endif
}
#if UNITY_EDITOR
private static readonly GUIContent s_HIDDescriptor = new GUIContent("HID Descriptor");
#endif
}
}