NEW: Can create devices reported by native using templates.
This commit is contained in:
Родитель
42daa0d115
Коммит
ceabd76b9e
|
@ -0,0 +1,35 @@
|
|||
namespace ISX
|
||||
{
|
||||
internal static class BuiltinDeviceTemplates
|
||||
{
|
||||
public static void RegisterTemplates(InputManager manager)
|
||||
{
|
||||
#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
|
||||
// Xbox one controller on OSX. State layout can be found here:
|
||||
// https://github.com/360Controller/360Controller/blob/master/360Controller/ControlStruct.h
|
||||
// struct State
|
||||
// {
|
||||
// short buttons;
|
||||
// byte triggerLeft;
|
||||
// byte triggerRight;
|
||||
// short leftX;
|
||||
// short leftY;
|
||||
// short rightX;
|
||||
// short rightY;
|
||||
// }
|
||||
// Report size is 14 bytes with some stuff at the end we can ignore.
|
||||
manager.RegisterTemplate(@"
|
||||
{
|
||||
""name"" : ""XboxGamepadOSX"",
|
||||
""extend"" : ""Gamepad"",
|
||||
""stateTypeCode"" : ""HID"",
|
||||
""device"" : {
|
||||
""interface"" : ""HID"",
|
||||
""product"" : ""Xbox One Wired Controller""
|
||||
}
|
||||
}
|
||||
");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 22daba482c044e26991dfbdc69b89d15
|
||||
timeCreated: 1507276459
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ISX
|
||||
{
|
||||
|
@ -43,9 +44,34 @@ namespace ISX
|
|||
return true;
|
||||
if (string.IsNullOrEmpty(right))
|
||||
return false;
|
||||
if (!Regex.IsMatch(right, left))
|
||||
if (!Regex.IsMatch(right, left, RegexOptions.IgnoreCase))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static InputDeviceDescription FromJson(string json)
|
||||
{
|
||||
var data = JsonUtility.FromJson<DeviceDescriptionJson>(json);
|
||||
|
||||
return new InputDeviceDescription
|
||||
{
|
||||
interfaceName = data.@interface,
|
||||
deviceClass = data.type,
|
||||
product = data.product,
|
||||
manufacturer = data.manufacturer,
|
||||
serial = data.serial,
|
||||
version = data.version
|
||||
};
|
||||
}
|
||||
|
||||
private struct DeviceDescriptionJson
|
||||
{
|
||||
public string @interface;
|
||||
public string type;
|
||||
public string product;
|
||||
public string serial;
|
||||
public string version;
|
||||
public string manufacturer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,16 @@ namespace ISX
|
|||
{
|
||||
// A chunk of memory signaling a data transfer in the input system.
|
||||
// This has to be layout compatible with native events.
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct InputEvent : IInputEventTypeInfo
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
private FourCC m_Type;
|
||||
[FieldOffset(4)]
|
||||
private int m_SizeInBytes;
|
||||
[FieldOffset(8)]
|
||||
private int m_DeviceId;
|
||||
[FieldOffset(12)]
|
||||
private double m_Time;
|
||||
|
||||
public FourCC type { get { return m_Type; } }
|
||||
|
|
|
@ -5,13 +5,16 @@ using UnityEngine;
|
|||
namespace ISX
|
||||
{
|
||||
// Full state update for an input device.
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct StateEvent : IInputEventTypeInfo
|
||||
{
|
||||
public const int Type = 0x42554C4B;
|
||||
public const int Type = 0x53544154;
|
||||
|
||||
[FieldOffset(0)]
|
||||
public InputEvent baseEvent;
|
||||
[FieldOffset(20)]
|
||||
public FourCC stateType;
|
||||
[FieldOffset(24)]
|
||||
public fixed byte stateData[1]; // Variable-sized.
|
||||
|
||||
public int stateSizeInBytes
|
||||
|
|
|
@ -91,12 +91,30 @@ namespace ISX
|
|||
|
||||
// Add it to our records.
|
||||
m_TemplateStrings[name.ToLower()] = json;
|
||||
|
||||
if (!deviceDescription.empty)
|
||||
{
|
||||
m_DeviceDescriptions.Add(new DeviceDescription
|
||||
{
|
||||
description = deviceDescription,
|
||||
template = name
|
||||
});
|
||||
|
||||
// The template has a device description, so if there's any native
|
||||
// devices we couldn't make sense of, see if the template helps
|
||||
// with that.
|
||||
for (var i = 0; i < m_NativeDevices.Count; ++i)
|
||||
{
|
||||
var deviceId = m_NativeDevices[i].deviceId;
|
||||
if (TryGetDeviceById(deviceId) != null)
|
||||
continue;
|
||||
|
||||
if (deviceDescription.Matches(m_NativeDevices[i].description))
|
||||
{
|
||||
AddNativeDevice(deviceId, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string TryFindTemplate(InputDeviceDescription deviceDescription)
|
||||
|
@ -244,6 +262,17 @@ namespace ISX
|
|||
return AddDevice(template);
|
||||
}
|
||||
|
||||
internal InputDevice AddNativeDevice(int deviceId, string template)
|
||||
{
|
||||
var setup = new InputControlSetup(template);
|
||||
var device = setup.Finish();
|
||||
device.m_Id = deviceId;
|
||||
|
||||
AddDevice(device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
public void RemoveDevice(InputDevice device)
|
||||
{
|
||||
//need to make sure that all actions rescan their source paths
|
||||
|
@ -330,6 +359,7 @@ namespace ISX
|
|||
m_DeviceDescriptions = new List<DeviceDescription>();
|
||||
m_Processors = new Dictionary<string, Type>();
|
||||
m_DevicesById = new Dictionary<int, InputDevice>();
|
||||
m_NativeDevices = new List<NativeDevice>();
|
||||
|
||||
// Determine our default set of enabled update types. By
|
||||
// default we enable both fixed and dynamic update because
|
||||
|
@ -376,10 +406,9 @@ namespace ISX
|
|||
// Register action modifiers.
|
||||
//RegisterModifier("Hold", typeof(HoldModifier));
|
||||
|
||||
InputTemplate.s_TemplateTypes = m_TemplateTypes;
|
||||
InputTemplate.s_TemplateStrings = m_TemplateStrings;
|
||||
BuiltinDeviceTemplates.RegisterTemplates(this);
|
||||
|
||||
NativeInputSystem.onUpdate += OnNativeUpdate;
|
||||
InstallGlobals();
|
||||
}
|
||||
|
||||
internal void Destroy()
|
||||
|
@ -388,6 +417,16 @@ namespace ISX
|
|||
InputTemplate.s_TemplateStrings = null;
|
||||
|
||||
NativeInputSystem.onUpdate -= OnNativeUpdate;
|
||||
NativeInputSystem.onDeviceDiscovered -= OnNativeDeviceDiscovered;
|
||||
}
|
||||
|
||||
// Revive after domain reload.
|
||||
internal void InstallGlobals()
|
||||
{
|
||||
InputTemplate.s_TemplateTypes = m_TemplateTypes;
|
||||
InputTemplate.s_TemplateStrings = m_TemplateStrings;
|
||||
NativeInputSystem.onUpdate += OnNativeUpdate;
|
||||
NativeInputSystem.onDeviceDiscovered += OnNativeDeviceDiscovered;
|
||||
}
|
||||
|
||||
// Bundles a template name and a device description.
|
||||
|
@ -398,10 +437,19 @@ namespace ISX
|
|||
public string template;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private struct NativeDevice
|
||||
{
|
||||
public InputDeviceDescription description;
|
||||
public int deviceId;
|
||||
}
|
||||
|
||||
private Dictionary<string, Type> m_TemplateTypes;
|
||||
private Dictionary<string, string> m_TemplateStrings;
|
||||
private Dictionary<string, Type> m_Processors;
|
||||
|
||||
private List<DeviceDescription> m_DeviceDescriptions;
|
||||
private List<NativeDevice> m_NativeDevices;
|
||||
|
||||
private InputDevice[] m_Devices;
|
||||
private Dictionary<int, InputDevice> m_DevicesById;
|
||||
|
@ -564,6 +612,26 @@ namespace ISX
|
|||
////TODO: need to update state change monitors
|
||||
}
|
||||
|
||||
private void OnNativeDeviceDiscovered(NativeInputDeviceInfo deviceInfo)
|
||||
{
|
||||
// Parse description.
|
||||
var description = InputDeviceDescription.FromJson(deviceInfo.deviceDescriptor);
|
||||
|
||||
// Remember device.
|
||||
m_NativeDevices.Add(new NativeDevice
|
||||
{
|
||||
description = description,
|
||||
deviceId = deviceInfo.deviceId
|
||||
});
|
||||
|
||||
// Try to turn it into a device instance.
|
||||
var template = TryFindTemplate(description);
|
||||
if (template != null)
|
||||
{
|
||||
AddNativeDevice(deviceInfo.deviceId, template);
|
||||
}
|
||||
}
|
||||
|
||||
// When we have the C# job system, this should be a job and NativeInputSystem should double
|
||||
// buffer input between frames. On top, the state change detection in here can be further
|
||||
// split off and put in its own job(s) (might not yield a gain; might be enough to just have
|
||||
|
@ -886,6 +954,7 @@ namespace ISX
|
|||
public TemplateState[] templateStrings;
|
||||
public DeviceDescription[] deviceDescriptions;
|
||||
public DeviceState[] devices;
|
||||
public NativeDevice[] nativeDevices;
|
||||
public InputStateBuffers buffers;
|
||||
public DeviceChangeEvent deviceChangeEvent;
|
||||
}
|
||||
|
@ -942,6 +1011,7 @@ namespace ISX
|
|||
templateStrings = templateStringArray,
|
||||
deviceDescriptions = m_DeviceDescriptions.ToArray(),
|
||||
devices = deviceArray,
|
||||
nativeDevices = m_NativeDevices.ToArray(),
|
||||
buffers = m_StateBuffers,
|
||||
deviceChangeEvent = m_DeviceChangeEvent
|
||||
};
|
||||
|
@ -961,6 +1031,8 @@ namespace ISX
|
|||
m_StateBuffers = m_SerializedState.buffers;
|
||||
m_CurrentUpdate = InputUpdateType.Dynamic;
|
||||
m_DeviceChangeEvent = m_SerializedState.deviceChangeEvent;
|
||||
m_DevicesById = new Dictionary<int, InputDevice>();
|
||||
m_NativeDevices = m_SerializedState.nativeDevices.ToList();
|
||||
|
||||
// Template types.
|
||||
foreach (var template in m_SerializedState.templateTypes)
|
||||
|
@ -984,6 +1056,7 @@ namespace ISX
|
|||
device.m_Id = state.deviceId;
|
||||
device.BakeOffsetIntoStateBlockRecursive(state.stateOffset);
|
||||
devices[i] = device;
|
||||
m_DevicesById[device.m_Id] = device;
|
||||
}
|
||||
m_Devices = devices;
|
||||
ReallocateStateBuffers();
|
||||
|
|
|
@ -143,13 +143,12 @@ namespace ISX
|
|||
if (s_Initialized)
|
||||
return;
|
||||
|
||||
// We may get InitializeOnLoad-related calls to the static class constructor
|
||||
// *after*
|
||||
var existingSystemObjects = Resources.FindObjectsOfTypeAll<InputSystemObject>();
|
||||
if (existingSystemObjects != null && existingSystemObjects.Length > 0)
|
||||
{
|
||||
m_SystemObject = existingSystemObjects[0];
|
||||
s_Manager = m_SystemObject.manager;
|
||||
s_Manager.InstallGlobals();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -613,5 +613,5 @@ PlayerSettings:
|
|||
projectName:
|
||||
organizationId:
|
||||
cloudEnabled: 0
|
||||
enableNativePlatformBackendsForNewInputSystem: 0
|
||||
disableOldInputManagerSupport: 0
|
||||
enableNativePlatformBackendsForNewInputSystem: 1
|
||||
disableOldInputManagerSupport: 1
|
||||
|
|
Загрузка…
Ссылка в новой задаче