CHANGE: Revert .NET profile back to 3.5.
This commit is contained in:
Родитель
794a5d165e
Коммит
fb2a22ab93
|
@ -1,5 +1,6 @@
|
|||
namespace ISX.DualShock
|
||||
{
|
||||
[InputPlugin]
|
||||
public static class DualShockSupport
|
||||
{
|
||||
public static void Initialize()
|
||||
|
|
|
@ -3,19 +3,25 @@ using UnityEngine;
|
|||
|
||||
namespace ISX.HID
|
||||
{
|
||||
// A generic HID device.
|
||||
//
|
||||
// This class represents a best effort to mirror the control setup of a HID
|
||||
// discovered in the system. It is used only as a fallback where we cannot
|
||||
// match the device to a specific product we know of. Wherever possible we
|
||||
// construct more specific device representations such as Gamepad.
|
||||
/// <summary>
|
||||
/// A generic HID input device.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class represents a best effort to mirror the control setup of a HID
|
||||
/// discovered in the system. It is used only as a fallback where we cannot
|
||||
/// match the device to a specific product we know of. Wherever possible we
|
||||
/// construct more specific device representations such as Gamepad.
|
||||
/// </remarks>
|
||||
public class HID : InputDevice
|
||||
{
|
||||
public const string kHIDInterface = "HID";
|
||||
public const string kHIDNamespace = "HID";
|
||||
|
||||
// The HID device descriptor as received from the device driver.
|
||||
public HIDDeviceDescriptor hidDescriptor => new HIDDeviceDescriptor();////TODO: parse on demand from description.capabilities
|
||||
public HIDDeviceDescriptor hidDescriptor
|
||||
{
|
||||
get { return new HIDDeviceDescriptor(); }
|
||||
}
|
||||
|
||||
internal static string OnFindTemplateForDevice(InputDeviceDescription description, string matchedTemplate)
|
||||
{
|
||||
|
@ -44,7 +50,7 @@ namespace ISX.HID
|
|||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.Log($"Could not parse HID descriptor (exception: {exception}");
|
||||
Debug.Log(string.Format("Could not parse HID descriptor (exception: {0}", exception));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -84,7 +90,7 @@ namespace ISX.HID
|
|||
|
||||
// Register template constructor that will turn the HID descriptor into an
|
||||
// InputTemplate instance.
|
||||
var templateName = $"{kHIDNamespace}::{description.product}";
|
||||
var templateName = string.Format("{0}::{1}", kHIDNamespace, description.product);
|
||||
var template = new HIDTemplate {descriptor = hidDeviceDescriptor};
|
||||
InputSystem.RegisterTemplateConstructor(() => template.Build(), templateName, baseTemplate, description);
|
||||
|
||||
|
@ -174,7 +180,7 @@ namespace ISX.HID
|
|||
switch (usagePage)
|
||||
{
|
||||
case UsagePage.Button:
|
||||
return $"button{usage}";
|
||||
return string.Format("button{0}", usage);
|
||||
case UsagePage.GenericDesktop:
|
||||
return ((GenericDesktop)usage).ToString();
|
||||
}
|
||||
|
|
|
@ -2,23 +2,34 @@ using UnityEngine;
|
|||
|
||||
namespace ISX.HID
|
||||
{
|
||||
[InputModule]
|
||||
/// <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 support HID requires a template 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 descriptor to populate the device.
|
||||
/// </remarks>
|
||||
[InputPlugin(
|
||||
description = "Support for surfacing HIDs as input devices without knowing the specific products being used.",
|
||||
supportedPlatforms = new[]
|
||||
{
|
||||
RuntimePlatform.WindowsEditor,
|
||||
RuntimePlatform.WindowsPlayer,
|
||||
RuntimePlatform.OSXEditor,
|
||||
RuntimePlatform.OSXPlayer,
|
||||
})]
|
||||
public static class HIDSupport
|
||||
{
|
||||
public static string description =>
|
||||
"Support for surfacing HIDs as input devices without knowing the specific products being used.";
|
||||
|
||||
public static RuntimePlatform[] supportedPlatforms =>
|
||||
new[]
|
||||
{
|
||||
RuntimePlatform.WindowsEditor,
|
||||
RuntimePlatform.WindowsPlayer,
|
||||
RuntimePlatform.OSXEditor,
|
||||
RuntimePlatform.OSXPlayer,
|
||||
RuntimePlatform.LinuxEditor,
|
||||
RuntimePlatform.LinuxPlayer
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Add support for generic HIDs to InputSystem.
|
||||
/// </summary>
|
||||
public static void Initialize()
|
||||
{
|
||||
InputSystem.RegisterTemplate<HID>();
|
||||
|
|
|
@ -2,7 +2,14 @@ namespace ISX.VR
|
|||
{
|
||||
public class OculusTouch : XRController
|
||||
{
|
||||
public new static OculusTouch leftHand => XRController.leftHand as OculusTouch;
|
||||
public new static OculusTouch rightHand => XRController.leftHand as OculusTouch;
|
||||
public new static OculusTouch leftHand
|
||||
{
|
||||
get { return XRController.leftHand as OculusTouch; }
|
||||
}
|
||||
|
||||
public new static OculusTouch rightHand
|
||||
{
|
||||
get { return XRController.leftHand as OculusTouch; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,10 @@ namespace ISX.XInput
|
|||
{
|
||||
public static class XInputSupport
|
||||
{
|
||||
public static string description => "Support for XInput-compatible controllers.";
|
||||
public static string description
|
||||
{
|
||||
get { return "Support for XInput-compatible controllers."; }
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
|
@ -17,6 +17,10 @@ using ISX.Editor;
|
|||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
#if !NET_4_0
|
||||
using ISX.Net35Compatibility;
|
||||
#endif
|
||||
|
||||
// These tests rely on the default template setup present in the code
|
||||
// of the system (e.g. they make assumptions about Gamepad is set up).
|
||||
public class FunctionalTests : InputTestFixture
|
||||
|
@ -1345,9 +1349,9 @@ public class FunctionalTests : InputTestFixture
|
|||
var setup = new InputControlSetup("Gamepad");
|
||||
var gamepad = (Gamepad)setup.Finish();
|
||||
|
||||
Assert.That(gamepad.stateBlock.sizeInBits, Is.EqualTo(Marshal.SizeOf<GamepadState>() * 8));
|
||||
Assert.That(gamepad.leftStick.stateBlock.byteOffset, Is.EqualTo(Marshal.OffsetOf<GamepadState>("leftStick").ToInt32()));
|
||||
Assert.That(gamepad.dpad.stateBlock.byteOffset, Is.EqualTo(Marshal.OffsetOf<GamepadState>("buttons").ToInt32()));
|
||||
Assert.That(gamepad.stateBlock.sizeInBits, Is.EqualTo(UnsafeUtility.SizeOf<GamepadState>() * 8));
|
||||
Assert.That(gamepad.leftStick.stateBlock.byteOffset, Is.EqualTo(UnsafeUtility.OffsetOf<GamepadState>("leftStick")));
|
||||
Assert.That(gamepad.dpad.stateBlock.byteOffset, Is.EqualTo(UnsafeUtility.OffsetOf<GamepadState>("buttons")));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -1358,8 +1362,8 @@ public class FunctionalTests : InputTestFixture
|
|||
var rightMotor = setup.GetControl("rightMotor");
|
||||
setup.Finish();
|
||||
|
||||
var outputOffset = Marshal.OffsetOf<GamepadState>("motors").ToInt32();
|
||||
var rightMotorOffset = outputOffset + Marshal.OffsetOf<GamepadOutputState>("rightMotor").ToInt32();
|
||||
var outputOffset = UnsafeUtility.OffsetOf<GamepadState>("motors");
|
||||
var rightMotorOffset = outputOffset + UnsafeUtility.OffsetOf<GamepadOutputState>("rightMotor");
|
||||
|
||||
Assert.That(rightMotor.stateBlock.byteOffset, Is.EqualTo(rightMotorOffset));
|
||||
}
|
||||
|
@ -1384,7 +1388,7 @@ public class FunctionalTests : InputTestFixture
|
|||
var setup = new InputControlSetup("Gamepad");
|
||||
var device = (Gamepad)setup.Finish();
|
||||
|
||||
var leftStickOffset = Marshal.OffsetOf<GamepadState>("leftStick").ToInt32();
|
||||
var leftStickOffset = UnsafeUtility.OffsetOf<GamepadState>("leftStick");
|
||||
var leftStickXOffset = leftStickOffset;
|
||||
var leftStickYOffset = leftStickOffset + 4;
|
||||
|
||||
|
@ -1399,7 +1403,7 @@ public class FunctionalTests : InputTestFixture
|
|||
InputSystem.AddDevice("Gamepad");
|
||||
var gamepad2 = (Gamepad)InputSystem.AddDevice("Gamepad");
|
||||
|
||||
var leftStickOffset = Marshal.OffsetOf<GamepadState>("leftStick").ToInt32();
|
||||
var leftStickOffset = UnsafeUtility.OffsetOf<GamepadState>("leftStick");
|
||||
var leftStickXOffset = leftStickOffset;
|
||||
var leftStickYOffset = leftStickOffset + 4;
|
||||
|
||||
|
@ -1416,7 +1420,7 @@ public class FunctionalTests : InputTestFixture
|
|||
var gamepad1 = InputSystem.AddDevice("Gamepad");
|
||||
var gamepad2 = InputSystem.AddDevice("Gamepad");
|
||||
|
||||
var sizeofGamepadState = Marshal.SizeOf<GamepadState>();
|
||||
var sizeofGamepadState = UnsafeUtility.SizeOf<GamepadState>();
|
||||
|
||||
Assert.That(gamepad1.stateBlock.byteOffset, Is.EqualTo(0));
|
||||
Assert.That(gamepad2.stateBlock.byteOffset, Is.EqualTo(gamepad1.stateBlock.byteOffset + sizeofGamepadState));
|
||||
|
@ -2205,7 +2209,7 @@ public class FunctionalTests : InputTestFixture
|
|||
InputDevice device = null;
|
||||
Assert.That(() => device = InputSystem.AddDevice(description), Throws.Nothing);
|
||||
|
||||
Assert.That(InputSystem.GetControls($"/<{baseTemplate}>"), Has.Exactly(1).SameAs(device));
|
||||
Assert.That(InputSystem.GetControls(string.Format("/<{0}>", baseTemplate)), Has.Exactly(1).SameAs(device));
|
||||
Assert.That(device.name, Is.EqualTo(baseTemplate));
|
||||
Assert.That(device.description.manufacturer, Is.EqualTo(manufacturer));
|
||||
Assert.That(device.description.interfaceName, Is.EqualTo(interfaceName));
|
||||
|
@ -4351,7 +4355,8 @@ public class FunctionalTests : InputTestFixture
|
|||
|
||||
local.StartSending();
|
||||
|
||||
var remoteGamepadTemplate = $"{InputRemoting.kRemoteTemplateNamespacePrefix}0::{localGamepad.template}";
|
||||
var remoteGamepadTemplate =
|
||||
string.Format("{0}0::{1}", InputRemoting.kRemoteTemplateNamespacePrefix, localGamepad.template);
|
||||
|
||||
// Make sure that our "remote" system now has the data we initially
|
||||
// set up on the local system.
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
using ISX;
|
||||
|
||||
// Unit tests for InputData.
|
||||
public class InputDataTests
|
||||
{
|
||||
private InputData m_Data;
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using ISX;
|
||||
using NUnit.Framework;
|
||||
|
@ -42,7 +43,7 @@ public class PerformanceTests
|
|||
var totalTime = endTime - startTime;
|
||||
|
||||
Assert.That(totalTime, Is.LessThan(0.01 / 1000.0));
|
||||
Debug.Log($"{MethodBase.GetCurrentMethod().Name}: {totalTime*1000}ms");
|
||||
Debug.Log(string.Format("{0}: {1}ms", MethodBase.GetCurrentMethod().Name, totalTime * 1000));
|
||||
}
|
||||
|
||||
////TODO: same test but with several actions listening on each gamepad
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: eb7028da89c84269a0b936b350bca4e4
|
||||
timeCreated: 1511482273
|
|
@ -0,0 +1,6 @@
|
|||
using ISX;
|
||||
|
||||
public class UnitTests_InputData
|
||||
{
|
||||
private InputData m_Data;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using NUnit.Framework;
|
||||
|
||||
public class UnitTests_InputEventQueue
|
||||
{
|
||||
[Test]
|
||||
[Category("Events")]
|
||||
public void CanQueueEvent()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a4b0932be94e46ae91daae57e9413cad
|
||||
timeCreated: 1511482285
|
|
@ -53,11 +53,20 @@ namespace ISX
|
|||
Cancelled
|
||||
}
|
||||
|
||||
public string name => m_Name;
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
}
|
||||
|
||||
public Phase phase => m_CurrentPhase;
|
||||
public Phase phase
|
||||
{
|
||||
get { return m_CurrentPhase; }
|
||||
}
|
||||
|
||||
public InputActionSet set => isSingletonAction ? null : m_ActionSet;
|
||||
public InputActionSet set
|
||||
{
|
||||
get { return isSingletonAction ? null : m_ActionSet; }
|
||||
}
|
||||
|
||||
////TODO: add support for turning binding array into displayable info
|
||||
//// (allow to constrain by sets of devics set on action set)
|
||||
|
@ -87,12 +96,35 @@ namespace ISX
|
|||
}
|
||||
|
||||
////REVIEW: expose this as a struct?
|
||||
public InputControl lastTriggerControl => m_LastTrigger.control;
|
||||
public double lastTriggerTime => m_LastTrigger.time;
|
||||
public double lastTriggerStartTime => m_LastTrigger.startTime;
|
||||
public double lastTriggerDuration => m_LastTrigger.time - m_LastTrigger.startTime;
|
||||
public InputBinding lastTriggerBinding => GetBinding(m_LastTrigger.bindingIndex);
|
||||
public IInputActionModifier lastTriggerModifier => GetModifier(m_LastTrigger.bindingIndex, m_LastTrigger.modifierIndex);
|
||||
public InputControl lastTriggerControl
|
||||
{
|
||||
get { return m_LastTrigger.control; }
|
||||
}
|
||||
|
||||
public double lastTriggerTime
|
||||
{
|
||||
get { return m_LastTrigger.time; }
|
||||
}
|
||||
|
||||
public double lastTriggerStartTime
|
||||
{
|
||||
get { return m_LastTrigger.startTime; }
|
||||
}
|
||||
|
||||
public double lastTriggerDuration
|
||||
{
|
||||
get { return m_LastTrigger.time - m_LastTrigger.startTime; }
|
||||
}
|
||||
|
||||
public InputBinding lastTriggerBinding
|
||||
{
|
||||
get { return GetBinding(m_LastTrigger.bindingIndex); }
|
||||
}
|
||||
|
||||
public IInputActionModifier lastTriggerModifier
|
||||
{
|
||||
get { return GetModifier(m_LastTrigger.bindingIndex, m_LastTrigger.modifierIndex); }
|
||||
}
|
||||
|
||||
public bool enabled
|
||||
{
|
||||
|
@ -133,7 +165,7 @@ namespace ISX
|
|||
public InputAction(string name = null, string binding = null, string modifiers = null)
|
||||
{
|
||||
if (binding == null && modifiers != null)
|
||||
throw new ArgumentException("Cannot have modifier without binding", nameof(modifiers));
|
||||
throw new ArgumentException("Cannot have modifier without binding", "modifiers");
|
||||
|
||||
m_Name = name;
|
||||
if (binding != null)
|
||||
|
@ -151,7 +183,7 @@ namespace ISX
|
|||
return "<unnamed>";
|
||||
|
||||
if (m_ActionSet != null && !isSingletonAction && !string.IsNullOrEmpty(m_ActionSet.name))
|
||||
return $"{m_ActionSet.name}/{m_Name}";
|
||||
return string.Format("{0}/{1}", m_ActionSet.name, m_Name);
|
||||
|
||||
return m_Name;
|
||||
}
|
||||
|
@ -216,7 +248,8 @@ namespace ISX
|
|||
public AddBindingSyntax AddBinding(string path, string modifiers = null, string groups = null)
|
||||
{
|
||||
if (enabled)
|
||||
throw new InvalidOperationException($"Cannot add binding to action '{this}' while the action is enabled");
|
||||
throw new InvalidOperationException(
|
||||
string.Format("Cannot add binding to action '{0}' while the action is enabled", this));
|
||||
|
||||
var binding = new InputBinding {path = path, modifiers = modifiers, group = groups};
|
||||
|
||||
|
@ -275,11 +308,13 @@ namespace ISX
|
|||
public void ApplyBindingOverride(int bindingIndex, string path)
|
||||
{
|
||||
if (enabled)
|
||||
throw new InvalidOperationException($"Cannot change overrides on action '{this}' while the action is enabled");
|
||||
throw new InvalidOperationException(
|
||||
string.Format("Cannot change overrides on action '{0}' while the action is enabled", this));
|
||||
|
||||
if (bindingIndex < 0 || bindingIndex > m_BindingsCount)
|
||||
throw new IndexOutOfRangeException(
|
||||
$"Binding index {bindingIndex} is out of range for action '{this}' which has {m_BindingsCount} bindings");
|
||||
string.Format("Binding index {0} is out of range for action '{1}' which has {2} bindings",
|
||||
bindingIndex, this, m_BindingsCount));
|
||||
|
||||
m_Bindings[m_BindingsStartIndex + bindingIndex].overridePath = path;
|
||||
}
|
||||
|
@ -297,7 +332,8 @@ namespace ISX
|
|||
public void ApplyBindingOverride(InputBindingOverride bindingOverride)
|
||||
{
|
||||
if (enabled)
|
||||
throw new InvalidOperationException($"Cannot change overrides on action '{this}' while the action is enabled");
|
||||
throw new InvalidOperationException(
|
||||
string.Format("Cannot change overrides on action '{0}' while the action is enabled", this));
|
||||
|
||||
if (bindingOverride.binding == string.Empty)
|
||||
bindingOverride.binding = null;
|
||||
|
@ -322,7 +358,8 @@ namespace ISX
|
|||
public void RemoveAllBindingOverrides()
|
||||
{
|
||||
if (enabled)
|
||||
throw new InvalidOperationException($"Cannot removed overrides from action '{this}' while the action is enabled");
|
||||
throw new InvalidOperationException(
|
||||
string.Format("Cannot removed overrides from action '{0}' while the action is enabled", this));
|
||||
|
||||
for (var i = 0; i < m_BindingsCount; ++i)
|
||||
m_Bindings[m_BindingsStartIndex + i].overridePath = null;
|
||||
|
@ -392,7 +429,10 @@ namespace ISX
|
|||
public int modifierIndex;
|
||||
}
|
||||
|
||||
private bool isSingletonAction => m_ActionSet == null || ReferenceEquals(m_ActionSet.m_SingletonAction, this);
|
||||
private bool isSingletonAction
|
||||
{
|
||||
get { return m_ActionSet == null || ReferenceEquals(m_ActionSet.m_SingletonAction, this); }
|
||||
}
|
||||
|
||||
private void CreateInternalActionSetForSingletonAction()
|
||||
{
|
||||
|
@ -422,7 +462,9 @@ namespace ISX
|
|||
if (!haveGroup)
|
||||
// Group is required to disambiguate.
|
||||
throw new InvalidOperationException(
|
||||
$"Action {this} has multiple bindings; overriding binding requires the use of binding groups so the action knows which binding to override. Set 'group' property on InputBindingOverride.");
|
||||
string.Format(
|
||||
"Action {0} has multiple bindings; overriding binding requires the use of binding groups so the action knows which binding to override. Set 'group' property on InputBindingOverride.",
|
||||
this));
|
||||
|
||||
int groupStringLength;
|
||||
var indexInGroup = bindingOverride.GetIndexInGroup(out groupStringLength);
|
||||
|
@ -600,13 +642,17 @@ namespace ISX
|
|||
{
|
||||
if (newPhase == Phase.Started && currentPhase != Phase.Waiting)
|
||||
throw new InvalidOperationException(
|
||||
$"Cannot go from '{m_CurrentPhase}' to '{Phase.Started}'; must be '{Phase.Waiting}' (action: {this}, modifier: {GetModifier(bindingIndex, modifierIndex)})");
|
||||
string.Format("Cannot go from '{0}' to '{1}'; must be '{2}' (action: {3}, modifier: {4})",
|
||||
m_CurrentPhase, Phase.Started, Phase.Waiting, this, GetModifier(bindingIndex, modifierIndex)));
|
||||
if (newPhase == Phase.Performed && currentPhase != Phase.Waiting && currentPhase != Phase.Started)
|
||||
throw new InvalidOperationException(
|
||||
$"Cannot go from '{m_CurrentPhase}' to '{Phase.Performed}'; must be '{Phase.Waiting}' or '{Phase.Started}' (action: {this}, modifier: {GetModifier(bindingIndex, modifierIndex)})");
|
||||
string.Format("Cannot go from '{0}' to '{1}'; must be '{2}' or '{3}' (action: {4}, modifier: {5})",
|
||||
m_CurrentPhase, Phase.Performed, Phase.Waiting, Phase.Started, this,
|
||||
GetModifier(bindingIndex, modifierIndex)));
|
||||
if (newPhase == Phase.Cancelled && currentPhase != Phase.Started)
|
||||
throw new InvalidOperationException(
|
||||
$"Cannot go from '{m_CurrentPhase}' to '{Phase.Cancelled}'; must be '{Phase.Started}' (action: {this}, modifier: {GetModifier(bindingIndex, modifierIndex)})");
|
||||
string.Format("Cannot go from '{0}' to '{1}'; must be '{2}' (action: {3}, modifier: {4})",
|
||||
m_CurrentPhase, Phase.Cancelled, Phase.Started, this, GetModifier(bindingIndex, modifierIndex)));
|
||||
}
|
||||
|
||||
private InputBinding GetBinding(int bindingIndex)
|
||||
|
@ -738,19 +784,60 @@ namespace ISX
|
|||
internal bool m_ControlIsAtDefaultValue;
|
||||
internal bool m_TimerHasExpired;
|
||||
|
||||
internal int bindingIndex => m_Trigger.bindingIndex;
|
||||
internal int modifierIndex => m_Trigger.modifierIndex;
|
||||
internal int bindingIndex
|
||||
{
|
||||
get { return m_Trigger.bindingIndex; }
|
||||
}
|
||||
|
||||
public InputAction action => m_Action;
|
||||
public InputControl control => m_Trigger.control;
|
||||
public Phase phase => m_Trigger.phase;
|
||||
public double time => m_Trigger.time;
|
||||
public double startTime => m_Trigger.startTime;
|
||||
public bool controlHasDefaultValue => m_ControlIsAtDefaultValue;
|
||||
public bool timerHasExpired => m_TimerHasExpired;
|
||||
internal int modifierIndex
|
||||
{
|
||||
get { return m_Trigger.modifierIndex; }
|
||||
}
|
||||
|
||||
public bool isWaiting => phase == Phase.Waiting;
|
||||
public bool isStarted => phase == Phase.Started;
|
||||
public InputAction action
|
||||
{
|
||||
get { return m_Action; }
|
||||
}
|
||||
|
||||
public InputControl control
|
||||
{
|
||||
get { return m_Trigger.control; }
|
||||
}
|
||||
|
||||
public Phase phase
|
||||
{
|
||||
get { return m_Trigger.phase; }
|
||||
}
|
||||
|
||||
public double time
|
||||
{
|
||||
get { return m_Trigger.time; }
|
||||
}
|
||||
|
||||
public double startTime
|
||||
{
|
||||
get { return m_Trigger.startTime; }
|
||||
}
|
||||
|
||||
public bool controlHasDefaultValue
|
||||
{
|
||||
get { return m_ControlIsAtDefaultValue; }
|
||||
}
|
||||
|
||||
public bool timerHasExpired
|
||||
{
|
||||
get { return m_TimerHasExpired; }
|
||||
}
|
||||
|
||||
public bool isWaiting
|
||||
{
|
||||
get { return phase == Phase.Waiting; }
|
||||
}
|
||||
|
||||
public bool isStarted
|
||||
{
|
||||
get { return phase == Phase.Started; }
|
||||
}
|
||||
|
||||
public void Started()
|
||||
{
|
||||
|
@ -791,18 +878,40 @@ namespace ISX
|
|||
internal double m_Time;
|
||||
internal double m_StartTime;
|
||||
|
||||
public InputAction action => m_Action;
|
||||
public InputControl control => m_Control;
|
||||
public IInputActionModifier modifier => m_Modifier;
|
||||
public InputAction action
|
||||
{
|
||||
get { return m_Action; }
|
||||
}
|
||||
|
||||
public InputControl control
|
||||
{
|
||||
get { return m_Control; }
|
||||
}
|
||||
|
||||
public IInputActionModifier modifier
|
||||
{
|
||||
get { return m_Modifier; }
|
||||
}
|
||||
|
||||
public TValue GetValue<TValue>()
|
||||
{
|
||||
return ((InputControl<TValue>)control).value;
|
||||
}
|
||||
|
||||
public double time => m_Time;
|
||||
public double startTime => m_StartTime;
|
||||
public double duration => m_Time - m_StartTime;
|
||||
public double time
|
||||
{
|
||||
get { return m_Time; }
|
||||
}
|
||||
|
||||
public double startTime
|
||||
{
|
||||
get { return m_StartTime; }
|
||||
}
|
||||
|
||||
public double duration
|
||||
{
|
||||
get { return m_Time - m_StartTime; }
|
||||
}
|
||||
}
|
||||
|
||||
public struct AddBindingSyntax
|
||||
|
|
|
@ -19,7 +19,10 @@ namespace ISX
|
|||
{
|
||||
public const string kExtension = "inputactions";
|
||||
|
||||
public ReadOnlyArray<InputActionSet> actionSets => new ReadOnlyArray<InputActionSet>(m_ActionSets);
|
||||
public ReadOnlyArray<InputActionSet> actionSets
|
||||
{
|
||||
get { return new ReadOnlyArray<InputActionSet>(m_ActionSets); }
|
||||
}
|
||||
|
||||
// Return a JSON representation of the asset.
|
||||
public string ToJson()
|
||||
|
@ -37,12 +40,13 @@ namespace ISX
|
|||
public void AddActionSet(InputActionSet set)
|
||||
{
|
||||
if (set == null)
|
||||
throw new ArgumentNullException(nameof(set));
|
||||
throw new ArgumentNullException("set");
|
||||
if (string.IsNullOrEmpty(set.name))
|
||||
throw new InvalidOperationException("Sets added to an input action asset must be named");
|
||||
////REVIEW: some of the rules here seem stupid; just replace?
|
||||
if (TryGetActionSet(set.name) != null)
|
||||
throw new InvalidOperationException($"An action set called '{set.name}' already exists in the asset");
|
||||
throw new InvalidOperationException(
|
||||
string.Format("An action set called '{0}' already exists in the asset", set.name));
|
||||
|
||||
ArrayHelpers.Append(ref m_ActionSets, set);
|
||||
}
|
||||
|
@ -50,7 +54,7 @@ namespace ISX
|
|||
public void RemoveActionSet(InputActionSet set)
|
||||
{
|
||||
if (set == null)
|
||||
throw new ArgumentNullException(nameof(set));
|
||||
throw new ArgumentNullException("set");
|
||||
|
||||
ArrayHelpers.Erase(ref m_ActionSets, set);
|
||||
}
|
||||
|
@ -58,7 +62,7 @@ namespace ISX
|
|||
public void RemoveActionSet(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
throw new ArgumentNullException("name");
|
||||
|
||||
var set = TryGetActionSet(name);
|
||||
if (set != null)
|
||||
|
@ -68,7 +72,7 @@ namespace ISX
|
|||
public InputActionSet TryGetActionSet(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException(nameof(name));
|
||||
throw new ArgumentException("name");
|
||||
|
||||
if (m_ActionSets == null)
|
||||
return null;
|
||||
|
@ -87,7 +91,8 @@ namespace ISX
|
|||
{
|
||||
var set = TryGetActionSet(name);
|
||||
if (set == null)
|
||||
throw new KeyNotFoundException($"Could not find an action set called '{name}' in asset '{this}'");
|
||||
throw new KeyNotFoundException(string.Format("Could not find an action set called '{0}' in asset '{1}'",
|
||||
name, this));
|
||||
return set;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,9 +23,9 @@ namespace ISX
|
|||
public static int ApplyOverridesUsingMatchingControls(this InputAction action, InputControl control)
|
||||
{
|
||||
if (action == null)
|
||||
throw new ArgumentNullException(nameof(action));
|
||||
throw new ArgumentNullException("action");
|
||||
if (control == null)
|
||||
throw new ArgumentNullException(nameof(control));
|
||||
throw new ArgumentNullException("control");
|
||||
|
||||
var bindings = action.bindings;
|
||||
var bindingsCount = bindings.Count;
|
||||
|
@ -47,9 +47,9 @@ namespace ISX
|
|||
public static int ApplyOverridesUsingMatchingControls(this InputActionSet actionSet, InputControl control)
|
||||
{
|
||||
if (actionSet == null)
|
||||
throw new ArgumentNullException(nameof(actionSet));
|
||||
throw new ArgumentNullException("actionSet");
|
||||
if (control == null)
|
||||
throw new ArgumentNullException(nameof(control));
|
||||
throw new ArgumentNullException("control");
|
||||
|
||||
var actions = actionSet.actions;
|
||||
var actionCount = actions.Count;
|
||||
|
@ -126,10 +126,11 @@ namespace ISX
|
|||
public static RebindOperation PerformUserRebind(InputAction action, InputAction cancel = null)
|
||||
{
|
||||
if (action == null)
|
||||
throw new ArgumentNullException(nameof(action));
|
||||
throw new ArgumentNullException("action");
|
||||
if (action.bindings.Count == 0)
|
||||
throw new ArgumentException(
|
||||
$"For rebinding, action must have at least one existing binding (action: {action})", nameof(action));
|
||||
string.Format("For rebinding, action must have at least one existing binding (action: {0})",
|
||||
action), "action");
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
@ -44,9 +44,9 @@ namespace ISX
|
|||
public void Set(InputActionAsset asset, string set, string action)
|
||||
{
|
||||
if (string.IsNullOrEmpty(set))
|
||||
throw new ArgumentException(nameof(set));
|
||||
throw new ArgumentException("set");
|
||||
if (string.IsNullOrEmpty(action))
|
||||
throw new ArgumentException(nameof(action));
|
||||
throw new ArgumentException("action");
|
||||
|
||||
m_Asset = asset;
|
||||
m_SetName = set;
|
||||
|
@ -56,7 +56,7 @@ namespace ISX
|
|||
public override string ToString()
|
||||
{
|
||||
if (m_Asset != null)
|
||||
return $"{m_Action.name}:{m_SetName}/{m_ActionName}";
|
||||
return string.Format("{0}:{1}/{2}", m_Action.name, m_SetName, m_ActionName);
|
||||
|
||||
return base.ToString();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,20 @@ namespace ISX
|
|||
[Serializable]
|
||||
public class InputActionSet : ISerializationCallbackReceiver, ICloneable
|
||||
{
|
||||
public string name => m_Name;
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
}
|
||||
|
||||
public bool enabled => m_EnabledActionsCount > 0;
|
||||
public bool enabled
|
||||
{
|
||||
get { return m_EnabledActionsCount > 0; }
|
||||
}
|
||||
|
||||
public ReadOnlyArray<InputAction> actions => new ReadOnlyArray<InputAction>(m_Actions);
|
||||
public ReadOnlyArray<InputAction> actions
|
||||
{
|
||||
get { return new ReadOnlyArray<InputAction>(m_Actions); }
|
||||
}
|
||||
|
||||
public InputActionSet(string name = null)
|
||||
{
|
||||
|
@ -33,9 +42,10 @@ namespace ISX
|
|||
public InputAction AddAction(string name, string binding = null, string modifiers = null, string groups = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException("Action must have name", nameof(name));
|
||||
throw new ArgumentException("Action must have name", "name");
|
||||
if (TryGetAction(name) != null)
|
||||
throw new InvalidOperationException($"Cannot add action with duplicate name '{name}' to set '{this.name}'");
|
||||
throw new InvalidOperationException(
|
||||
string.Format("Cannot add action with duplicate name '{0}' to set '{1}'", name, this.name));
|
||||
|
||||
var action = new InputAction(name);
|
||||
ArrayHelpers.Append(ref m_Actions, action);
|
||||
|
@ -64,7 +74,8 @@ namespace ISX
|
|||
{
|
||||
var action = TryGetAction(name);
|
||||
if (action == null)
|
||||
throw new KeyNotFoundException($"Could not find action '{name}' in set '{this.name}'");
|
||||
throw new KeyNotFoundException(string.Format("Could not find action '{0}' in set '{1}'", name,
|
||||
this.name));
|
||||
return action;
|
||||
}
|
||||
|
||||
|
@ -131,7 +142,7 @@ namespace ISX
|
|||
// them. Cloning them is not allowed.
|
||||
if (m_SingletonAction != null)
|
||||
throw new InvalidOperationException(
|
||||
$"Cloning internal set of singleton action '{m_SingletonAction}' is not allowed");
|
||||
string.Format("Cloning internal set of singleton action '{0}' is not allowed", m_SingletonAction));
|
||||
|
||||
var clone = new InputActionSet
|
||||
{
|
||||
|
@ -232,7 +243,10 @@ namespace ISX
|
|||
}
|
||||
}
|
||||
|
||||
public bool isPartOfChain => chainsWithNext || isEndOfChain;
|
||||
public bool isPartOfChain
|
||||
{
|
||||
get { return chainsWithNext || isEndOfChain; }
|
||||
}
|
||||
}
|
||||
|
||||
////TODO: when re-resolving, we need to preserve ModifierStates and not just reset them
|
||||
|
@ -364,7 +378,7 @@ namespace ISX
|
|||
//// moving the logic to a shared place.
|
||||
//// Alternatively, may split the paths. May help in getting rid of unnecessary allocations.
|
||||
|
||||
var firstModifierIndex = modifiers?.Count ?? 0;
|
||||
var firstModifierIndex = modifiers != null ? modifiers.Count : 0;
|
||||
|
||||
////TODO: get rid of the extra array allocations here
|
||||
var list = InputTemplate.ParseNameAndParameterList(modifierString);
|
||||
|
@ -373,12 +387,14 @@ namespace ISX
|
|||
// Look up modifier.
|
||||
var type = InputSystem.TryGetModifier(list[i].name);
|
||||
if (type == null)
|
||||
throw new Exception($"No modifier with name '{list[i].name}' (mentioned in '{modifierString}') has been registered");
|
||||
throw new Exception(string.Format(
|
||||
"No modifier with name '{0}' (mentioned in '{1}') has been registered", list[i].name,
|
||||
modifierString));
|
||||
|
||||
// Instantiate it.
|
||||
var modifier = Activator.CreateInstance(type) as IInputActionModifier;
|
||||
if (modifier == null)
|
||||
throw new Exception($"Modifier '{list[i].name}' is not an IInputActionModifier");
|
||||
throw new Exception(string.Format("Modifier '{0}' is not an IInputActionModifier", list[i].name));
|
||||
|
||||
// Pass parameters to it.
|
||||
InputControlSetup.SetParameters(modifier, list[i].parameters);
|
||||
|
@ -589,13 +605,13 @@ namespace ISX
|
|||
var actions = new List<List<InputAction>>();
|
||||
var bindings = new List<List<InputBinding>>();
|
||||
|
||||
var actionCount = this.actions?.Length ?? 0;
|
||||
var actionCount = this.actions != null ? this.actions.Length : 0;
|
||||
for (var i = 0; i < actionCount; ++i)
|
||||
{
|
||||
var jsonAction = this.actions[i];
|
||||
|
||||
if (string.IsNullOrEmpty(jsonAction.name))
|
||||
throw new Exception($"Action number {i + 1} has no name");
|
||||
throw new Exception(string.Format("Action number {0} has no name", i + 1));
|
||||
|
||||
////REVIEW: make sure all action names are unique?
|
||||
|
||||
|
@ -609,7 +625,8 @@ namespace ISX
|
|||
actionName = actionName.Substring(indexOfFirstSlash + 1);
|
||||
|
||||
if (string.IsNullOrEmpty(actionName))
|
||||
throw new Exception($"Invalid action name '{jsonAction.name}' (missing action name after '/')");
|
||||
throw new Exception(string.Format(
|
||||
"Invalid action name '{0}' (missing action name after '/')", jsonAction.name));
|
||||
}
|
||||
|
||||
// Try to find existing set.
|
||||
|
@ -684,7 +701,7 @@ namespace ISX
|
|||
actionsJson[i] = ActionJson.FromAction(actions[i]);
|
||||
|
||||
if (haveSetName)
|
||||
actionsJson[i].name = $"{set.name}/{actions[i].name}";
|
||||
actionsJson[i].name = string.Format("{0}/{1}", set.name, actions[i].name);
|
||||
}
|
||||
|
||||
return new ActionFileJson
|
||||
|
@ -713,7 +730,7 @@ namespace ISX
|
|||
actionsJson[actionIndex] = ActionJson.FromAction(actions[i]);
|
||||
|
||||
if (haveSetName)
|
||||
actionsJson[actionIndex].name = $"{set.name}/{actions[i].name}";
|
||||
actionsJson[actionIndex].name = string.Format("{0}/{1}", set.name, actions[i].name);
|
||||
|
||||
++actionIndex;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,10 @@ namespace ISX
|
|||
[Serializable]
|
||||
public class InputActionWrapper : ICloneable
|
||||
{
|
||||
public InputActionAsset asset => m_Asset;
|
||||
public InputActionAsset asset
|
||||
{
|
||||
get { return m_Asset; }
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
{
|
||||
|
|
|
@ -5,7 +5,10 @@ namespace ISX
|
|||
public class HoldModifier : IInputActionModifier
|
||||
{
|
||||
public float duration;
|
||||
public float durationOrDefault => duration > 0.0 ? duration : InputConfiguration.HoldTime;
|
||||
public float durationOrDefault
|
||||
{
|
||||
get { return duration > 0.0 ? duration : InputConfiguration.HoldTime; }
|
||||
}
|
||||
|
||||
// If true, the action will be performed repeatedly every 'duration'
|
||||
// intervals for as long as a control is pressed.
|
||||
|
|
|
@ -6,7 +6,10 @@ namespace ISX
|
|||
{
|
||||
public float duration;
|
||||
////REVIEW: this seems stupid; shouldn't a slow tap just be anything that takes longer than TapTime?
|
||||
public float durationOrDefault => duration > 0.0f ? duration : InputConfiguration.SlowTapTime;
|
||||
public float durationOrDefault
|
||||
{
|
||||
get { return duration > 0.0f ? duration : InputConfiguration.SlowTapTime; }
|
||||
}
|
||||
|
||||
// If this is non-zero, then if the control is held for longer than
|
||||
// this time, the slow tap is not performed when the control is finally
|
||||
|
|
|
@ -5,7 +5,10 @@ namespace ISX
|
|||
public class TapModifier : IInputActionModifier
|
||||
{
|
||||
public float duration;
|
||||
public float durationOrDefault => duration > 0.0 ? duration : InputConfiguration.TapTime;
|
||||
public float durationOrDefault
|
||||
{
|
||||
get { return duration > 0.0 ? duration : InputConfiguration.TapTime; }
|
||||
}
|
||||
|
||||
private double m_TapStartTime;
|
||||
|
||||
|
|
|
@ -7,7 +7,10 @@ namespace ISX
|
|||
// returns 1.0; otherwise it returns 0.0.
|
||||
public class AnyKeyControl : InputControl<float>
|
||||
{
|
||||
public bool isPressed => value > 0.0f;
|
||||
public bool isPressed
|
||||
{
|
||||
get { return value > 0.0f; }
|
||||
}
|
||||
|
||||
public AnyKeyControl()
|
||||
{
|
||||
|
@ -17,7 +20,7 @@ namespace ISX
|
|||
|
||||
protected override float ReadRawValueFrom(IntPtr statePtr)
|
||||
{
|
||||
var valuePtr = statePtr + (int)m_StateBlock.byteOffset;
|
||||
var valuePtr = new IntPtr(statePtr.ToInt64() + (int)m_StateBlock.byteOffset);
|
||||
return CheckStateIsAllZeros(valuePtr) ? 0.0f : 1.0f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace ISX
|
|||
protected override unsafe float ReadRawValueFrom(IntPtr statePtr)
|
||||
{
|
||||
float value;
|
||||
var valuePtr = statePtr + (int)m_StateBlock.byteOffset;
|
||||
var valuePtr = new IntPtr(statePtr.ToInt64() + (int)m_StateBlock.byteOffset);
|
||||
|
||||
var format = m_StateBlock.format;
|
||||
if (format == InputStateBlock.kTypeFloat)
|
||||
|
@ -69,7 +69,8 @@ namespace ISX
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"State format '{m_StateBlock.format}' is not supported as state for {GetType().Name}");
|
||||
throw new Exception(string.Format("State format '{0}' is not supported as state for {1}",
|
||||
m_StateBlock.format, GetType().Name));
|
||||
}
|
||||
|
||||
return Preprocess(value);
|
||||
|
|
|
@ -12,7 +12,10 @@ namespace ISX
|
|||
public class ButtonControl : AxisControl
|
||||
{
|
||||
public float pressPoint;
|
||||
public float pressPointOrDefault => pressPoint > 0.0f ? pressPoint : InputConfiguration.ButtonPressPoint;
|
||||
public float pressPointOrDefault
|
||||
{
|
||||
get { return pressPoint > 0.0f ? pressPoint : InputConfiguration.ButtonPressPoint; }
|
||||
}
|
||||
|
||||
public ButtonControl()
|
||||
{
|
||||
|
@ -28,8 +31,19 @@ namespace ISX
|
|||
}
|
||||
|
||||
////REVIEW: this may have to go into value itself; otherwise actions will trigger on the slightest value change
|
||||
public bool isPressed => IsValueConsideredPressed(value);
|
||||
public bool wasJustPressed => IsValueConsideredPressed(value) && !IsValueConsideredPressed(previous);
|
||||
public bool wasJustReleased => !IsValueConsideredPressed(value) && IsValueConsideredPressed(previous);
|
||||
public bool isPressed
|
||||
{
|
||||
get { return IsValueConsideredPressed(value); }
|
||||
}
|
||||
|
||||
public bool wasJustPressed
|
||||
{
|
||||
get { return IsValueConsideredPressed(value) && !IsValueConsideredPressed(previous); }
|
||||
}
|
||||
|
||||
public bool wasJustReleased
|
||||
{
|
||||
get { return !IsValueConsideredPressed(value) && IsValueConsideredPressed(previous); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace ISX
|
|||
|
||||
protected override unsafe int ReadRawValueFrom(IntPtr statePtr)
|
||||
{
|
||||
var valuePtr = statePtr + (int)m_StateBlock.byteOffset;
|
||||
var valuePtr = new IntPtr(statePtr.ToInt64() + (int)m_StateBlock.byteOffset);
|
||||
return *(int*)valuePtr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,54 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
////TODO: add ability to get and to set configuration on a control (probably just key/value pairs)
|
||||
|
||||
////TODO: remove the distinction between input and output controls; allow every InputControl to write values
|
||||
////FIXME: doxygen can't handle two classes 'Foo' and 'Foo<T>'; Foo won't show any of its members and Foo<T> won't get any docs at all
|
||||
|
||||
namespace ISX
|
||||
{
|
||||
using Configuration = KeyValuePair<InternedString, PrimitiveValue>;
|
||||
|
||||
// A typed and named value.
|
||||
// Actual value is stored in central state storage managed by InputSystem.
|
||||
// Controls form hierarchies and can be looked with paths.
|
||||
// Can have usages that give meaning to the control.
|
||||
/// <summary>
|
||||
/// A typed and named value in a hierarchy of controls.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Controls do not actually store values. Instead, every control receives an InputStateBlock
|
||||
/// which, after the control's device has been added to the system, is used to read out values
|
||||
/// from the device's backing store.
|
||||
///
|
||||
/// Controls can have children which in turn may have children. At the root of the child
|
||||
/// hierarchy is always an InputDevice (which themselves are InputControls).
|
||||
///
|
||||
/// Controls can be looked up by their path (see <see cref="InputControlSetup.GetControl"/> and
|
||||
/// <see cref="InputControlPath.FindControl"/>).
|
||||
///
|
||||
/// Each control must have a unique name within its parent (see <see cref="name"/>). Multiple
|
||||
/// names can be assigned to controls using aliases (see <see cref="aliases"/>). Name lookup
|
||||
/// is case-insensitive.
|
||||
///
|
||||
/// In addition to names, a control may have usages associated with it (see <see cref="usages"/>).
|
||||
/// A usage indicates how a control is meant to be used. For example, a button can be assigned
|
||||
/// the "PrimaryAction" usage to indicate it is the primary action button the device. Within a
|
||||
/// device, usages have to be unique. See CommonUsages for a list of standardized usages.
|
||||
/// </remarks>
|
||||
/// <seealso cref="InputDevice"/>
|
||||
/// \todo Add ability to get and to set configuration on a control (probably just key/value pairs)
|
||||
/// \todo Remove the distinction between input and output controls; allow every InputControl to write values
|
||||
public abstract class InputControl
|
||||
{
|
||||
// Final name part of the path.
|
||||
public string name => m_Name;
|
||||
/// <summary>
|
||||
/// The name of the control, i.e. the final name part in its path.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Names of controls must be unique within the context of their parent.
|
||||
///
|
||||
/// Lookup of names is case-insensitive.
|
||||
/// </remarks>
|
||||
/// <seealso cref="path"/>
|
||||
/// <seealso cref="aliases"/>
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
}
|
||||
|
||||
////TODO: include icon-related info from control template
|
||||
|
||||
|
@ -29,9 +61,9 @@ namespace ISX
|
|||
if (m_Path == null)
|
||||
{
|
||||
if (m_Parent != null)
|
||||
m_Path = $"{m_Parent.path}/{m_Name}";
|
||||
m_Path = string.Format("{0}/{1}", m_Parent.path, m_Name);
|
||||
else
|
||||
m_Path = $"/{m_Name}";
|
||||
m_Path = string.Format("/{0}", m_Name);
|
||||
}
|
||||
return m_Path;
|
||||
}
|
||||
|
@ -40,43 +72,70 @@ namespace ISX
|
|||
// Template the control is based on.
|
||||
// We store the name rather than reference the InputTemplate as we want
|
||||
// to avoid allocating those objects except where necessary.
|
||||
public string template => m_Template;
|
||||
public string template
|
||||
{
|
||||
get { return m_Template; }
|
||||
}
|
||||
|
||||
// Variant of the template or "default".
|
||||
// Example: "Lefty" when using the "Lefty" gamepad layout.
|
||||
public string variant => m_Variant;
|
||||
public string variant
|
||||
{
|
||||
get { return m_Variant; }
|
||||
}
|
||||
|
||||
////TODO: setting value (will it also go through the processor stack?)
|
||||
|
||||
// Current value as boxed object.
|
||||
// NOTE: Calling this will cause garbage.
|
||||
public virtual object valueAsObject => null;
|
||||
public virtual object valueAsObject
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
// Root of the control hierarchy.
|
||||
public InputDevice device => m_Device;
|
||||
public InputDevice device
|
||||
{
|
||||
get { return m_Device; }
|
||||
}
|
||||
|
||||
// Immediate parent.
|
||||
public InputControl parent => m_Parent;
|
||||
public InputControl parent
|
||||
{
|
||||
get { return m_Parent; }
|
||||
}
|
||||
|
||||
// Immediate children.
|
||||
public ReadOnlyArray<InputControl> children => m_ChildrenReadOnly;
|
||||
public ReadOnlyArray<InputControl> children
|
||||
{
|
||||
get { return m_ChildrenReadOnly; }
|
||||
}
|
||||
|
||||
// List of uses for this control. Gives meaning to the control such that you can, for example,
|
||||
// find a button on a device to use as the "back" button regardless of what it is named. The "back"
|
||||
// button is also an example of why there are multiple possible usages of a button as a use may
|
||||
// be context-dependent; if "back" does not make sense in a context, another use may make sense for
|
||||
// the very same button.
|
||||
public ReadOnlyArray<InternedString> usages => m_UsagesReadOnly;
|
||||
public ReadOnlyArray<InternedString> usages
|
||||
{
|
||||
get { return m_UsagesReadOnly; }
|
||||
}
|
||||
|
||||
// List of alternate names for the control.
|
||||
public ReadOnlyArray<InternedString> aliases => m_AliasesReadOnly;
|
||||
public ReadOnlyArray<InternedString> aliases
|
||||
{
|
||||
get { return m_AliasesReadOnly; }
|
||||
}
|
||||
|
||||
// Information about where the control stores its state.
|
||||
public InputStateBlock stateBlock => m_StateBlock;
|
||||
public InputStateBlock stateBlock
|
||||
{
|
||||
get { return m_StateBlock; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{template}:{path}";
|
||||
return string.Format("{0}:{1}", template, path);
|
||||
}
|
||||
|
||||
public TValue GetValue<TValue>()
|
||||
|
@ -84,7 +143,8 @@ namespace ISX
|
|||
var controlOfType = this as InputControl<TValue>;
|
||||
if (controlOfType == null)
|
||||
throw new InvalidCastException(
|
||||
$"Cannot query value of type '{typeof(TValue).Name}' from control of type '{this.GetType().Name}");
|
||||
string.Format("Cannot query value of type '{0}' from control of type '{1}", typeof(TValue).Name,
|
||||
this.GetType().Name));
|
||||
return controlOfType.value;
|
||||
}
|
||||
|
||||
|
@ -123,10 +183,15 @@ namespace ISX
|
|||
|
||||
protected internal InputStateBlock m_StateBlock;
|
||||
|
||||
protected internal IntPtr currentStatePtr =>
|
||||
InputStateBuffers.GetFrontBuffer(ResolveDeviceIndex());
|
||||
protected internal IntPtr previousStatePtr =>
|
||||
InputStateBuffers.GetBackBuffer(ResolveDeviceIndex());
|
||||
protected internal IntPtr currentStatePtr
|
||||
{
|
||||
get { return InputStateBuffers.GetFrontBuffer(ResolveDeviceIndex()); }
|
||||
}
|
||||
|
||||
protected internal IntPtr previousStatePtr
|
||||
{
|
||||
get { return InputStateBuffers.GetBackBuffer(ResolveDeviceIndex()); }
|
||||
}
|
||||
|
||||
// This data is initialized by InputControlSetup.
|
||||
internal InternedString m_Name;
|
||||
|
@ -153,7 +218,7 @@ namespace ISX
|
|||
{
|
||||
if (this is InputDevice)
|
||||
return path;
|
||||
return $"{this.path}/{path}";
|
||||
return string.Format("{0}/{1}", this.path, path);
|
||||
}
|
||||
|
||||
internal void BakeOffsetIntoStateBlockRecursive(uint offset)
|
||||
|
@ -172,7 +237,7 @@ namespace ISX
|
|||
internal unsafe bool CheckStateIsAllZeros(IntPtr valuePtr = new IntPtr())
|
||||
{
|
||||
if (valuePtr == IntPtr.Zero)
|
||||
valuePtr = currentStatePtr + (int)m_StateBlock.byteOffset;
|
||||
valuePtr = new IntPtr(currentStatePtr.ToInt64() + (int)m_StateBlock.byteOffset);
|
||||
|
||||
// Bitfield value.
|
||||
if (m_StateBlock.sizeInBits % 8 != 0 || m_StateBlock.bitOffset != 0)
|
||||
|
@ -197,7 +262,8 @@ namespace ISX
|
|||
{
|
||||
var deviceIndex = m_Device.m_DeviceIndex;
|
||||
if (deviceIndex == InputDevice.kInvalidDeviceIndex)
|
||||
throw new InvalidOperationException($"Cannot query value of control '{path}' before '{device.name}' has been added to system!");
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Cannot query value of control '{0}' before '{1}' has been added to system!", path, device.name));
|
||||
return deviceIndex;
|
||||
}
|
||||
|
||||
|
@ -210,10 +276,20 @@ namespace ISX
|
|||
// Adds processing stack.
|
||||
public abstract class InputControl<TValue> : InputControl
|
||||
{
|
||||
public TValue value => ReadValueFrom(currentStatePtr);
|
||||
public TValue previous => ReadValueFrom(previousStatePtr);
|
||||
public TValue value
|
||||
{
|
||||
get { return ReadValueFrom(currentStatePtr); }
|
||||
}
|
||||
|
||||
public override object valueAsObject => value;
|
||||
public TValue previous
|
||||
{
|
||||
get { return ReadValueFrom(previousStatePtr); }
|
||||
}
|
||||
|
||||
public override object valueAsObject
|
||||
{
|
||||
get { return value; }
|
||||
}
|
||||
|
||||
// Read a control value directly from a state event.
|
||||
//
|
||||
|
@ -223,9 +299,9 @@ namespace ISX
|
|||
public unsafe TValue ReadValueFrom(InputEventPtr inputEvent, bool process = true)
|
||||
{
|
||||
if (!inputEvent.valid)
|
||||
throw new ArgumentNullException(nameof(inputEvent));
|
||||
throw new ArgumentNullException("inputEvent");
|
||||
if (!inputEvent.IsA<StateEvent>() && !inputEvent.IsA<DeltaStateEvent>())
|
||||
throw new ArgumentException("Event must be a state or delta state event", nameof(inputEvent));
|
||||
throw new ArgumentException("Event must be a state or delta state event", "inputEvent");
|
||||
|
||||
////TODO: support delta events
|
||||
if (inputEvent.IsA<DeltaStateEvent>())
|
||||
|
@ -240,7 +316,9 @@ namespace ISX
|
|||
var stateFormat = stateEvent->stateFormat;
|
||||
if (stateEvent->stateFormat != device.m_StateBlock.format)
|
||||
throw new InvalidOperationException(
|
||||
$"Cannot read control '{path}' from StateEvent with format {stateFormat}; device '{device}' expects format {device.m_StateBlock.format}");
|
||||
string.Format(
|
||||
"Cannot read control '{0}' from StateEvent with format {1}; device '{2}' expects format {3}",
|
||||
path, stateFormat, device, device.m_StateBlock.format));
|
||||
|
||||
// Once a device has been added, global state buffer offsets are baked into control hierarchies.
|
||||
// We need to unsubtract those offsets here.
|
||||
|
@ -249,9 +327,11 @@ namespace ISX
|
|||
var stateSizeInBytes = stateEvent->stateSizeInBytes;
|
||||
if (m_StateBlock.byteOffset - deviceStateOffset + m_StateBlock.alignedSizeInBytes > stateSizeInBytes)
|
||||
throw new Exception(
|
||||
$"StateEvent with format {stateFormat} and size {stateSizeInBytes} bytes provides less data than expected by control {path}");
|
||||
string.Format(
|
||||
"StateEvent with format {0} and size {1} bytes provides less data than expected by control {2}",
|
||||
stateFormat, stateSizeInBytes, path));
|
||||
|
||||
var statePtr = stateEvent->state - (int)deviceStateOffset;
|
||||
var statePtr = new IntPtr(stateEvent->state.ToInt64() - (int)deviceStateOffset);
|
||||
var value = ReadRawValueFrom(statePtr);
|
||||
|
||||
if (process)
|
||||
|
@ -306,10 +386,14 @@ namespace ISX
|
|||
{
|
||||
var processorOfType = processor as IInputProcessor<TValue>;
|
||||
if (processorOfType == null)
|
||||
throw new Exception($"Cannot add processor of type '{processor.GetType().Name}' to control of type '{GetType().Name}'");
|
||||
throw new Exception(string.Format("Cannot add processor of type '{0}' to control of type '{1}'",
|
||||
processor.GetType().Name, GetType().Name));
|
||||
m_ProcessorStack.Append(processorOfType);
|
||||
}
|
||||
|
||||
internal IInputProcessor<TValue>[] processors => m_ProcessorStack.ToArray();
|
||||
internal IInputProcessor<TValue>[] processors
|
||||
{
|
||||
get { return m_ProcessorStack.ToArray(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace ISX
|
|||
public static string TryGetDeviceTemplate(string path)
|
||||
{
|
||||
if (path == null)
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
throw new ArgumentNullException("path");
|
||||
|
||||
var parser = new PathParser(path);
|
||||
if (!parser.MoveToNextComponent())
|
||||
|
@ -69,7 +69,7 @@ namespace ISX
|
|||
public static string TryGetControlTemplate(string path)
|
||||
{
|
||||
if (path == null)
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
throw new ArgumentNullException("path");
|
||||
var pathLength = path.Length;
|
||||
|
||||
var indexOfLastSlash = path.LastIndexOf('/');
|
||||
|
@ -261,9 +261,9 @@ namespace ISX
|
|||
public static InputControl FindControl(InputControl control, string path, int indexInPath = 0)
|
||||
{
|
||||
if (control == null)
|
||||
throw new ArgumentNullException(nameof(control));
|
||||
throw new ArgumentNullException("control");
|
||||
if (path == null)
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
throw new ArgumentNullException("path");
|
||||
|
||||
if (indexInPath == 0 && path[0] == '/')
|
||||
++indexInPath;
|
||||
|
@ -285,9 +285,9 @@ namespace ISX
|
|||
List<InputControl> matches)
|
||||
{
|
||||
if (control == null)
|
||||
throw new ArgumentNullException(nameof(control));
|
||||
throw new ArgumentNullException("control");
|
||||
if (path == null)
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
throw new ArgumentNullException("path");
|
||||
|
||||
if (indexInPath == 0 && path[0] == '/')
|
||||
++indexInPath;
|
||||
|
@ -432,7 +432,7 @@ namespace ISX
|
|||
Debug.Assert(path[indexInPath] == '{');
|
||||
++indexInPath;
|
||||
if (indexInPath == pathLength)
|
||||
throw new Exception($"Invalid path spec '{path}'; trailing '{{'");
|
||||
throw new Exception(string.Format("Invalid path spec '{0}'; trailing '{{'", path));
|
||||
|
||||
InputControl lastMatch = null;
|
||||
|
||||
|
@ -617,8 +617,15 @@ namespace ISX
|
|||
public Substring usage;
|
||||
public Substring name;
|
||||
|
||||
public bool isWildcard => name == kWildcard;
|
||||
public bool isDoubleWildcard => name == kDoubleWildcard;
|
||||
public bool isWildcard
|
||||
{
|
||||
get { return name == kWildcard; }
|
||||
}
|
||||
|
||||
public bool isDoubleWildcard
|
||||
{
|
||||
get { return name == kDoubleWildcard; }
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Must not allocate!
|
||||
|
@ -630,7 +637,10 @@ namespace ISX
|
|||
public int rightIndexInPath; // Points either to a '/' character or one past the end of the path string.
|
||||
public ParsedPathComponent current;
|
||||
|
||||
public bool isAtEnd => rightIndexInPath == length;
|
||||
public bool isAtEnd
|
||||
{
|
||||
get { return rightIndexInPath == length; }
|
||||
}
|
||||
|
||||
public PathParser(string path)
|
||||
{
|
||||
|
|
|
@ -41,7 +41,8 @@ namespace ISX
|
|||
{
|
||||
if (existingDevice != null && existingDevice.m_DeviceIndex != InputDevice.kInvalidDeviceIndex)
|
||||
throw new InvalidOperationException(
|
||||
$"Cannot modify control setup of existing device {existingDevice} while added to system.");
|
||||
string.Format("Cannot modify control setup of existing device {0} while added to system.",
|
||||
existingDevice));
|
||||
|
||||
if (variant.IsEmpty())
|
||||
variant = new InternedString("Default");
|
||||
|
@ -68,7 +69,7 @@ namespace ISX
|
|||
public InputControl TryGetControl(InputControl parent, string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
throw new ArgumentException(nameof(path));
|
||||
throw new ArgumentException("path");
|
||||
|
||||
if (m_Device == null)
|
||||
return null;
|
||||
|
@ -86,7 +87,7 @@ namespace ISX
|
|||
}
|
||||
|
||||
if (ReferenceEquals(parent, m_Device))
|
||||
return InputControlPath.FindControl(m_Device, $"{m_Device.name}/{path}");
|
||||
return InputControlPath.FindControl(m_Device, string.Format("{0}/{1}", m_Device.name, path));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -102,7 +103,9 @@ namespace ISX
|
|||
|
||||
var controlOfType = control as TControl;
|
||||
if (controlOfType == null)
|
||||
throw new Exception($"Expected control '{path}' to be of type '{typeof(TControl).Name}' but is of type '{control.GetType().Name}' instead!");
|
||||
throw new Exception(string.Format(
|
||||
"Expected control '{0}' to be of type '{1}' but is of type '{2}' instead!", path,
|
||||
typeof(TControl).Name, control.GetType().Name));
|
||||
|
||||
return controlOfType;
|
||||
}
|
||||
|
@ -113,7 +116,7 @@ namespace ISX
|
|||
{
|
||||
var control = TryGetControl(parent, path);
|
||||
if (control == null)
|
||||
throw new Exception($"Cannot find input control '{parent.MakeChildPath(path)}'");
|
||||
throw new Exception(string.Format("Cannot find input control '{0}'", parent.MakeChildPath(path)));
|
||||
return control;
|
||||
}
|
||||
|
||||
|
@ -124,7 +127,9 @@ namespace ISX
|
|||
|
||||
var controlOfType = control as TControl;
|
||||
if (controlOfType == null)
|
||||
throw new Exception($"Expected control '{path}' to be of type '{typeof(TControl).Name}' but is of type '{control.GetType().Name}' instead!");
|
||||
throw new Exception(string.Format(
|
||||
"Expected control '{0}' to be of type '{1}' but is of type '{2}' instead!", path,
|
||||
typeof(TControl).Name, control.GetType().Name));
|
||||
|
||||
return controlOfType;
|
||||
}
|
||||
|
@ -133,7 +138,7 @@ namespace ISX
|
|||
{
|
||||
var control = TryGetControl(path);
|
||||
if (control == null)
|
||||
throw new Exception($"Cannot find input control '{path}'");
|
||||
throw new Exception(string.Format("Cannot find input control '{0}'", path));
|
||||
return control;
|
||||
}
|
||||
|
||||
|
@ -147,7 +152,7 @@ namespace ISX
|
|||
{
|
||||
var control = TryGetControl<TControl>(path);
|
||||
if (control == null)
|
||||
throw new Exception($"Cannot find input control '{path}'");
|
||||
throw new Exception(string.Format("Cannot find input control '{0}'", path));
|
||||
return control;
|
||||
}
|
||||
|
||||
|
@ -160,7 +165,9 @@ namespace ISX
|
|||
|
||||
var controlOfType = control as TControl;
|
||||
if (controlOfType == null)
|
||||
throw new Exception($"Expected control '{path}' to be of type '{typeof(TControl).Name}' but is of type '{control.GetType().Name}' instead!");
|
||||
throw new Exception(string.Format(
|
||||
"Expected control '{0}' to be of type '{1}' but is of type '{2}' instead!", path,
|
||||
typeof(TControl).Name, control.GetType().Name));
|
||||
|
||||
return controlOfType;
|
||||
}
|
||||
|
@ -205,7 +212,8 @@ namespace ISX
|
|||
control = controlObject as InputControl;
|
||||
if (control == null)
|
||||
{
|
||||
throw new Exception($"Type '{template.type.Name}' referenced by template '{template.name}' is not an InputControl");
|
||||
throw new Exception(string.Format("Type '{0}' referenced by template '{1}' is not an InputControl",
|
||||
template.type.Name, template.name));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,7 +223,9 @@ namespace ISX
|
|||
if (controlAsDevice != null)
|
||||
{
|
||||
if (parent != null)
|
||||
throw new Exception($"Cannot instantiate device template '{template.name}' as child of '{parent.path}'; devices must be added at root");
|
||||
throw new Exception(string.Format(
|
||||
"Cannot instantiate device template '{0}' as child of '{1}'; devices must be added at root",
|
||||
template.name, parent.path));
|
||||
|
||||
m_Device = controlAsDevice;
|
||||
m_Device.m_StateBlock.byteOffset = 0;
|
||||
|
@ -257,7 +267,9 @@ namespace ISX
|
|||
// Someone did "new InputControlSetup(...)" with a control template.
|
||||
// We don't support creating control hierarchies without a device at the root.
|
||||
throw new InvalidOperationException(
|
||||
$"Toplevel template used with InputControlSetup must be a device template; '{template.name}' is a control template");
|
||||
string.Format(
|
||||
"Toplevel template used with InputControlSetup must be a device template; '{0}' is a control template",
|
||||
template.name));
|
||||
}
|
||||
|
||||
// Set common properties.
|
||||
|
@ -279,7 +291,8 @@ namespace ISX
|
|||
// actually reuse the existing control (and thus control.m_ChildrenReadOnly will
|
||||
// now be blank) but still want crawling down the hierarchy to preserve existing
|
||||
// controls where possible.
|
||||
AddChildControls(template, variant, control, existingControl?.m_ChildrenReadOnly,
|
||||
AddChildControls(template, variant, control,
|
||||
existingControl != null ? existingControl.m_ChildrenReadOnly : (ReadOnlyArray<InputControl>?)null,
|
||||
ref haveChildrenUsingStateFromOtherControl);
|
||||
}
|
||||
catch
|
||||
|
@ -307,7 +320,9 @@ namespace ISX
|
|||
var referencedControl = TryGetControl(control, controlTemplate.useStateFrom);
|
||||
if (referencedControl == null)
|
||||
throw new Exception(
|
||||
$"Cannot find control '{controlTemplate.useStateFrom}' referenced in 'useStateFrom' of control '{controlTemplate.name}' in template '{template.name}'");
|
||||
string.Format(
|
||||
"Cannot find control '{0}' referenced in 'useStateFrom' of control '{1}' in template '{2}'",
|
||||
controlTemplate.useStateFrom, controlTemplate.name, template.name));
|
||||
|
||||
// Copy its state settings.
|
||||
child.m_StateBlock = referencedControl.m_StateBlock;
|
||||
|
@ -375,7 +390,8 @@ namespace ISX
|
|||
|
||||
////REVIEW: can we check this in InputTemplate instead?
|
||||
if (string.IsNullOrEmpty(controlTemplate.template))
|
||||
throw new Exception($"Template has not been set on control '{controlTemplate.name}' in '{template.name}'");
|
||||
throw new Exception(string.Format("Template has not been set on control '{0}' in '{1}'",
|
||||
controlTemplate.name, template.name));
|
||||
|
||||
// See if we have an existing control that we might be able to re-use.
|
||||
InputControl existingControl = null;
|
||||
|
@ -401,7 +417,8 @@ namespace ISX
|
|||
{
|
||||
// Throw better exception that gives more info.
|
||||
throw new Exception(
|
||||
$"Cannot find template '{exception.template}' used in control '{controlTemplate.name}' of template '{template.name}'",
|
||||
string.Format("Cannot find template '{0}' used in control '{1}' of template '{2}'",
|
||||
exception.template, controlTemplate.name, template.name),
|
||||
exception);
|
||||
}
|
||||
|
||||
|
@ -483,7 +500,8 @@ namespace ISX
|
|||
var child = TryGetControl(parent, controlTemplate.name);
|
||||
if (child == null)
|
||||
throw new Exception(
|
||||
$"Cannot find control '{controlTemplate.name}' in template '{template.name}'");
|
||||
string.Format("Cannot find control '{0}' in template '{1}'", controlTemplate.name,
|
||||
template.name));
|
||||
|
||||
// Controls layout themselves as we come back up the hierarchy. However, when we
|
||||
// apply layout modifications reaching *into* the hierarchy, we need to retrigger
|
||||
|
@ -541,7 +559,8 @@ namespace ISX
|
|||
var type = InputProcessor.TryGet(name);
|
||||
if (type == null)
|
||||
throw new Exception(
|
||||
$"Cannot find processor '{name}' referenced by control '{controlTemplate.name}' in template '{templateName}'");
|
||||
string.Format("Cannot find processor '{0}' referenced by control '{1}' in template '{2}'", name,
|
||||
controlTemplate.name, templateName));
|
||||
|
||||
var processor = Activator.CreateInstance(type);
|
||||
|
||||
|
@ -562,7 +581,8 @@ namespace ISX
|
|||
|
||||
var field = objectType.GetField(parameter.name);
|
||||
if (field == null)
|
||||
throw new Exception($"Cannot find public field {parameter.name} in {objectType.Name} (referenced by parameter)");
|
||||
throw new Exception(string.Format("Cannot find public field {0} in {1} (referenced by parameter)",
|
||||
parameter.name, objectType.Name));
|
||||
|
||||
////REVIEW: can we do this without boxing?
|
||||
|
||||
|
@ -621,7 +641,9 @@ namespace ISX
|
|||
if (control.m_StateBlock.sizeInBits == 0 && children.Count == 0)
|
||||
{
|
||||
throw new Exception(
|
||||
$"Control '{control.path}' with template '{control.template}' has no size set but has no children to compute size from");
|
||||
string.Format(
|
||||
"Control '{0}' with template '{1}' has no size set but has no children to compute size from",
|
||||
control.path, control.template));
|
||||
}
|
||||
|
||||
// If there's no children, our job is done.
|
||||
|
@ -642,7 +664,8 @@ namespace ISX
|
|||
// Make sure the child has a valid size set on it.
|
||||
var childSizeInBits = child.m_StateBlock.sizeInBits;
|
||||
if (childSizeInBits == 0)
|
||||
throw new Exception($"Child '{child.name}' of '{control.name}' has no size set!");
|
||||
throw new Exception(
|
||||
string.Format("Child '{0}' of '{1}' has no size set!", child.name, control.name));
|
||||
|
||||
// Skip children that don't have fixed offsets.
|
||||
if (child.m_StateBlock.byteOffset == InputStateBlock.kInvalidOffset)
|
||||
|
|
|
@ -5,6 +5,10 @@ using System.Reflection;
|
|||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
#if !NET_4_0
|
||||
using ISX.Net35Compatibility;
|
||||
#endif
|
||||
|
||||
////TODO: make it so that a control with no variant set can act as the base template for controls with the same name that have a variant set
|
||||
|
||||
////TODO: ensure that if a template sets a device description, it is indeed a device template
|
||||
|
@ -13,23 +17,29 @@ using UnityEngine;
|
|||
|
||||
namespace ISX
|
||||
{
|
||||
// A template lays out the composition of an input control.
|
||||
//
|
||||
// Can be created in two ways:
|
||||
//
|
||||
// 1) Loaded from JSON.
|
||||
// 2) Constructed through reflection from InputControls classes.
|
||||
//
|
||||
// Once constructed, templates are immutable (but you can always
|
||||
// replace a registered template in the system and it will affect
|
||||
// everything constructed from the template).
|
||||
//
|
||||
// Templates can be for arbitrary control rigs or for entire
|
||||
// devices. Device templates can use the 'deviceDescriptor' field
|
||||
// to specify regexs that are to match against compatible devices.
|
||||
//
|
||||
// InputTemplate objects are considered temporaries. Except in the
|
||||
// editor, we don't keep them around beyond device creation.
|
||||
/// <summary>
|
||||
/// A template lays out the composition of an input control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Templates can be created in three ways:
|
||||
///
|
||||
/// <list type="number">
|
||||
/// <item><description>Loaded from JSON.</description></item>
|
||||
/// <item><description>Constructed through reflection from InputControls classes.</description></item>
|
||||
/// <item><description>Through template constructors using InputTemplate.Builder.</description></item>
|
||||
/// </list>
|
||||
///
|
||||
/// Once constructed, templates are immutable (but you can always
|
||||
/// replace a registered template in the system and it will affect
|
||||
/// everything constructed from the template).
|
||||
///
|
||||
/// Templates can be for arbitrary control rigs or for entire
|
||||
/// devices. Device templates can use the 'deviceDescriptor' field
|
||||
/// to specify regexs that are to match against compatible devices.
|
||||
///
|
||||
/// InputTemplate objects are considered temporaries. Except in the
|
||||
/// editor, we don't keep them around beyond device creation.
|
||||
/// </remarks>
|
||||
public class InputTemplate
|
||||
{
|
||||
// String that is used to separate names from namespaces in template names.
|
||||
|
@ -77,13 +87,13 @@ namespace ISX
|
|||
case ParameterType.Boolean:
|
||||
if (*((bool*)ptr))
|
||||
return name;
|
||||
return $"{name}=false";
|
||||
return string.Format("{0}=false", name);
|
||||
case ParameterType.Integer:
|
||||
var intValue = *((int*)ptr);
|
||||
return $"{name}={intValue}";
|
||||
return string.Format("{0}={1}", name, intValue);
|
||||
case ParameterType.Float:
|
||||
var floatValue = *((float*)ptr);
|
||||
return $"{name}={floatValue}";
|
||||
return string.Format("{0}={1}", name, floatValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,8 +110,8 @@ namespace ISX
|
|||
{
|
||||
if (parameters.Count == 0)
|
||||
return name;
|
||||
var parameterString = string.Join(",", parameters.Select(x => x.ToString()));
|
||||
return $"name({parameterString})";
|
||||
var parameterString = string.Join(",", parameters.Select(x => x.ToString()).ToArray());
|
||||
return string.Format("name({0})", parameterString);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,26 +174,54 @@ namespace ISX
|
|||
|
||||
// Unique name of the template.
|
||||
// NOTE: Case-insensitive.
|
||||
public InternedString name => m_Name;
|
||||
public InternedString name
|
||||
{
|
||||
get { return m_Name; }
|
||||
}
|
||||
|
||||
public Type type => m_Type;
|
||||
public Type type
|
||||
{
|
||||
get { return m_Type; }
|
||||
}
|
||||
|
||||
public FourCC stateFormat => m_StateFormat;
|
||||
public FourCC stateFormat
|
||||
{
|
||||
get { return m_StateFormat; }
|
||||
}
|
||||
|
||||
public string extendsTemplate => m_ExtendsTemplate;
|
||||
public string extendsTemplate
|
||||
{
|
||||
get { return m_ExtendsTemplate; }
|
||||
}
|
||||
|
||||
// Unlike in a normal device descriptor, the strings in this descriptor are
|
||||
// regular expressions which can be used to match against the strings of an
|
||||
// actual device descriptor.
|
||||
public InputDeviceDescription deviceDescription => m_DeviceDescription;
|
||||
public InputDeviceDescription deviceDescription
|
||||
{
|
||||
get { return m_DeviceDescription; }
|
||||
}
|
||||
|
||||
public ReadOnlyArray<ControlTemplate> controls => new ReadOnlyArray<ControlTemplate>(m_Controls);
|
||||
public ReadOnlyArray<ControlTemplate> controls
|
||||
{
|
||||
get { return new ReadOnlyArray<ControlTemplate>(m_Controls); }
|
||||
}
|
||||
|
||||
public bool isDeviceTemplate => typeof(InputDevice).IsAssignableFrom(m_Type);
|
||||
public bool isControlTemplate => !isDeviceTemplate;
|
||||
public bool isDeviceTemplate
|
||||
{
|
||||
get { return typeof(InputDevice).IsAssignableFrom(m_Type); }
|
||||
}
|
||||
|
||||
// Build a template programmatically. Primarily for use by template constructors
|
||||
// registered with the system.
|
||||
public bool isControlTemplate
|
||||
{
|
||||
get { return !isDeviceTemplate; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a template programmatically. Primarily for use by template constructors
|
||||
/// registered with the system.
|
||||
/// </summary>
|
||||
/// <seealso cref="InputSystem.RegisterTemplateConstructor"/>
|
||||
public struct Builder
|
||||
{
|
||||
public string name;
|
||||
|
@ -293,7 +331,7 @@ namespace ISX
|
|||
var format = new FourCC();
|
||||
if (typeof(InputDevice).IsAssignableFrom(type))
|
||||
{
|
||||
var stateAttribute = type.GetCustomAttribute<InputStateAttribute>();
|
||||
var stateAttribute = type.GetCustomAttribute<InputStateAttribute>(true);
|
||||
if (stateAttribute != null)
|
||||
{
|
||||
isDeviceWithStateAttribute = true;
|
||||
|
@ -420,7 +458,7 @@ namespace ISX
|
|||
|
||||
// Look for InputControlAttributes. If they aren't there, the member has to be
|
||||
// of an InputControl-derived value type.
|
||||
var attributes = member.GetCustomAttributes<InputControlAttribute>().ToArray();
|
||||
var attributes = member.GetCustomAttributes<InputControlAttribute>(false).ToArray();
|
||||
if (attributes.Length == 0)
|
||||
{
|
||||
if (valueType == null || !typeof(InputControl).IsAssignableFrom(valueType))
|
||||
|
@ -462,14 +500,14 @@ namespace ISX
|
|||
////REVIEW: make sure that the value type of the field and the value type of the control match?
|
||||
|
||||
// Determine name.
|
||||
var name = attribute?.name;
|
||||
var name = attribute != null ? attribute.name : null;
|
||||
if (string.IsNullOrEmpty(name))
|
||||
name = member.Name;
|
||||
|
||||
var isModifyingChildControlByPath = name.IndexOf('/') != -1;
|
||||
|
||||
// Determine template.
|
||||
var template = attribute?.template;
|
||||
var template = attribute != null ? attribute.template : null;
|
||||
if (string.IsNullOrEmpty(template) && !isModifyingChildControlByPath)
|
||||
{
|
||||
var valueType = TypeHelpers.GetValueType(member);
|
||||
|
@ -478,7 +516,7 @@ namespace ISX
|
|||
|
||||
// Determine variant.
|
||||
string variant = null;
|
||||
if (!string.IsNullOrEmpty(attribute?.variant))
|
||||
if (attribute != null && !string.IsNullOrEmpty(attribute.variant))
|
||||
variant = attribute.variant;
|
||||
|
||||
// Determine offset.
|
||||
|
@ -501,7 +539,7 @@ namespace ISX
|
|||
|
||||
// Determine format.
|
||||
var format = new FourCC();
|
||||
if (!string.IsNullOrEmpty(attribute?.format))
|
||||
if (attribute != null && !string.IsNullOrEmpty(attribute.format))
|
||||
format = new FourCC(attribute.format);
|
||||
else if (!isModifyingChildControlByPath && bit == InputStateBlock.kInvalidOffset)
|
||||
{
|
||||
|
@ -513,37 +551,33 @@ namespace ISX
|
|||
InternedString[] aliases = null;
|
||||
if (attribute != null)
|
||||
{
|
||||
if (attribute.alias != null && attribute.aliases == null)
|
||||
aliases = new InternedString[1] { new InternedString(attribute.alias) };
|
||||
else if (attribute.aliases != null)
|
||||
aliases = ArrayHelpers.Join(attribute.alias, attribute.aliases)?.Select(x => new InternedString(x))
|
||||
.ToArray();
|
||||
var joined = ArrayHelpers.Join(attribute.alias, attribute.aliases);
|
||||
if (joined != null)
|
||||
aliases = joined.Select(x => new InternedString(x)).ToArray();
|
||||
}
|
||||
|
||||
// Determine usages.
|
||||
InternedString[] usages = null;
|
||||
if (attribute != null)
|
||||
{
|
||||
if (attribute.usage != null && attribute.usages == null)
|
||||
usages = new InternedString[1] { new InternedString(attribute.usage) };
|
||||
else if (attribute.usages != null)
|
||||
usages = ArrayHelpers.Join(attribute.usage, attribute.usages)?.Select(x => new InternedString(x))
|
||||
.ToArray();
|
||||
var joined = ArrayHelpers.Join(attribute.usage, attribute.usages);
|
||||
if (joined != null)
|
||||
usages = joined.Select(x => new InternedString(x)).ToArray();
|
||||
}
|
||||
|
||||
// Determine parameters.
|
||||
ParameterValue[] parameters = null;
|
||||
if (!string.IsNullOrEmpty(attribute?.parameters))
|
||||
if (attribute != null && !string.IsNullOrEmpty(attribute.parameters))
|
||||
parameters = ParseParameters(attribute.parameters);
|
||||
|
||||
// Determine processors.
|
||||
NameAndParameters[] processors = null;
|
||||
if (!string.IsNullOrEmpty(attribute?.processors))
|
||||
if (attribute != null && !string.IsNullOrEmpty(attribute.processors))
|
||||
processors = ParseNameAndParameterList(attribute.processors);
|
||||
|
||||
// Determine whether to use state from another control.
|
||||
string useStateFrom = null;
|
||||
if (!string.IsNullOrEmpty(attribute?.useStateFrom))
|
||||
if (attribute != null && !string.IsNullOrEmpty(attribute.useStateFrom))
|
||||
useStateFrom = attribute.useStateFrom;
|
||||
|
||||
// Determine whether state automatically resets.
|
||||
|
@ -597,7 +631,7 @@ namespace ISX
|
|||
++index;
|
||||
}
|
||||
if (index - nameStart == 0)
|
||||
throw new Exception($"Expecting name at position {nameStart} in '{text}'");
|
||||
throw new Exception(string.Format("Expecting name at position {0} in '{1}'", nameStart, text));
|
||||
var name = text.Substring(nameStart, index - nameStart);
|
||||
|
||||
// Skip whitespace.
|
||||
|
@ -611,7 +645,8 @@ namespace ISX
|
|||
++index;
|
||||
var closeParenIndex = text.IndexOf(')', index);
|
||||
if (closeParenIndex == -1)
|
||||
throw new Exception($"Expecting ')' after '(' at position {index} in '{text}'");
|
||||
throw new Exception(string.Format("Expecting ')' after '(' at position {0} in '{1}'", index,
|
||||
text));
|
||||
|
||||
var parameterString = text.Substring(index, closeParenIndex - index);
|
||||
parameters = ParseParameters(parameterString);
|
||||
|
@ -773,7 +808,7 @@ namespace ISX
|
|||
var isTargetingVariants = false;
|
||||
foreach (var variant in baseControlVariants)
|
||||
{
|
||||
var key = $"{pair.Key}@{variant}";
|
||||
var key = string.Format("{0}@{1}", pair.Key, variant);
|
||||
if (baseControlTable.TryGetValue(key, out baseControlTemplate))
|
||||
{
|
||||
var mergedTemplate = MergeControlTemplate(pair.Value, baseControlTemplate);
|
||||
|
@ -811,8 +846,9 @@ namespace ISX
|
|||
if (!controlTemplates[i].variant.IsEmpty())
|
||||
{
|
||||
var variant = controlTemplates[i].variant.ToLower();
|
||||
key = $"{key}@{variant}";
|
||||
variants?.Add(variant);
|
||||
key = string.Format("{0}@{1}", key, variant);
|
||||
if (variants != null)
|
||||
variants.Add(variant);
|
||||
}
|
||||
table[key] = controlTemplates[i];
|
||||
}
|
||||
|
@ -882,7 +918,7 @@ namespace ISX
|
|||
foreach (var existing in controlTemplates)
|
||||
if (string.Compare(name, existing.name, StringComparison.OrdinalIgnoreCase) == 0 &&
|
||||
existing.variant == controlTemplate.variant)
|
||||
throw new Exception($"Duplicate control '{name}' in template '{templateName}'");
|
||||
throw new Exception(string.Format("Duplicate control '{0}' in template '{1}'", name, templateName));
|
||||
}
|
||||
|
||||
internal static string ParseHeaderFromJson(string json, out InputDeviceDescription deviceDescription, out string baseTemplate)
|
||||
|
@ -937,12 +973,15 @@ namespace ISX
|
|||
type = Type.GetType(this.type, false);
|
||||
if (type == null)
|
||||
{
|
||||
Debug.Log($"Cannot find type '{this.type}' used by template '{name}'; falling back to using InputDevice");
|
||||
Debug.Log(string.Format(
|
||||
"Cannot find type '{0}' used by template '{1}'; falling back to using InputDevice",
|
||||
this.type, name));
|
||||
type = typeof(InputDevice);
|
||||
}
|
||||
else if (!typeof(InputControl).IsAssignableFrom(type))
|
||||
{
|
||||
throw new Exception($"'{this.type}' used by template '{name}' is not an InputControl");
|
||||
throw new Exception(string.Format("'{0}' used by template '{1}' is not an InputControl",
|
||||
this.type, name));
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrEmpty(extend))
|
||||
|
@ -965,7 +1004,7 @@ namespace ISX
|
|||
else if (beforeRenderLowerCase == "update")
|
||||
template.m_UpdateBeforeRender = true;
|
||||
else
|
||||
throw new Exception($"Invalid beforeRender setting '{beforeRender}'");
|
||||
throw new Exception(string.Format("Invalid beforeRender setting '{0}'", beforeRender));
|
||||
}
|
||||
|
||||
// Add overrides.
|
||||
|
@ -986,7 +1025,7 @@ namespace ISX
|
|||
foreach (var control in controls)
|
||||
{
|
||||
if (string.IsNullOrEmpty(control.name))
|
||||
throw new Exception($"Control with no name in template '{name}");
|
||||
throw new Exception(string.Format("Control with no name in template '{0}", name));
|
||||
var controlTemplate = control.ToTemplate();
|
||||
ThrowIfControlTemplateIsDuplicate(ref controlTemplate, controlTemplates, template.name);
|
||||
controlTemplates.Add(controlTemplate);
|
||||
|
@ -1125,8 +1164,8 @@ namespace ISX
|
|||
offset = template.offset,
|
||||
sizeInBits = template.sizeInBits,
|
||||
format = template.format.ToString(),
|
||||
parameters = string.Join(",", template.parameters.Select(x => x.ToString())),
|
||||
processors = string.Join(",", template.processors.Select(x => x.ToString())),
|
||||
parameters = string.Join(",", template.parameters.Select(x => x.ToString()).ToArray()),
|
||||
processors = string.Join(",", template.processors.Select(x => x.ToString()).ToArray()),
|
||||
usages = template.usages.Select(x => x.ToString()).ToArray(),
|
||||
aliases = template.aliases.Select(x => x.ToString()).ToArray()
|
||||
};
|
||||
|
@ -1198,13 +1237,13 @@ namespace ISX
|
|||
if (string.IsNullOrEmpty(part))
|
||||
return null;
|
||||
|
||||
return $"{part}";
|
||||
return part;
|
||||
}
|
||||
|
||||
if (regex[regex.Length - 1] != ')')
|
||||
return $"({regex})|({part}";
|
||||
return string.Format("({0})|({1}", regex, part);
|
||||
|
||||
return $"{regex}|({part})";
|
||||
return string.Format("{0}|({1})", regex, part);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1268,7 +1307,8 @@ namespace ISX
|
|||
////TODO: catch cycles
|
||||
var superTemplate = TryLoadTemplate(template.m_ExtendsTemplate, table);
|
||||
if (superTemplate == null)
|
||||
throw new TemplateNotFoundException($"Cannot find base template '{template.m_ExtendsTemplate}' of template '{name}'");
|
||||
throw new TemplateNotFoundException(string.Format(
|
||||
"Cannot find base template '{0}' of template '{1}'", template.m_ExtendsTemplate, name));
|
||||
template.MergeTemplate(superTemplate);
|
||||
}
|
||||
}
|
||||
|
@ -1326,7 +1366,7 @@ namespace ISX
|
|||
{
|
||||
public string template { get; private set; }
|
||||
public TemplateNotFoundException(string name)
|
||||
: base($"Cannot find template '{name}'")
|
||||
: base(string.Format("Cannot find template '{0}'", name))
|
||||
{
|
||||
template = name;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@ namespace ISX
|
|||
{
|
||||
public class KeyControl : ButtonControl
|
||||
{
|
||||
public int scanCode => 0;
|
||||
public int scanCode
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace ISX
|
|||
|
||||
protected override unsafe float ReadRawValueFrom(IntPtr statePtr)
|
||||
{
|
||||
var valuePtr = (float*)(statePtr + (int)m_StateBlock.byteOffset);
|
||||
var valuePtr = (float*)new IntPtr(statePtr.ToInt64() + (int)m_StateBlock.byteOffset);
|
||||
var x = valuePtr[0];
|
||||
var y = valuePtr[1];
|
||||
return new Vector2(x, y).magnitude;
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace ISX
|
|||
|
||||
protected override unsafe float ReadRawValueFrom(IntPtr statePtr)
|
||||
{
|
||||
var valuePtr = (float*)(statePtr + (int)m_StateBlock.byteOffset);
|
||||
var valuePtr = (float*)new IntPtr(statePtr.ToInt64() + (int)m_StateBlock.byteOffset);
|
||||
var x = valuePtr[0];
|
||||
var y = valuePtr[1];
|
||||
var z = valuePtr[2];
|
||||
|
|
|
@ -10,8 +10,15 @@ namespace ISX
|
|||
public float min;
|
||||
public float max;
|
||||
|
||||
public float minOrDefault => min == 0.0f ? InputConfiguration.DeadzoneMin : min;
|
||||
public float maxOrDefault => max == 0.0f ? InputConfiguration.DeadzoneMax : max;
|
||||
public float minOrDefault
|
||||
{
|
||||
get { return min == 0.0f ? InputConfiguration.DeadzoneMin : min; }
|
||||
}
|
||||
|
||||
public float maxOrDefault
|
||||
{
|
||||
get { return max == 0.0f ? InputConfiguration.DeadzoneMax : max; }
|
||||
}
|
||||
|
||||
public Vector2 Process(Vector2 vector)
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace ISX
|
|||
|
||||
protected override unsafe Quaternion ReadRawValueFrom(IntPtr statePtr)
|
||||
{
|
||||
var valuePtr = (float*)(statePtr + (int)m_StateBlock.byteOffset);
|
||||
var valuePtr = (float*)new IntPtr(statePtr.ToInt64() + (int)m_StateBlock.byteOffset);
|
||||
var x = valuePtr[0];
|
||||
var y = valuePtr[1];
|
||||
var z = valuePtr[2];
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace ISX
|
|||
|
||||
protected override unsafe Touch ReadRawValueFrom(IntPtr statePtr)
|
||||
{
|
||||
var valuePtr = (Touch*)(statePtr + (int)m_StateBlock.byteOffset);
|
||||
var valuePtr = (Touch*)new IntPtr(statePtr.ToInt64() + (int)m_StateBlock.byteOffset);
|
||||
return *valuePtr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
namespace ISX
|
||||
{
|
||||
// If no module manager has been set up, this one is taken as a fallback.
|
||||
// Scans for all input modules present in the code and initializes any
|
||||
// that is compatible with the current runtime platform.
|
||||
public class DefaultInputModuleManager : IInputModuleManager
|
||||
{
|
||||
public void Initialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7fd5d06ebb86414baed5cafa3aa761c6
|
||||
timeCreated: 1511228343
|
|
@ -17,7 +17,10 @@ namespace ISX
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct GamepadState : IInputStateTypeInfo
|
||||
{
|
||||
public static FourCC kFormat => new FourCC('G', 'P', 'A', 'D');
|
||||
public static FourCC kFormat
|
||||
{
|
||||
get { return new FourCC('G', 'P', 'A', 'D'); }
|
||||
}
|
||||
|
||||
////REVIEW: do we want the name to correspond to what's actually on the device?
|
||||
[InputControl(name = "dpad", template = "Dpad", usage = "Hatswitch")]
|
||||
|
@ -100,7 +103,10 @@ namespace ISX
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct GamepadOutputState : IInputStateTypeInfo
|
||||
{
|
||||
public static FourCC kFormat => new FourCC('M', 'O', 'T', 'R');
|
||||
public static FourCC kFormat
|
||||
{
|
||||
get { return new FourCC('M', 'O', 'T', 'R'); }
|
||||
}
|
||||
|
||||
[InputControl(name = "leftMotor", template = "Motor", usage = "LowFreqMotor")]
|
||||
public float leftMotor;
|
||||
|
|
|
@ -19,7 +19,10 @@ namespace ISX
|
|||
public const int kMaxDeviceId = 256;
|
||||
internal const int kInvalidDeviceIndex = -1;
|
||||
|
||||
public InputDeviceDescription description => m_Description;
|
||||
public InputDeviceDescription description
|
||||
{
|
||||
get { return m_Description; }
|
||||
}
|
||||
|
||||
////REVIEW: on Xbox, a device can have multiple player IDs assigned to it
|
||||
////TODO: this needs to become part of the device's configuration
|
||||
|
@ -27,28 +30,49 @@ namespace ISX
|
|||
// player inputs are usually numbered. For example, on a console the gamepads slots on the system
|
||||
// will be numbered and associated with gamepads. This number corresponds to the system assigned
|
||||
// player index for the device.
|
||||
public int playerId => m_PlayerId;
|
||||
public int playerId
|
||||
{
|
||||
get { return m_PlayerId; }
|
||||
}
|
||||
|
||||
// Whether the device is currently connected.
|
||||
// If you want to listen for state changes, hook into InputManager.onDeviceChange.
|
||||
public bool connected => (m_Flags & Flags.Connected) == Flags.Connected;
|
||||
public bool connected
|
||||
{
|
||||
get { return (m_Flags & Flags.Connected) == Flags.Connected; }
|
||||
}
|
||||
|
||||
// Whether the device is mirrored from a remote input system and not actually present
|
||||
// as a "real" device in the local system.
|
||||
public bool remote => (m_Flags & Flags.Remote) == Flags.Remote;
|
||||
public bool remote
|
||||
{
|
||||
get { return (m_Flags & Flags.Remote) == Flags.Remote; }
|
||||
}
|
||||
|
||||
////REVIEW: is this one really worth the code?
|
||||
// Whether the device comes from the native Unity runtime.
|
||||
public bool native => (m_Flags & Flags.Native) == Flags.Native;
|
||||
public bool native
|
||||
{
|
||||
get { return (m_Flags & Flags.Native) == Flags.Native; }
|
||||
}
|
||||
|
||||
public bool updateBeforeRender => (m_Flags & Flags.UpdateBeforeRender) == Flags.UpdateBeforeRender;
|
||||
public bool updateBeforeRender
|
||||
{
|
||||
get { return (m_Flags & Flags.UpdateBeforeRender) == Flags.UpdateBeforeRender; }
|
||||
}
|
||||
|
||||
// Every registered device in the system gets a unique numeric ID.
|
||||
// For native devices, this is assigned by the underlying runtime.
|
||||
public int id => m_Id;
|
||||
public int id
|
||||
{
|
||||
get { return m_Id; }
|
||||
}
|
||||
|
||||
// Timestamp of last state event used to update the device.
|
||||
public double lastUpdateTime => m_LastUpdateTime;
|
||||
public double lastUpdateTime
|
||||
{
|
||||
get { return m_LastUpdateTime; }
|
||||
}
|
||||
|
||||
// Make this the current device of its type.
|
||||
// Use this to set static properties that give fast access to the latest device used of a given
|
||||
|
@ -123,7 +147,7 @@ namespace ISX
|
|||
internal void SetUsage(InternedString usage)
|
||||
{
|
||||
// Make last entry in m_UsagesForEachControl be our device usage string.
|
||||
var numControlUsages = m_UsageToControl?.Length ?? 0;
|
||||
var numControlUsages = m_UsageToControl != null ? m_UsageToControl.Length : 0;
|
||||
Array.Resize(ref m_UsagesForEachControl, numControlUsages + 1);
|
||||
m_UsagesForEachControl[numControlUsages] = usage;
|
||||
m_UsagesReadOnly = new ReadOnlyArray<InternedString>(m_UsagesForEachControl, numControlUsages, 1);
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace ISX
|
|||
// input device-related assets in the project go into the build. The
|
||||
// imported asset corresponds to only the assets that get included
|
||||
// in the build for the current build target.
|
||||
public class InputDeviceDatabaseAsset : ScriptableObject, IInputModuleManager
|
||||
public class InputDeviceDatabaseAsset : ScriptableObject, IInputPlugin
|
||||
{
|
||||
public const string kExtension = "inputdevices";
|
||||
|
||||
|
|
|
@ -24,13 +24,19 @@ namespace ISX
|
|||
// Example: For HIDs, this will be the HID descriptor.
|
||||
public string capabilities;
|
||||
|
||||
public bool empty => string.IsNullOrEmpty(interfaceName) &&
|
||||
string.IsNullOrEmpty(deviceClass) &&
|
||||
string.IsNullOrEmpty(manufacturer) &&
|
||||
string.IsNullOrEmpty(product) &&
|
||||
string.IsNullOrEmpty(serial) &&
|
||||
string.IsNullOrEmpty(version) &&
|
||||
string.IsNullOrEmpty(capabilities);
|
||||
public bool empty
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.IsNullOrEmpty(interfaceName) &&
|
||||
string.IsNullOrEmpty(deviceClass) &&
|
||||
string.IsNullOrEmpty(manufacturer) &&
|
||||
string.IsNullOrEmpty(product) &&
|
||||
string.IsNullOrEmpty(serial) &&
|
||||
string.IsNullOrEmpty(version) &&
|
||||
string.IsNullOrEmpty(capabilities);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
|
@ -38,7 +44,7 @@ namespace ISX
|
|||
var haveManufacturer = !string.IsNullOrEmpty(manufacturer);
|
||||
|
||||
if (haveProduct && haveManufacturer)
|
||||
return $"{manufacturer} {product}";
|
||||
return string.Format("{0} {1}", manufacturer, product);
|
||||
if (haveProduct)
|
||||
return product;
|
||||
|
||||
|
|
|
@ -6,7 +6,10 @@ namespace ISX
|
|||
{
|
||||
public struct JoystickState : IInputStateTypeInfo
|
||||
{
|
||||
public static FourCC kFormat => new FourCC('J', 'O', 'Y');
|
||||
public static FourCC kFormat
|
||||
{
|
||||
get { return new FourCC('J', 'O', 'Y'); }
|
||||
}
|
||||
|
||||
[InputControl(name = "hat", template = "Dpad", usage = "Hatswitch")]
|
||||
[InputControl(name = "trigger", template = "Button", usages = new[] { "PrimaryTrigger", "PrimaryAction" }, bit = (int)Button.Trigger)]
|
||||
|
@ -47,8 +50,15 @@ namespace ISX
|
|||
|
||||
////REVIEW: are these really useful?
|
||||
// List of all buttons and axes on the joystick.
|
||||
public ReadOnlyArray<ButtonControl> buttons => new ReadOnlyArray<ButtonControl>(m_Buttons);
|
||||
public ReadOnlyArray<AxisControl> axes => new ReadOnlyArray<AxisControl>(m_Axes);
|
||||
public ReadOnlyArray<ButtonControl> buttons
|
||||
{
|
||||
get { return new ReadOnlyArray<ButtonControl>(m_Buttons); }
|
||||
}
|
||||
|
||||
public ReadOnlyArray<AxisControl> axes
|
||||
{
|
||||
get { return new ReadOnlyArray<AxisControl>(m_Axes); }
|
||||
}
|
||||
|
||||
public static Joystick current { get; internal set; }
|
||||
|
||||
|
|
|
@ -98,7 +98,11 @@ namespace ISX
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct KeyboardState : IInputStateTypeInfo
|
||||
{
|
||||
public static FourCC kFormat => new FourCC('K', 'E', 'Y', 'S');
|
||||
public static FourCC kFormat
|
||||
{
|
||||
get { return new FourCC('K', 'E', 'Y', 'S'); }
|
||||
}
|
||||
|
||||
public const int kSizeInBytes = ((int)Key.Count) / 8 + (((int)Key.Count) % 8 > 0 ? 1 : 0);
|
||||
public const int kSizeInBits = kSizeInBytes * 8;
|
||||
|
||||
|
|
|
@ -9,7 +9,10 @@ namespace ISX
|
|||
[StructLayout(LayoutKind.Explicit, Size = 28)]
|
||||
public struct MouseState : IInputStateTypeInfo
|
||||
{
|
||||
public static FourCC kFormat => new FourCC('M', 'O', 'U', 'S');
|
||||
public static FourCC kFormat
|
||||
{
|
||||
get { return new FourCC('M', 'O', 'U', 'S'); }
|
||||
}
|
||||
|
||||
[InputControl(usage = "Point")]
|
||||
[FieldOffset(0)]
|
||||
|
|
|
@ -15,7 +15,10 @@ namespace ISX
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PointerState : IInputStateTypeInfo
|
||||
{
|
||||
public static FourCC kFormat => new FourCC('P', 'T', 'R');
|
||||
public static FourCC kFormat
|
||||
{
|
||||
get { return new FourCC('P', 'T', 'R'); }
|
||||
}
|
||||
|
||||
[InputControl(template = "Digital")]
|
||||
public uint pointerId;
|
||||
|
|
|
@ -5,6 +5,10 @@ using System.Text;
|
|||
using UnityEngine;
|
||||
using UnityEngineInternal.Input;
|
||||
|
||||
#if !NET_4_0
|
||||
using ISX.Net35Compatibility;
|
||||
#endif
|
||||
|
||||
namespace ISX
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -74,7 +78,7 @@ namespace ISX
|
|||
internal InputRemoting(InputManager manager, bool startSendingOnConnect = false)
|
||||
{
|
||||
if (manager == null)
|
||||
throw new ArgumentNullException(nameof(manager));
|
||||
throw new ArgumentNullException("manager");
|
||||
|
||||
m_LocalManager = manager;
|
||||
|
||||
|
@ -159,7 +163,7 @@ namespace ISX
|
|||
public IDisposable Subscribe(IObserver<Message> observer)
|
||||
{
|
||||
if (observer == null)
|
||||
throw new ArgumentNullException(nameof(observer));
|
||||
throw new ArgumentNullException("observer");
|
||||
|
||||
var subscriber = new Subscriber {owner = this, observer = observer};
|
||||
ArrayHelpers.Append(ref m_Subscribers, subscriber);
|
||||
|
@ -298,7 +302,7 @@ namespace ISX
|
|||
var sender = new RemoteSender
|
||||
{
|
||||
senderId = senderId,
|
||||
templateNamespace = $"{kRemoteTemplateNamespacePrefix}{senderId}"
|
||||
templateNamespace = string.Format("{0}{1}", kRemoteTemplateNamespacePrefix, senderId)
|
||||
};
|
||||
return ArrayHelpers.Append(ref m_Senders, sender);
|
||||
}
|
||||
|
@ -423,7 +427,9 @@ namespace ISX
|
|||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.Log($"Could not load template '{templateName}'; not sending to remote listeners (exception: {exception})");
|
||||
Debug.Log(string.Format(
|
||||
"Could not load template '{0}'; not sending to remote listeners (exception: {1})", templateName,
|
||||
exception));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -510,16 +516,20 @@ namespace ISX
|
|||
var data = DeserializeData<Data>(msg.data);
|
||||
|
||||
// Create device.
|
||||
var template = $"{receiver.m_Senders[senderIndex].templateNamespace}::{data.template}";
|
||||
var template = string.Format("{0}::{1}", receiver.m_Senders[senderIndex].templateNamespace,
|
||||
data.template);
|
||||
InputDevice device;
|
||||
try
|
||||
{
|
||||
device = receiver.m_LocalManager.AddDevice(template, $"Remote{msg.participantId}::{data.name}");
|
||||
device = receiver.m_LocalManager.AddDevice(template,
|
||||
string.Format("Remote{0}::{1}", msg.participantId, data.name));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.Log(
|
||||
$"Could not create remote device '{data.description}' with template '{data.template}' locally (exception: {exception})");
|
||||
string.Format(
|
||||
"Could not create remote device '{0}' with template '{1}' locally (exception: {2})",
|
||||
data.description, data.template, exception));
|
||||
return;
|
||||
}
|
||||
device.m_Description = data.description;
|
||||
|
@ -577,7 +587,7 @@ namespace ISX
|
|||
|
||||
fixed(byte* dataPtr = msg.data)
|
||||
{
|
||||
var dataEndPtr = new IntPtr(dataPtr) + msg.data.Length;
|
||||
var dataEndPtr = new IntPtr(dataPtr + msg.data.Length);
|
||||
var eventCount = 0;
|
||||
var eventPtr = new InputEventPtr((InputEvent*)dataPtr);
|
||||
var senderIndex = receiver.FindOrCreateSenderRecord(msg.participantId);
|
||||
|
|
|
@ -2,6 +2,10 @@ using System;
|
|||
using UnityEngine;
|
||||
using UnityEngine.Networking.PlayerConnection;
|
||||
|
||||
#if !NET_4_0
|
||||
using ISX.Net35Compatibility;
|
||||
#endif
|
||||
|
||||
namespace ISX
|
||||
{
|
||||
// Transports input remoting messages from and to players. Can be used to
|
||||
|
|
|
@ -10,7 +10,10 @@ namespace ISX
|
|||
[StructLayout(LayoutKind.Explicit, Size = 360)]
|
||||
public struct TouchscreenState : IInputStateTypeInfo
|
||||
{
|
||||
public static FourCC kFormat => new FourCC('T', 'S', 'C', 'R');
|
||||
public static FourCC kFormat
|
||||
{
|
||||
get { return new FourCC('T', 'S', 'C', 'R'); }
|
||||
}
|
||||
|
||||
public const int kMaxTouches = 10;
|
||||
|
||||
|
|
|
@ -5,7 +5,10 @@ namespace ISX
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TrackingState : IInputStateTypeInfo
|
||||
{
|
||||
public static FourCC kFormat => new FourCC('T', 'R', 'A', 'K');
|
||||
public static FourCC kFormat
|
||||
{
|
||||
get { return new FourCC('T', 'R', 'A', 'K'); }
|
||||
}
|
||||
|
||||
[InputControl] public Pose pose;
|
||||
|
||||
|
@ -18,7 +21,10 @@ namespace ISX
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct HMDState : IInputStateTypeInfo
|
||||
{
|
||||
public static FourCC kFormat => new FourCC('H', 'E', 'A', 'D');
|
||||
public static FourCC kFormat
|
||||
{
|
||||
get { return new FourCC('H', 'E', 'A', 'D'); }
|
||||
}
|
||||
|
||||
[InputControl(name = "isWearing", template = "Button", bit = 0)]
|
||||
public int buttons;
|
||||
|
@ -65,7 +71,10 @@ namespace ISX
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XRControllerState : IInputStateTypeInfo
|
||||
{
|
||||
public static FourCC kFormat => new FourCC('C', 'T', 'R', 'L');
|
||||
public static FourCC kFormat
|
||||
{
|
||||
get { return new FourCC('C', 'T', 'R', 'L'); }
|
||||
}
|
||||
|
||||
[InputControl] public Pose pose;
|
||||
|
||||
|
|
|
@ -52,7 +52,11 @@ namespace ISX.Editor
|
|||
s_RefreshListeners = new List<Action>();
|
||||
s_RefreshListeners.Add(value);
|
||||
}
|
||||
remove { s_RefreshListeners?.Remove(value); }
|
||||
remove
|
||||
{
|
||||
if (s_RefreshListeners != null)
|
||||
s_RefreshListeners.Remove(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static InputTemplate TryGetTemplate(string name)
|
||||
|
@ -63,7 +67,8 @@ namespace ISX.Editor
|
|||
internal static void Clear()
|
||||
{
|
||||
s_TemplateSetupVersion = 0;
|
||||
s_Cache.table?.Clear();
|
||||
if (s_Cache.table != null)
|
||||
s_Cache.table.Clear();
|
||||
s_Usages.Clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,8 @@ namespace ISX.Editor
|
|||
public void Reload()
|
||||
{
|
||||
serializedObject.Update();
|
||||
m_ActionTreeView?.Reload();
|
||||
if (m_ActionTreeView != null)
|
||||
m_ActionTreeView.Reload();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
|
@ -68,7 +69,8 @@ namespace ISX.Editor
|
|||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndVertical();
|
||||
var treeViewRect = GUILayoutUtility.GetLastRect();
|
||||
m_ActionTreeView?.OnGUI(treeViewRect);
|
||||
if (m_ActionTreeView != null)
|
||||
m_ActionTreeView.OnGUI(treeViewRect);
|
||||
}
|
||||
|
||||
protected void DrawToolbarGUI()
|
||||
|
@ -103,7 +105,8 @@ namespace ISX.Editor
|
|||
private void Apply()
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
m_ApplyAction?.Invoke();
|
||||
if (m_ApplyAction != null)
|
||||
m_ApplyAction.Invoke();
|
||||
}
|
||||
|
||||
[SerializeField] private TreeViewState m_ActionTreeViewState;
|
||||
|
|
|
@ -49,19 +49,19 @@ namespace ISX.Editor
|
|||
};
|
||||
|
||||
// Header.
|
||||
writer.WriteLine($"// GENERATED AUTOMATICALLY FROM '{options.sourceAssetPath}'\n");
|
||||
writer.WriteLine(string.Format("// GENERATED AUTOMATICALLY FROM '{0}'\n", options.sourceAssetPath));
|
||||
|
||||
// Begin namespace.
|
||||
var haveNamespace = !string.IsNullOrEmpty(options.namespaceName);
|
||||
if (haveNamespace)
|
||||
{
|
||||
writer.WriteLine($"namespace {options.namespaceName}");
|
||||
writer.WriteLine(string.Format("namespace {0}", options.namespaceName));
|
||||
writer.BeginBlock();
|
||||
}
|
||||
|
||||
// Begin class.
|
||||
writer.WriteLine("[System.Serializable]");
|
||||
writer.WriteLine($"public class {options.className} : ISX.InputActionWrapper");
|
||||
writer.WriteLine(string.Format("public class {0} : ISX.InputActionWrapper", options.className));
|
||||
writer.BeginBlock();
|
||||
|
||||
// Initialize method.
|
||||
|
@ -70,10 +70,11 @@ namespace ISX.Editor
|
|||
writer.BeginBlock();
|
||||
foreach (var set in sets)
|
||||
{
|
||||
writer.WriteLine($"// {set.name}");
|
||||
writer.WriteLine($"m_{set.name} = asset.GetActionSet(\"{set.name}\");");
|
||||
writer.WriteLine(string.Format("// {0}", set.name));
|
||||
writer.WriteLine(string.Format("m_{0} = asset.GetActionSet(\"{1}\");", set.name, set.name));
|
||||
foreach (var action in set.actions)
|
||||
writer.WriteLine($"m_{set.name}_{action.name} = m_{set.name}.GetAction(\"{action.name}\");");
|
||||
writer.WriteLine(string.Format("m_{0}_{1} = m_{2}.GetAction(\"{3}\");", set.name, action.name,
|
||||
set.name, action.name));
|
||||
}
|
||||
writer.WriteLine("m_Initialized = true;");
|
||||
writer.EndBlock();
|
||||
|
@ -81,51 +82,57 @@ namespace ISX.Editor
|
|||
// Action set accessors.
|
||||
foreach (var set in sets)
|
||||
{
|
||||
writer.WriteLine($"// {set.name}");
|
||||
writer.WriteLine(string.Format("// {0}", set.name));
|
||||
var setStructName = MakeTypeName(set.name, "Actions");
|
||||
|
||||
// Caching field for action set.
|
||||
writer.WriteLine($"private ISX.InputActionSet m_{set.name};");
|
||||
writer.WriteLine(string.Format("private ISX.InputActionSet m_{0};", set.name));
|
||||
|
||||
// Caching fields for all actions.
|
||||
foreach (var action in set.actions)
|
||||
writer.WriteLine($"private ISX.InputAction m_{set.name}_{action.name};");
|
||||
writer.WriteLine(string.Format("private ISX.InputAction m_{0}_{1};", set.name, action.name));
|
||||
|
||||
// Struct wrapping access to action set.
|
||||
writer.WriteLine($"public struct {setStructName}");
|
||||
writer.WriteLine(string.Format("public struct {0}", setStructName));
|
||||
writer.BeginBlock();
|
||||
|
||||
// Constructor.
|
||||
writer.WriteLine($"private {options.className} m_Wrapper;");
|
||||
writer.WriteLine($"public {setStructName}({options.className} wrapper) {{ m_Wrapper = wrapper; }}");
|
||||
writer.WriteLine(string.Format("private {0} m_Wrapper;", options.className));
|
||||
writer.WriteLine(string.Format("public {0}({1} wrapper) {{ m_Wrapper = wrapper; }}", setStructName,
|
||||
options.className));
|
||||
|
||||
// Getter for each action.
|
||||
foreach (var action in set.actions)
|
||||
writer.WriteLine($"public ISX.InputAction @{action.name} {{ get {{ return m_Wrapper.m_{set.name}_{action.name}; }} }}");
|
||||
writer.WriteLine(string.Format(
|
||||
"public ISX.InputAction @{0} {{ get {{ return m_Wrapper.m_{1}_{2}; }} }}", action.name,
|
||||
set.name, action.name));
|
||||
|
||||
// Action set getter.
|
||||
writer.WriteLine($"public ISX.InputActionSet Get() {{ return m_Wrapper.m_{set.name}; }}");
|
||||
writer.WriteLine(string.Format("public ISX.InputActionSet Get() {{ return m_Wrapper.m_{0}; }}",
|
||||
set.name));
|
||||
|
||||
// Enable/disable methods.
|
||||
writer.WriteLine($"public void Enable() {{ Get().Enable(); }}");
|
||||
writer.WriteLine($"public void Disable() {{ Get().Disable(); }}");
|
||||
writer.WriteLine("public void Enable() { Get().Enable(); }");
|
||||
writer.WriteLine("public void Disable() { Get().Disable(); }");
|
||||
|
||||
// Clone method.
|
||||
writer.WriteLine($"public ISX.InputActionSet Clone() {{ return Get().Clone(); }}");
|
||||
writer.WriteLine("public ISX.InputActionSet Clone() { return Get().Clone(); }");
|
||||
|
||||
// Implicit conversion operator.
|
||||
writer.WriteLine($"public static implicit operator ISX.InputActionSet({setStructName} set) {{ return set.Get(); }}");
|
||||
writer.WriteLine(string.Format(
|
||||
"public static implicit operator ISX.InputActionSet({0} set) {{ return set.Get(); }}",
|
||||
setStructName));
|
||||
|
||||
writer.EndBlock();
|
||||
|
||||
// Getter for instance of struct.
|
||||
writer.WriteLine($"public {setStructName} @{set.name}");
|
||||
writer.WriteLine(string.Format("public {0} @{1}", setStructName, set.name));
|
||||
writer.BeginBlock();
|
||||
|
||||
writer.WriteLine($"get");
|
||||
writer.WriteLine("get");
|
||||
writer.BeginBlock();
|
||||
writer.WriteLine("if (!m_Initialized) Initialize();");
|
||||
writer.WriteLine($"return new {setStructName}(this);");
|
||||
writer.WriteLine(string.Format("return new {0}(this);", setStructName));
|
||||
writer.EndBlock();
|
||||
|
||||
writer.EndBlock();
|
||||
|
@ -181,7 +188,7 @@ namespace ISX.Editor
|
|||
{
|
||||
if (char.IsLower(name[0]))
|
||||
name = char.ToUpper(name[0]).ToString() + name.Substring(1);
|
||||
return $"{name}{suffix}";
|
||||
return string.Format("{0}{1}", name, suffix);
|
||||
}
|
||||
|
||||
// Updates the given file with wrapper code generated for the given action sets.
|
||||
|
|
|
@ -52,7 +52,8 @@ namespace ISX.Editor
|
|||
|
||||
private void RemoveFromList()
|
||||
{
|
||||
s_OpenDebuggerWindows?.Remove(this);
|
||||
if (s_OpenDebuggerWindows != null)
|
||||
s_OpenDebuggerWindows.Remove(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace ISX.Editor
|
|||
|
||||
var objectName = action.name;
|
||||
if (haveSetName)
|
||||
objectName = $"{set.name}/{action.name}";
|
||||
objectName = string.Format("{0}/{1}", set.name, action.name);
|
||||
|
||||
actionObject.name = objectName;
|
||||
ctx.AddObjectToAsset(objectName, actionObject);
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace ISX.Editor
|
|||
|
||||
////TODO: would be nice to include template name to print something like "Gamepad A Button" instead of "Gamepad A" (or whatever)
|
||||
|
||||
text = $"{device} {control}";
|
||||
text = string.Format("{0} {1}", device, control);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,8 +102,8 @@ namespace ISX.Editor
|
|||
if (!string.IsNullOrEmpty(modifiers))
|
||||
{
|
||||
var modifierList = InputTemplate.ParseNameAndParameterList(modifiers);
|
||||
var modifierString = string.Join(" OR ", modifierList.Select(x => x.name));
|
||||
text = $"{modifierString} {text}";
|
||||
var modifierString = string.Join(" OR ", modifierList.Select(x => x.name).ToArray());
|
||||
text = string.Format("{0} {1}", modifierString, text);
|
||||
}
|
||||
|
||||
////TODO: this looks ugly and not very obvious; find a better way
|
||||
|
@ -158,7 +158,7 @@ namespace ISX.Editor
|
|||
if (!string.IsNullOrEmpty(modifierString))
|
||||
m_Modifiers = InputTemplate.ParseNameAndParameterList(modifierString);
|
||||
else
|
||||
m_Modifiers = Array.Empty<InputTemplate.NameAndParameters>();
|
||||
m_Modifiers = new InputTemplate.NameAndParameters[0]; //Array.Empty<InputTemplate.NameAndParameters>();
|
||||
|
||||
InitializeModifierListView();
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ namespace ISX.Editor
|
|||
|
||||
private void ApplyModifiers()
|
||||
{
|
||||
var modifiers = string.Join(",", m_Modifiers.Select(x => x.ToString()));
|
||||
var modifiers = string.Join(",", m_Modifiers.Select(x => x.ToString()).ToArray());
|
||||
m_ModifiersProperty.stringValue = modifiers;
|
||||
m_ModifiersProperty.serializedObject.ApplyModifiedProperties();
|
||||
InitializeModifierListView();
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace ISX.Editor
|
|||
public InputControlPicker(SerializedProperty pathProperty)
|
||||
{
|
||||
if (pathProperty == null)
|
||||
throw new ArgumentNullException(nameof(pathProperty));
|
||||
throw new ArgumentNullException("pathProperty");
|
||||
m_PathProperty = pathProperty;
|
||||
|
||||
m_PathTreeState = new TreeViewState();
|
||||
|
@ -103,7 +103,7 @@ namespace ISX.Editor
|
|||
var rect = args.rowRect;
|
||||
rect.x += indent;
|
||||
rect.width -= indent;
|
||||
EditorGUI.LabelField(rect, $"{item.device}/{item.control}");
|
||||
EditorGUI.LabelField(rect, string.Format("{0}/{1}", item.device, item.control));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -120,11 +120,11 @@ namespace ISX.Editor
|
|||
{
|
||||
String path = null;
|
||||
if (item.usage != null)
|
||||
path = $"*/{{{item.usage}}}";
|
||||
path = string.Format("*/{{{0}}}", item.usage);
|
||||
else if (item.device != null && item.control != null)
|
||||
path = $"<{item.device}>/{item.control}";
|
||||
path = string.Format("<{0}>/{1}", item.device, item.control);
|
||||
else if (item.device != null)
|
||||
path = $"<{item.device}>";
|
||||
path = string.Format("<{0}>", item.device);
|
||||
|
||||
if (path != null)
|
||||
{
|
||||
|
@ -241,8 +241,9 @@ namespace ISX.Editor
|
|||
parent.AddChild(child);
|
||||
}
|
||||
|
||||
parent.children?.Sort((a, b) =>
|
||||
string.Compare(a.displayName, b.displayName, StringComparison.Ordinal));
|
||||
if (parent.children != null)
|
||||
parent.children.Sort((a, b) =>
|
||||
string.Compare(a.displayName, b.displayName, StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,8 @@ namespace ISX.Editor
|
|||
{
|
||||
RemoveFromList();
|
||||
|
||||
m_EventTrace?.Dispose();
|
||||
if (m_EventTrace != null)
|
||||
m_EventTrace.Dispose();
|
||||
InputSystem.onDeviceChange -= OnDeviceChange;
|
||||
}
|
||||
|
||||
|
@ -155,7 +156,7 @@ namespace ISX.Editor
|
|||
m_Device = device;
|
||||
m_DeviceId = device.id;
|
||||
m_DeviceIdString = device.id.ToString();
|
||||
m_DeviceUsagesString = string.Join(", ", device.usages.Select(x => x.ToString()));
|
||||
m_DeviceUsagesString = string.Join(", ", device.usages.Select(x => x.ToString()).ToArray());
|
||||
|
||||
// Set up event trace. The default trace size of 1mb fits a ton of events and will
|
||||
// likely bog down the UI if we try to display that many events. Instead, come up
|
||||
|
@ -208,7 +209,8 @@ namespace ISX.Editor
|
|||
|
||||
private void RemoveFromList()
|
||||
{
|
||||
s_OpenDebuggerWindows?.Remove(this);
|
||||
if (s_OpenDebuggerWindows != null)
|
||||
s_OpenDebuggerWindows.Remove(this);
|
||||
}
|
||||
|
||||
private void OnDeviceChange(InputDevice device, InputDeviceChange change)
|
||||
|
|
|
@ -133,7 +133,7 @@ namespace ISX.Editor
|
|||
else
|
||||
rootBaseTemplateName += "s";
|
||||
|
||||
var group = products.children?.FirstOrDefault(x => x.displayName == rootBaseTemplateName);
|
||||
var group = products.children != null ? products.children.FirstOrDefault(x => x.displayName == rootBaseTemplateName) : null;
|
||||
if (group == null)
|
||||
{
|
||||
group = new TreeViewItem
|
||||
|
@ -172,27 +172,30 @@ namespace ISX.Editor
|
|||
};
|
||||
|
||||
// Header.
|
||||
AddChild(item, $"Type: {template.type.Name}", ref id);
|
||||
AddChild(item, string.Format("Type: {0}", template.type.Name), ref id);
|
||||
if (!string.IsNullOrEmpty(template.extendsTemplate))
|
||||
AddChild(item, $"Extends: {template.extendsTemplate}", ref id);
|
||||
AddChild(item, string.Format("Extends: {0}", template.extendsTemplate), ref id);
|
||||
if (template.stateFormat != 0)
|
||||
AddChild(item, $"Format: {template.stateFormat}", ref id);
|
||||
AddChild(item, string.Format("Format: {0}", template.stateFormat), ref id);
|
||||
if (template.m_UpdateBeforeRender != null)
|
||||
{
|
||||
var value = template.m_UpdateBeforeRender.Value ? "Update" : "Disabled";
|
||||
AddChild(item, $"Before Render: {value}", ref id);
|
||||
AddChild(item, string.Format("Before Render: {0}", value), ref id);
|
||||
}
|
||||
if (!template.deviceDescription.empty)
|
||||
{
|
||||
var deviceDescription = AddChild(item, "Device Description", ref id);
|
||||
if (!string.IsNullOrEmpty(template.deviceDescription.deviceClass))
|
||||
AddChild(deviceDescription, $"Device Class: {template.deviceDescription.deviceClass}", ref id);
|
||||
AddChild(deviceDescription,
|
||||
string.Format("Device Class: {0}", template.deviceDescription.deviceClass), ref id);
|
||||
if (!string.IsNullOrEmpty(template.deviceDescription.interfaceName))
|
||||
AddChild(deviceDescription, $"Interface: {template.deviceDescription.interfaceName}", ref id);
|
||||
AddChild(deviceDescription,
|
||||
string.Format("Interface: {0}", template.deviceDescription.interfaceName), ref id);
|
||||
if (!string.IsNullOrEmpty(template.deviceDescription.product))
|
||||
AddChild(deviceDescription, $"Product: {template.deviceDescription.product}", ref id);
|
||||
AddChild(deviceDescription, string.Format("Product: {0}", template.deviceDescription.product), ref id);
|
||||
if (!string.IsNullOrEmpty(template.deviceDescription.manufacturer))
|
||||
AddChild(deviceDescription, $"Manufacturer: {template.deviceDescription.manufacturer}", ref id);
|
||||
AddChild(deviceDescription,
|
||||
string.Format("Manufacturer: {0}", template.deviceDescription.manufacturer), ref id);
|
||||
}
|
||||
|
||||
// Controls.
|
||||
|
@ -210,32 +213,33 @@ namespace ISX.Editor
|
|||
|
||||
private void BuildItem(InputTemplate.ControlTemplate control, TreeViewItem parent, ref int id)
|
||||
{
|
||||
var item = AddChild(parent, control.variant.IsEmpty() ? control.name : $"{control.name} ({control.variant})", ref id);
|
||||
var item = AddChild(parent, control.variant.IsEmpty() ? control.name : string.Format("{0} ({1})",
|
||||
control.name, control.variant), ref id);
|
||||
|
||||
////TODO: fully merge TreeViewItems from isModifyingChildControlByPath control templates into the control they modify
|
||||
|
||||
////TODO: allow clicking this field to jump to the template
|
||||
if (!control.template.IsEmpty())
|
||||
AddChild(item, $"Template: {control.template}", ref id);
|
||||
AddChild(item, string.Format("Template: {0}", control.template), ref id);
|
||||
if (!control.variant.IsEmpty())
|
||||
AddChild(item, $"Variant: {control.variant}", ref id);
|
||||
AddChild(item, string.Format("Variant: {0}", control.variant), ref id);
|
||||
if (control.format != 0)
|
||||
AddChild(item, $"Format: {control.format}", ref id);
|
||||
AddChild(item, string.Format("Format: {0}", control.format), ref id);
|
||||
if (control.offset != InputStateBlock.kInvalidOffset)
|
||||
AddChild(item, $"Offset: {control.offset}", ref id);
|
||||
AddChild(item, string.Format("Offset: {0}", control.offset), ref id);
|
||||
if (control.bit != InputStateBlock.kInvalidOffset)
|
||||
AddChild(item, $"Bit: {control.bit}", ref id);
|
||||
AddChild(item, string.Format("Bit: {0}", control.bit), ref id);
|
||||
if (control.sizeInBits != 0)
|
||||
AddChild(item, $"Size In Bits: {control.sizeInBits}", ref id);
|
||||
AddChild(item, string.Format("Size In Bits: {0}", control.sizeInBits), ref id);
|
||||
if (!string.IsNullOrEmpty(control.useStateFrom))
|
||||
AddChild(item, $"Use State From: {control.useStateFrom}", ref id);
|
||||
AddChild(item, string.Format("Use State From: {0}", control.useStateFrom), ref id);
|
||||
if (control.isAutoResetControl)
|
||||
AddChild(item, "Auto-Reset: true", ref id);
|
||||
|
||||
if (control.usages.Count > 0)
|
||||
AddChild(item, "Usages: " + string.Join(", ", control.usages), ref id);
|
||||
AddChild(item, "Usages: " + string.Join(", ", control.usages.Select(x => x.ToString()).ToArray()), ref id);
|
||||
if (control.aliases.Count > 0)
|
||||
AddChild(item, "Aliases: " + string.Join(", ", control.aliases), ref id);
|
||||
AddChild(item, "Aliases: " + string.Join(", ", control.aliases.Select(x => x.ToString()).ToArray()), ref id);
|
||||
|
||||
if (control.parameters.Count > 0)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using UnityEditor;
|
||||
|
||||
namespace ISX.Editor
|
||||
|
@ -163,7 +164,7 @@ namespace ISX.Editor
|
|||
if (elementName.ToLower() == lowerCase)
|
||||
{
|
||||
++namesTried;
|
||||
result = $"{baseName}{namesTried}";
|
||||
result = string.Format("{0}{1}", baseName, namesTried);
|
||||
lowerCase = result.ToLower();
|
||||
nameIsUnique = false;
|
||||
break;
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace ISX.Editor
|
|||
var buffer = new byte[stateSize];
|
||||
fixed(byte* stateDataPtr = buffer)
|
||||
{
|
||||
UnsafeUtility.MemCpy(new IntPtr(stateDataPtr), deviceState + (int)stateOffset, stateSize);
|
||||
UnsafeUtility.MemCpy(new IntPtr(stateDataPtr), new IntPtr(deviceState.ToInt64() + (int)stateOffset), stateSize);
|
||||
}
|
||||
m_StateBuffers[i] = buffer;
|
||||
|
||||
|
|
|
@ -32,7 +32,10 @@ namespace ISX
|
|||
[FieldOffset(InputEvent.kBaseEventSize + 4)] public uint stateOffset;
|
||||
[FieldOffset(InputEvent.kBaseEventSize + 8)] public fixed byte stateData[1]; // Variable-sized.
|
||||
|
||||
public int stateSizeInBytes => baseEvent.sizeInBytes - (InputEvent.kBaseEventSize + 8);
|
||||
public int stateSizeInBytes
|
||||
{
|
||||
get { return baseEvent.sizeInBytes - (InputEvent.kBaseEventSize + 8); }
|
||||
}
|
||||
|
||||
public IntPtr state
|
||||
{
|
||||
|
@ -48,12 +51,35 @@ namespace ISX
|
|||
// Action-specific fields are appended *after* the device state in the event.
|
||||
// This way we can use ActionEvent everywhere a DeltaStateEvent is expected.
|
||||
|
||||
public int actionIndex => *(int*)(actionData + (int)ActionDataOffset.ActionIndex);
|
||||
public int bindingIndex => *(int*)(actionData + (int)ActionDataOffset.BindingIndex);
|
||||
public int modifierIndex => *(int*)(actionData + (int)ActionDataOffset.ModifierIndex);
|
||||
public double startTime => *(double*)(actionData + (int)ActionDataOffset.StartTime);
|
||||
public double endTime => *(double*)(actionData + (int)ActionDataOffset.EndTime);
|
||||
public InputAction.Phase phase => (InputAction.Phase)(*(int*)(actionData + (int)ActionDataOffset.Phase));
|
||||
public int actionIndex
|
||||
{
|
||||
get { return *(int*)new IntPtr(actionData.ToInt64() + (int)ActionDataOffset.ActionIndex); }
|
||||
}
|
||||
|
||||
public int bindingIndex
|
||||
{
|
||||
get { return *(int*)new IntPtr(actionData.ToInt64() + (int)ActionDataOffset.BindingIndex); }
|
||||
}
|
||||
|
||||
public int modifierIndex
|
||||
{
|
||||
get { return *(int*)new IntPtr(actionData.ToInt64() + (int)ActionDataOffset.ModifierIndex); }
|
||||
}
|
||||
|
||||
public double startTime
|
||||
{
|
||||
get { return *(double*)new IntPtr(actionData.ToInt64() + (int)ActionDataOffset.StartTime); }
|
||||
}
|
||||
|
||||
public double endTime
|
||||
{
|
||||
get { return *(double*)new IntPtr(actionData.ToInt64() + (int)ActionDataOffset.EndTime); }
|
||||
}
|
||||
|
||||
public InputAction.Phase phase
|
||||
{
|
||||
get { return (InputAction.Phase)(*(int*)new IntPtr(actionData.ToInt64() + (int)ActionDataOffset.Phase)); }
|
||||
}
|
||||
|
||||
////TODO: give all currently enabled actions indices
|
||||
|
||||
|
@ -62,7 +88,10 @@ namespace ISX
|
|||
return Type;
|
||||
}
|
||||
|
||||
internal IntPtr actionData => state + stateSizeInBytes;
|
||||
internal IntPtr actionData
|
||||
{
|
||||
get { return new IntPtr(state.ToInt64() + stateSizeInBytes); }
|
||||
}
|
||||
|
||||
internal enum ActionDataOffset
|
||||
{
|
||||
|
|
|
@ -18,7 +18,10 @@ namespace ISX
|
|||
[FieldOffset(InputEvent.kBaseEventSize + 4)] public uint stateOffset;
|
||||
[FieldOffset(InputEvent.kBaseEventSize + 8)] public fixed byte stateData[1]; // Variable-sized.
|
||||
|
||||
public int stateSizeInBytes => baseEvent.sizeInBytes - (InputEvent.kBaseEventSize + 8);
|
||||
public int stateSizeInBytes
|
||||
{
|
||||
get { return baseEvent.sizeInBytes - (InputEvent.kBaseEventSize + 8); }
|
||||
}
|
||||
|
||||
public IntPtr state
|
||||
{
|
||||
|
|
|
@ -2,8 +2,10 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace ISX
|
||||
{
|
||||
// A chunk of memory signaling a data transfer in the input system.
|
||||
// This has to be layout compatible with native events.
|
||||
/// <summary>
|
||||
/// A chunk of memory signaling a data transfer in the input system.
|
||||
/// </summary>
|
||||
// NOTE: This has to be layout compatible with native events.
|
||||
[StructLayout(LayoutKind.Explicit, Size = kBaseEventSize)]
|
||||
public struct InputEvent : IInputEventTypeInfo
|
||||
{
|
||||
|
@ -20,10 +22,33 @@ namespace ISX
|
|||
////REVIEW: does this really need to be a double? float would save us a 4 bytes
|
||||
[FieldOffset(12)] private double m_Time;
|
||||
|
||||
public FourCC type => m_Type;
|
||||
public int sizeInBytes => m_SizeInBytes;
|
||||
public FourCC type
|
||||
{
|
||||
get { return m_Type; }
|
||||
}
|
||||
|
||||
public int eventId => (int)(m_EventId & kIdMask);
|
||||
/// <summary>
|
||||
/// Total size of the event in bytes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Events are variable-size structs. This field denotes the total size of the event
|
||||
/// as stored in memory.
|
||||
/// </remarks>
|
||||
public int sizeInBytes
|
||||
{
|
||||
get { return m_SizeInBytes; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unique serial ID of the event.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Events are assigned running IDs when they are put on an event queue.
|
||||
/// </remarks>
|
||||
public int eventId
|
||||
{
|
||||
get { return (int)(m_EventId & kIdMask); }
|
||||
}
|
||||
|
||||
////TODO: kill device IDs
|
||||
public int deviceId
|
||||
|
@ -65,7 +90,8 @@ namespace ISX
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"id={eventId} type={type} device={deviceId} size={sizeInBytes} time={time}";
|
||||
return string.Format("id={0} type={1} device={2} size={3} time={4}",
|
||||
eventId, type, deviceId, sizeInBytes, time);
|
||||
}
|
||||
|
||||
internal static unsafe InputEvent* GetNextInMemory(InputEvent* current)
|
||||
|
|
|
@ -21,8 +21,12 @@
|
|||
|
||||
namespace ISX
|
||||
{
|
||||
// A buffer containing InputEvents.
|
||||
// Stored in unmanaged memory. Safe to pass to jobs.
|
||||
/// <summary>
|
||||
/// A buffer containing InputEvents.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Stored in unmanaged memory. Safe to pass to jobs.
|
||||
/// </remarks>
|
||||
public struct InputEventBuffer
|
||||
{
|
||||
}
|
||||
|
|
|
@ -22,7 +22,10 @@ namespace ISX
|
|||
{
|
||||
}
|
||||
|
||||
public bool valid => m_EventPtr != null;
|
||||
public bool valid
|
||||
{
|
||||
get { return m_EventPtr != null; }
|
||||
}
|
||||
|
||||
public bool handled
|
||||
{
|
||||
|
@ -86,9 +89,15 @@ namespace ISX
|
|||
}
|
||||
}
|
||||
|
||||
public double time => valid ? m_EventPtr->time : 0.0;
|
||||
public double time
|
||||
{
|
||||
get { return valid ? m_EventPtr->time : 0.0; }
|
||||
}
|
||||
|
||||
public IntPtr data => new IntPtr(m_EventPtr);
|
||||
public IntPtr data
|
||||
{
|
||||
get { return new IntPtr(m_EventPtr); }
|
||||
}
|
||||
|
||||
public bool IsA<TOtherEvent>()
|
||||
where TOtherEvent : struct, IInputEventTypeInfo
|
||||
|
@ -106,7 +115,7 @@ namespace ISX
|
|||
if (!valid)
|
||||
return new InputEventPtr();
|
||||
|
||||
return new InputEventPtr(new IntPtr(m_EventPtr) + sizeInBytes);
|
||||
return new InputEventPtr(new IntPtr(new IntPtr(m_EventPtr).ToInt64() + sizeInBytes));
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ISX
|
||||
{
|
||||
/// <summary>
|
||||
/// An InputEventBuffer that can be concurrently written to and read from in FIFO order.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Event queues have a fixed size. If events are produced faster than they are consumed,
|
||||
/// new events will start overwriting old events.
|
||||
///
|
||||
/// Event size is also fixed. While smaller events can be written to the queue, larger
|
||||
/// events will be rejected.
|
||||
///
|
||||
/// Memory for event queues is allocated on the native heap and queues can be written to
|
||||
/// and read from both in C++ and in C#.
|
||||
/// </remarks>
|
||||
public struct InputEventQueue
|
||||
{
|
||||
public InputEventQueue(int maxEventSizeInBytes, int maxEventCount)
|
||||
{
|
||||
}
|
||||
|
||||
internal InputEventQueue(IntPtr nativeQueuePtr)
|
||||
{
|
||||
}
|
||||
|
||||
public void WriteEvent(InputEventPtr eventPtr)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public InputEventPtr TryReadNextEvent()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
// Data layout of queue in native memory.
|
||||
// The queue consists of a header, a variable-size table of event pointers, and
|
||||
// a variable-size buffer of event storage.
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
private unsafe struct QueueData
|
||||
{
|
||||
[FieldOffset(0)] public uint maxEventSizeInBytes;
|
||||
[FieldOffset(4)] public uint maxEventCount;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dfbd886143c3419692f4749b9bf0e970
|
||||
timeCreated: 1511482003
|
|
@ -23,7 +23,10 @@ namespace ISX
|
|||
set { m_DeviceId = value; }
|
||||
}
|
||||
|
||||
public bool enabled => m_Enabled;
|
||||
public bool enabled
|
||||
{
|
||||
get { return m_Enabled; }
|
||||
}
|
||||
|
||||
public event Action<InputEventPtr> onEvent
|
||||
{
|
||||
|
@ -84,8 +87,8 @@ namespace ISX
|
|||
|
||||
// Otherwise feel our way forward.
|
||||
|
||||
var nextEvent = current.data + current.sizeInBytes;
|
||||
var endOfBuffer = m_EventBuffer + m_EventBufferSize;
|
||||
var nextEvent = new IntPtr(current.data.ToInt64() + current.sizeInBytes);
|
||||
var endOfBuffer = new IntPtr(m_EventBuffer.ToInt64() + m_EventBufferSize);
|
||||
|
||||
// If we've run into our tail, there's no more events.
|
||||
if (nextEvent.ToInt64() == m_EventBufferTail.ToInt64())
|
||||
|
@ -184,14 +187,14 @@ namespace ISX
|
|||
// First event in buffer.
|
||||
buffer = m_EventBuffer;
|
||||
m_EventBufferHead = m_EventBuffer;
|
||||
m_EventBufferTail = buffer + eventSize;
|
||||
m_EventBufferTail = new IntPtr(buffer.ToInt64() + eventSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
var newTail = m_EventBufferTail + eventSize;
|
||||
var newTail = new IntPtr(m_EventBufferTail.ToInt64() + eventSize);
|
||||
|
||||
var newTailOvertakesHead = newTail.ToInt64() > m_EventBufferHead.ToInt64() && m_EventBufferHead != m_EventBuffer;
|
||||
var newTailGoesPastEndOfBuffer = newTail.ToInt64() > (m_EventBuffer + m_EventBufferSize).ToInt64();
|
||||
var newTailGoesPastEndOfBuffer = newTail.ToInt64() > (m_EventBuffer.ToInt64() + m_EventBufferSize);
|
||||
|
||||
// If tail goes out of bounds, go back to beginning of buffer.
|
||||
if (newTailGoesPastEndOfBuffer)
|
||||
|
@ -203,7 +206,7 @@ namespace ISX
|
|||
UnsafeUtility.MemClear(m_EventBufferTail, InputEvent.kBaseEventSize);
|
||||
|
||||
m_EventBufferTail = m_EventBuffer;
|
||||
newTail = m_EventBuffer + eventSize;
|
||||
newTail = new IntPtr(m_EventBuffer.ToInt64() + eventSize);
|
||||
|
||||
// Recheck whether we're overtaking head.
|
||||
newTailOvertakesHead = newTail.ToInt64() > m_EventBufferHead.ToInt64();
|
||||
|
@ -276,8 +279,15 @@ namespace ISX
|
|||
m_Current = new InputEventPtr();
|
||||
}
|
||||
|
||||
public InputEventPtr Current => m_Current;
|
||||
object IEnumerator.Current => Current;
|
||||
public InputEventPtr Current
|
||||
{
|
||||
get { return m_Current; }
|
||||
}
|
||||
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get { return Current; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,10 @@ namespace ISX
|
|||
[FieldOffset(InputEvent.kBaseEventSize)] public FourCC stateFormat;
|
||||
[FieldOffset(InputEvent.kBaseEventSize + 4)] public fixed byte stateData[1]; // Variable-sized.
|
||||
|
||||
public int stateSizeInBytes => baseEvent.sizeInBytes - (InputEvent.kBaseEventSize + 4);
|
||||
public int stateSizeInBytes
|
||||
{
|
||||
get { return baseEvent.sizeInBytes - (InputEvent.kBaseEventSize + 4); }
|
||||
}
|
||||
|
||||
public IntPtr state
|
||||
{
|
||||
|
@ -42,9 +45,10 @@ namespace ISX
|
|||
public static StateEvent* From(InputEventPtr ptr)
|
||||
{
|
||||
if (!ptr.valid)
|
||||
throw new ArgumentNullException(nameof(ptr));
|
||||
throw new ArgumentNullException("ptr");
|
||||
if (!ptr.IsA<StateEvent>())
|
||||
throw new InvalidCastException($"Cannot cast event with type '{ptr.type}' into StateEvent");
|
||||
throw new InvalidCastException(string.Format("Cannot cast event with type '{0}' into StateEvent",
|
||||
ptr.type));
|
||||
|
||||
return (StateEvent*)ptr.data;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace ISX
|
||||
{
|
||||
public interface IInputModuleManager
|
||||
public interface IInputPlugin
|
||||
{
|
||||
void Initialize();
|
||||
}
|
|
@ -49,10 +49,16 @@ namespace ISX
|
|||
}
|
||||
|
||||
// How many controls in total are in the system?
|
||||
public static int controlCount => 0;
|
||||
public static int controlCount
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
// How many devices in total are in the system?
|
||||
public static int deviceCount => 0;
|
||||
public static int deviceCount
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
////REVIEW: how should strings be handled in this system? store these externally? Use InternedString and a system-specific table?
|
||||
private string[] m_Names;
|
||||
|
|
|
@ -6,6 +6,10 @@ using UnityEngine;
|
|||
using UnityEngine.Profiling;
|
||||
using UnityEngineInternal.Input;
|
||||
|
||||
#if !NET_4_0
|
||||
using ISX.Net35Compatibility;
|
||||
#endif
|
||||
|
||||
////TODO: allow pushing events into the system any which way; decouple from the buffer in NativeInputSystem being the only source
|
||||
|
||||
////TODO: merge InputManager into InputSystem and have InputSystemObject store SerializedState directly
|
||||
|
@ -31,7 +35,10 @@ namespace ISX
|
|||
: ISerializationCallbackReceiver
|
||||
#endif
|
||||
{
|
||||
public ReadOnlyArray<InputDevice> devices => new ReadOnlyArray<InputDevice>(m_Devices);
|
||||
public ReadOnlyArray<InputDevice> devices
|
||||
{
|
||||
get { return new ReadOnlyArray<InputDevice>(m_Devices); }
|
||||
}
|
||||
|
||||
public InputUpdateType updateMask
|
||||
{
|
||||
|
@ -94,16 +101,16 @@ namespace ISX
|
|||
public void RegisterTemplate(string name, Type type)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException(nameof(name));
|
||||
throw new ArgumentException("name");
|
||||
if (type == null)
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
throw new ArgumentNullException("type");
|
||||
|
||||
var isDeviceTemplate = typeof(InputDevice).IsAssignableFrom(type);
|
||||
var isControlTemplate = typeof(InputControl).IsAssignableFrom(type);
|
||||
|
||||
if (!isDeviceTemplate && !isControlTemplate)
|
||||
throw new ArgumentException("Types used as templates have to be InputControls are InputDevices",
|
||||
nameof(type));
|
||||
"type");
|
||||
|
||||
var internedName = new InternedString(name);
|
||||
var isReplacement = HaveTemplate(internedName);
|
||||
|
@ -122,7 +129,7 @@ namespace ISX
|
|||
public void RegisterTemplate(string json, string name = null, string @namespace = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(json))
|
||||
throw new ArgumentException(nameof(json));
|
||||
throw new ArgumentException("json");
|
||||
|
||||
////REVIEW: as long as no one has instantiated the template, the base template information is kinda pointless
|
||||
|
||||
|
@ -138,12 +145,12 @@ namespace ISX
|
|||
|
||||
// Make sure we have a name.
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException($"Template name has not been given and is not set in JSON template",
|
||||
nameof(name));
|
||||
throw new ArgumentException("Template name has not been given and is not set in JSON template",
|
||||
"name");
|
||||
}
|
||||
|
||||
if (@namespace != null)
|
||||
name = $"{@namespace}::{name}";
|
||||
name = string.Format("{0}::{1}", @namespace, name);
|
||||
|
||||
var internedName = new InternedString(name);
|
||||
var isReplacement = HaveTemplate(internedName);
|
||||
|
@ -158,24 +165,26 @@ namespace ISX
|
|||
string baseTemplate = null, InputDeviceDescription? deviceDescription = null)
|
||||
{
|
||||
if (method == null)
|
||||
throw new ArgumentNullException(nameof(method));
|
||||
throw new ArgumentNullException("method");
|
||||
if (method.IsGenericMethod)
|
||||
throw new ArgumentException($"Method must not be generic ({method})", nameof(method));
|
||||
throw new ArgumentException(string.Format("Method must not be generic ({0})", method), "method");
|
||||
if (method.GetParameters().Length > 0)
|
||||
throw new ArgumentException($"Method must not take arguments ({method})", nameof(method));
|
||||
throw new ArgumentException(string.Format("Method must not take arguments ({0})", method), "method");
|
||||
if (!typeof(InputTemplate).IsAssignableFrom(method.ReturnType))
|
||||
throw new ArgumentException($"Method msut return InputTemplate ({method})", nameof(method));
|
||||
throw new ArgumentException(string.Format("Method msut return InputTemplate ({0})", method), "method");
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException(nameof(name));
|
||||
throw new ArgumentException("name");
|
||||
|
||||
// If we have an instance, make sure it is [Serializable].
|
||||
if (instance != null)
|
||||
{
|
||||
var type = instance.GetType();
|
||||
if (type.GetCustomAttribute<SerializableAttribute>() == null)
|
||||
if (type.GetCustomAttribute<SerializableAttribute>(true) == null)
|
||||
throw new ArgumentException(
|
||||
$"Instance used with {method} to construct a template must be [Serializable] but {type} is not",
|
||||
nameof(instance));
|
||||
string.Format(
|
||||
"Instance used with {0} to construct a template must be [Serializable] but {1} is not",
|
||||
method, type),
|
||||
"instance");
|
||||
}
|
||||
|
||||
var internedName = new InternedString(name);
|
||||
|
@ -318,10 +327,10 @@ namespace ISX
|
|||
public void RemoveTemplate(string name, string @namespace = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException(nameof(name));
|
||||
throw new ArgumentException("name");
|
||||
|
||||
if (@namespace != null)
|
||||
name = $"{@namespace}::{name}";
|
||||
name = string.Format("{0}::{1}", @namespace, name);
|
||||
|
||||
var internedName = new InternedString(name);
|
||||
|
||||
|
@ -397,7 +406,7 @@ namespace ISX
|
|||
public int ListTemplates(List<string> templates)
|
||||
{
|
||||
if (templates == null)
|
||||
throw new ArgumentNullException(nameof(templates));
|
||||
throw new ArgumentNullException("templates");
|
||||
|
||||
var countBefore = templates.Count;
|
||||
|
||||
|
@ -413,9 +422,9 @@ namespace ISX
|
|||
public void RegisterProcessor(string name, Type type)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException(nameof(name));
|
||||
throw new ArgumentException("name");
|
||||
if (type == null)
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
throw new ArgumentNullException("type");
|
||||
|
||||
////REVIEW: probably good to typecheck here but it would require dealing with generic type stuff
|
||||
|
||||
|
@ -426,7 +435,7 @@ namespace ISX
|
|||
public Type TryGetProcessor(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException(nameof(name));
|
||||
throw new ArgumentException("name");
|
||||
|
||||
Type type;
|
||||
var internedName = new InternedString(name);
|
||||
|
@ -438,9 +447,9 @@ namespace ISX
|
|||
public void RegisterModifier(string name, Type type)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException(nameof(name));
|
||||
throw new ArgumentException("name");
|
||||
if (type == null)
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
throw new ArgumentNullException("type");
|
||||
|
||||
var internedName = new InternedString(name);
|
||||
m_Modifiers[internedName] = type;
|
||||
|
@ -449,7 +458,7 @@ namespace ISX
|
|||
public Type TryGetModifier(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException(nameof(name));
|
||||
throw new ArgumentException("name");
|
||||
|
||||
Type type;
|
||||
var internedName = new InternedString(name);
|
||||
|
@ -492,7 +501,7 @@ namespace ISX
|
|||
if (string.IsNullOrEmpty(path))
|
||||
return 0;
|
||||
if (controls == null)
|
||||
throw new ArgumentNullException(nameof(controls));
|
||||
throw new ArgumentNullException("controls");
|
||||
if (m_Devices == null)
|
||||
return 0;
|
||||
|
||||
|
@ -510,7 +519,7 @@ namespace ISX
|
|||
public void SetVariant(InputControl control, string variant)
|
||||
{
|
||||
if (control == null)
|
||||
throw new ArgumentNullException(nameof(control));
|
||||
throw new ArgumentNullException("control");
|
||||
if (string.IsNullOrEmpty(variant))
|
||||
variant = "Default";
|
||||
|
||||
|
@ -522,7 +531,7 @@ namespace ISX
|
|||
public void SetUsage(InputDevice device, InternedString usage)
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException(nameof(device));
|
||||
throw new ArgumentNullException("device");
|
||||
device.SetUsage(usage);
|
||||
|
||||
// Notify listeners.
|
||||
|
@ -540,7 +549,7 @@ namespace ISX
|
|||
public InputDevice AddDevice(string template, string name = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(template))
|
||||
throw new ArgumentException(nameof(template));
|
||||
throw new ArgumentException("template");
|
||||
|
||||
var internedTemplateName = new InternedString(template);
|
||||
|
||||
|
@ -577,9 +586,9 @@ namespace ISX
|
|||
public void AddDevice(InputDevice device)
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException(nameof(device));
|
||||
throw new ArgumentNullException("device");
|
||||
if (string.IsNullOrEmpty(device.template))
|
||||
throw new ArgumentException("Device has no associated template", nameof(device));
|
||||
throw new ArgumentException("Device has no associated template", "device");
|
||||
|
||||
// Ignore if the same device gets added multiple times.
|
||||
if (ArrayHelpers.Contains(m_Devices, device))
|
||||
|
@ -650,7 +659,7 @@ namespace ISX
|
|||
if (template == null)
|
||||
{
|
||||
if (throwIfNoTemplateFound)
|
||||
throw new ArgumentException("Cannot find template matching device description", nameof(description));
|
||||
throw new ArgumentException("Cannot find template matching device description", "description");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -664,7 +673,7 @@ namespace ISX
|
|||
public void RemoveDevice(InputDevice device)
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException(nameof(device));
|
||||
throw new ArgumentNullException("device");
|
||||
|
||||
// If device has not been added, ignore.
|
||||
if (device.m_DeviceIndex == InputDevice.kInvalidDeviceIndex)
|
||||
|
@ -713,7 +722,7 @@ namespace ISX
|
|||
public InputDevice TryGetDevice(string nameOrTemplate)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nameOrTemplate))
|
||||
throw new ArgumentException(nameof(nameOrTemplate));
|
||||
throw new ArgumentException("nameOrTemplate");
|
||||
|
||||
if (m_Devices == null)
|
||||
return null;
|
||||
|
@ -735,7 +744,7 @@ namespace ISX
|
|||
{
|
||||
var device = TryGetDevice(nameOrTemplate);
|
||||
if (device == null)
|
||||
throw new Exception($"Cannot find device with name or template '{nameOrTemplate}'");
|
||||
throw new Exception(string.Format("Cannot find device with name or template '{0}'", nameOrTemplate));
|
||||
|
||||
return device;
|
||||
}
|
||||
|
@ -753,7 +762,7 @@ namespace ISX
|
|||
public int GetUnrecognizedDevices(List<InputDeviceDescription> descriptions)
|
||||
{
|
||||
if (descriptions == null)
|
||||
throw new ArgumentNullException(nameof(descriptions));
|
||||
throw new ArgumentNullException("descriptions");
|
||||
|
||||
var numFound = 0;
|
||||
for (var i = 0; i < m_AvailableDevices.Count; ++i)
|
||||
|
@ -777,7 +786,7 @@ namespace ISX
|
|||
string.IsNullOrEmpty(description.deviceClass))
|
||||
throw new ArgumentException(
|
||||
"Description must have at least one of 'product', 'manufacturer', or 'deviceClass'",
|
||||
nameof(description));
|
||||
"description");
|
||||
|
||||
var deviceId = NativeInputSystem.AllocateDeviceId();
|
||||
ReportAvailableDevice(description, deviceId);
|
||||
|
@ -1164,7 +1173,7 @@ namespace ISX
|
|||
if (m_Devices[i].name.ToLower() == nameLowerCase)
|
||||
{
|
||||
++namesTried;
|
||||
name = $"{device.name}{namesTried}";
|
||||
name = string.Format("{0}{1}", device.name, namesTried);
|
||||
nameLowerCase = name.ToLower();
|
||||
nameIsUnique = false;
|
||||
break;
|
||||
|
@ -1186,7 +1195,8 @@ namespace ISX
|
|||
var existingDeviceWithId = TryGetDeviceById(device.id);
|
||||
if (existingDeviceWithId != null)
|
||||
throw new Exception(
|
||||
$"Duplicate device ID {device.id} detected for devices '{device.name}' and '{existingDeviceWithId.name}'");
|
||||
string.Format("Duplicate device ID {0} detected for devices '{1}' and '{2}'", device.id,
|
||||
device.name, existingDeviceWithId.name));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1435,12 +1445,12 @@ namespace ISX
|
|||
|
||||
if (needToCopyFromBackBuffer)
|
||||
UnsafeUtility.MemCpy(
|
||||
buffer + (int)device.m_StateBlock.byteOffset,
|
||||
m_StateBuffers.m_EditorUpdateBuffers.GetBackBuffer(deviceIndex) +
|
||||
(int)device.m_StateBlock.byteOffset,
|
||||
new IntPtr(buffer.ToInt64() + (int)device.m_StateBlock.byteOffset),
|
||||
new IntPtr(m_StateBuffers.m_EditorUpdateBuffers.GetBackBuffer(deviceIndex).ToInt64() +
|
||||
(int)device.m_StateBlock.byteOffset),
|
||||
device.m_StateBlock.alignedSizeInBytes);
|
||||
|
||||
UnsafeUtility.MemCpy(buffer + (int)deviceStateOffset, statePtr, stateSize);
|
||||
UnsafeUtility.MemCpy(new IntPtr(buffer.ToInt64() + (int)deviceStateOffset), statePtr, stateSize);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -1458,12 +1468,12 @@ namespace ISX
|
|||
|
||||
if (needToCopyFromBackBuffer)
|
||||
UnsafeUtility.MemCpy(
|
||||
buffer + (int)device.m_StateBlock.byteOffset,
|
||||
m_StateBuffers.m_DynamicUpdateBuffers.GetBackBuffer(deviceIndex) +
|
||||
(int)device.m_StateBlock.byteOffset,
|
||||
new IntPtr(buffer.ToInt64() + (int)device.m_StateBlock.byteOffset),
|
||||
new IntPtr(m_StateBuffers.m_DynamicUpdateBuffers.GetBackBuffer(deviceIndex).ToInt64() +
|
||||
(int)device.m_StateBlock.byteOffset),
|
||||
device.m_StateBlock.alignedSizeInBytes);
|
||||
|
||||
UnsafeUtility.MemCpy(buffer + (int)deviceStateOffset, statePtr, stateSize);
|
||||
UnsafeUtility.MemCpy(new IntPtr(buffer.ToInt64() + (int)deviceStateOffset), statePtr, stateSize);
|
||||
}
|
||||
if (m_StateBuffers.m_FixedUpdateBuffers.valid)
|
||||
{
|
||||
|
@ -1472,12 +1482,12 @@ namespace ISX
|
|||
|
||||
if (needToCopyFromBackBuffer)
|
||||
UnsafeUtility.MemCpy(
|
||||
buffer + (int)device.m_StateBlock.byteOffset,
|
||||
m_StateBuffers.m_FixedUpdateBuffers.GetBackBuffer(deviceIndex) +
|
||||
(int)device.m_StateBlock.byteOffset,
|
||||
new IntPtr(buffer.ToInt64() + (int)device.m_StateBlock.byteOffset),
|
||||
new IntPtr(m_StateBuffers.m_FixedUpdateBuffers.GetBackBuffer(deviceIndex).ToInt64() +
|
||||
(int)device.m_StateBlock.byteOffset),
|
||||
device.m_StateBlock.alignedSizeInBytes);
|
||||
|
||||
UnsafeUtility.MemCpy(buffer + (int)deviceStateOffset, statePtr, stateSize);
|
||||
UnsafeUtility.MemCpy(new IntPtr(buffer.ToInt64() + (int)deviceStateOffset), statePtr, stateSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1573,8 +1583,8 @@ namespace ISX
|
|||
// them repeatedly.
|
||||
if (newStateOffset != 0)
|
||||
{
|
||||
newState -= (int)newStateOffset;
|
||||
oldState += (int)newStateOffset;
|
||||
newState = new IntPtr(newState.ToInt64() - newStateOffset);
|
||||
oldState = new IntPtr(oldState.ToInt64() + newStateOffset);
|
||||
}
|
||||
|
||||
for (var i = 0; i < numMonitors; ++i)
|
||||
|
@ -1604,8 +1614,8 @@ namespace ISX
|
|||
|
||||
//Debug.Log($"Bit {bitOffset} new={BitfieldHelpers.ReadSingleBit(newState+offset,bitOffset)} old={BitfieldHelpers.ReadSingleBit(oldState+offset, bitOffset)}");
|
||||
|
||||
if (BitfieldHelpers.ReadSingleBit(newState + offset, bitOffset) ==
|
||||
BitfieldHelpers.ReadSingleBit(oldState + offset, bitOffset))
|
||||
if (BitfieldHelpers.ReadSingleBit(new IntPtr(newState.ToInt64() + offset), bitOffset) ==
|
||||
BitfieldHelpers.ReadSingleBit(new IntPtr(oldState.ToInt64() + offset), bitOffset))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
@ -1616,7 +1626,7 @@ namespace ISX
|
|||
if (offset - newStateOffset + sizeInBytes > newStateSize)
|
||||
continue;
|
||||
|
||||
if (UnsafeUtility.MemCmp(newState + offset, oldState + offset, (int)sizeInBytes) == 0)
|
||||
if (UnsafeUtility.MemCmp(new IntPtr(newState.ToInt64() + offset), new IntPtr(oldState.ToInt64() + offset), (int)sizeInBytes) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1734,19 +1744,19 @@ namespace ISX
|
|||
|
||||
if (m_StateBuffers.m_DynamicUpdateBuffers.valid)
|
||||
{
|
||||
UnsafeUtility.MemClear(m_StateBuffers.m_DynamicUpdateBuffers.GetFrontBuffer(deviceIndex) + offset, sizeInBytes);
|
||||
UnsafeUtility.MemClear(m_StateBuffers.m_DynamicUpdateBuffers.GetBackBuffer(deviceIndex) + offset, sizeInBytes);
|
||||
UnsafeUtility.MemClear(new IntPtr(m_StateBuffers.m_DynamicUpdateBuffers.GetFrontBuffer(deviceIndex).ToInt64() + offset), sizeInBytes);
|
||||
UnsafeUtility.MemClear(new IntPtr(m_StateBuffers.m_DynamicUpdateBuffers.GetBackBuffer(deviceIndex).ToInt64() + offset), sizeInBytes);
|
||||
}
|
||||
|
||||
if (m_StateBuffers.m_FixedUpdateBuffers.valid)
|
||||
{
|
||||
UnsafeUtility.MemClear(m_StateBuffers.m_FixedUpdateBuffers.GetFrontBuffer(deviceIndex) + offset, sizeInBytes);
|
||||
UnsafeUtility.MemClear(m_StateBuffers.m_FixedUpdateBuffers.GetBackBuffer(deviceIndex) + offset, sizeInBytes);
|
||||
UnsafeUtility.MemClear(new IntPtr(m_StateBuffers.m_FixedUpdateBuffers.GetFrontBuffer(deviceIndex).ToInt64() + offset), sizeInBytes);
|
||||
UnsafeUtility.MemClear(new IntPtr(m_StateBuffers.m_FixedUpdateBuffers.GetBackBuffer(deviceIndex).ToInt64() + offset), sizeInBytes);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
UnsafeUtility.MemClear(m_StateBuffers.m_EditorUpdateBuffers.GetFrontBuffer(deviceIndex) + offset, sizeInBytes);
|
||||
UnsafeUtility.MemClear(m_StateBuffers.m_EditorUpdateBuffers.GetBackBuffer(deviceIndex) + offset, sizeInBytes);
|
||||
UnsafeUtility.MemClear(new IntPtr(m_StateBuffers.m_EditorUpdateBuffers.GetFrontBuffer(deviceIndex).ToInt64() + offset), sizeInBytes);
|
||||
UnsafeUtility.MemClear(new IntPtr(m_StateBuffers.m_EditorUpdateBuffers.GetBackBuffer(deviceIndex).ToInt64() + offset), sizeInBytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1891,7 +1901,7 @@ namespace ISX
|
|||
};
|
||||
|
||||
// Devices.
|
||||
var deviceCount = m_Devices?.Length ?? 0;
|
||||
var deviceCount = m_Devices != null ? m_Devices.Length : 0;
|
||||
var deviceArray = new DeviceState[deviceCount];
|
||||
for (i = 0; i < deviceCount; ++i)
|
||||
{
|
||||
|
@ -1969,7 +1979,8 @@ namespace ISX
|
|||
if (type != null)
|
||||
m_Templates.templateTypes[name] = type;
|
||||
else
|
||||
Debug.Log($"Input template '{template.name}' has been removed (type '{template.typeNameOrJson}' cannot be found)");
|
||||
Debug.Log(string.Format("Input template '{0}' has been removed (type '{1}' cannot be found)",
|
||||
template.name, template.typeNameOrJson));
|
||||
}
|
||||
|
||||
// Template strings.
|
||||
|
@ -1991,7 +2002,8 @@ namespace ISX
|
|||
var type = Type.GetType(template.typeName, false);
|
||||
if (type == null)
|
||||
{
|
||||
Debug.Log($"Template constructor '{name}' has been removed (type '{template.typeName}' cannot be found)");
|
||||
Debug.Log(string.Format("Template constructor '{0}' has been removed (type '{1}' cannot be found)",
|
||||
name, template.typeName));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2026,7 +2038,8 @@ namespace ISX
|
|||
if (type != null)
|
||||
m_Processors[name] = type;
|
||||
else
|
||||
Debug.Log($"Input processor '{processor.name}' has been removed (type '{processor.typeName}' cannot be found)");
|
||||
Debug.Log(string.Format("Input processor '{0}' has been removed (type '{1}' cannot be found)",
|
||||
processor.name, processor.typeName));
|
||||
}
|
||||
|
||||
// Modifiers.
|
||||
|
@ -2039,7 +2052,8 @@ namespace ISX
|
|||
if (type != null)
|
||||
m_Modifiers[name] = Type.GetType(modifier.typeName, true);
|
||||
else
|
||||
Debug.Log($"Input action modifier '{modifier.name}' has been removed (type '{modifier.typeName}' cannot be found)");
|
||||
Debug.Log(string.Format("Input action modifier '{0}' has been removed (type '{1}' cannot be found)",
|
||||
modifier.name, modifier.typeName));
|
||||
}
|
||||
|
||||
// Re-create devices.
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
using System;
|
||||
|
||||
////REVIEW: set up the plugin stuff such that if *nothing* is set up, we pull in whatever we got on the fly?
|
||||
|
||||
////REVIEW: move metadata like description and compatiable runtimes into attribute?
|
||||
|
||||
namespace ISX
|
||||
{
|
||||
public class InputModuleAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
////REVIEW: set up the plugin stuff such that if *nothing* is set up, we pull in whatever we got on the fly?
|
||||
|
||||
namespace ISX
|
||||
{
|
||||
/// <summary>
|
||||
/// Marks a class that initializes an input plugin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The class should be static and should have a <c>public static void Initialize()</c>
|
||||
/// method which performs any registration/initialization steps necessary for the module.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// [InputPlugin]
|
||||
/// public static class MyDeviceSupport
|
||||
/// {
|
||||
/// public static void Initialize()
|
||||
/// {
|
||||
/// InputSystem.RegisterTemplate<MyDevice>();
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class InputPluginAttribute : Attribute
|
||||
{
|
||||
public string description;
|
||||
public RuntimePlatform[] supportedPlatforms;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using UnityEngine;
|
||||
|
||||
|
@ -77,16 +78,17 @@ namespace ISX
|
|||
string baseTemplate = null, InputDeviceDescription? deviceDescription = null)
|
||||
{
|
||||
if (constructor == null)
|
||||
throw new ArgumentNullException(nameof(constructor));
|
||||
throw new ArgumentNullException("constructor");
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException(nameof(name));
|
||||
throw new ArgumentException("name");
|
||||
|
||||
// Grab method and (optional) instance from lambda expression.
|
||||
var methodCall = constructor.Body as MethodCallExpression;
|
||||
if (methodCall == null)
|
||||
throw new ArgumentException(
|
||||
$"Body of template constructor must be a method call (is a {constructor.Body.NodeType} instead)",
|
||||
nameof(constructor));
|
||||
string.Format("Body of template constructor must be a method call (is a {0} instead)",
|
||||
constructor.Body.NodeType),
|
||||
"constructor");
|
||||
|
||||
var method = methodCall.Method;
|
||||
var instance = methodCall.Object.NodeType == ExpressionType.Constant
|
||||
|
@ -158,7 +160,10 @@ namespace ISX
|
|||
|
||||
#region Devices
|
||||
|
||||
public static ReadOnlyArray<InputDevice> devices => s_Manager.devices;
|
||||
public static ReadOnlyArray<InputDevice> devices
|
||||
{
|
||||
get { return s_Manager.devices; }
|
||||
}
|
||||
|
||||
public static event Action<InputDevice, InputDeviceChange> onDeviceChange
|
||||
{
|
||||
|
@ -290,20 +295,22 @@ namespace ISX
|
|||
where TState : struct, IInputStateTypeInfo
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException(nameof(device));
|
||||
throw new ArgumentNullException("device");
|
||||
|
||||
// Make sure device is actually in the system.
|
||||
if (device.m_DeviceIndex == InputDevice.kInvalidDeviceIndex)
|
||||
throw new InvalidOperationException(
|
||||
$"Cannot queue state event device '{device}' because device has not been added to system");
|
||||
string.Format("Cannot queue state event device '{0}' because device has not been added to system",
|
||||
device));
|
||||
|
||||
////REVIEW: does it make more sense to go off the 'stateBlock' on the device and let that determine size?
|
||||
|
||||
var stateSize = UnsafeUtility.SizeOf<TState>();
|
||||
if (stateSize > StateEventBuffer.kMaxSize)
|
||||
throw new ArgumentException(
|
||||
$"Size of '{typeof(TState).Name}' exceeds maximum supported state size of {StateEventBuffer.kMaxSize}",
|
||||
nameof(state));
|
||||
string.Format("Size of '{0}' exceeds maximum supported state size of {1}", typeof(TState).Name,
|
||||
StateEventBuffer.kMaxSize),
|
||||
"state");
|
||||
var eventSize = UnsafeUtility.SizeOf<StateEvent>() + stateSize - 1;
|
||||
|
||||
if (time < 0)
|
||||
|
@ -336,16 +343,19 @@ namespace ISX
|
|||
where TDelta : struct
|
||||
{
|
||||
if (control == null)
|
||||
throw new ArgumentNullException(nameof(control));
|
||||
throw new ArgumentNullException("control");
|
||||
|
||||
if (control.stateBlock.bitOffset != 0)
|
||||
throw new InvalidOperationException($"Cannot send delta state events against bitfield controls: {control}");
|
||||
throw new InvalidOperationException(
|
||||
string.Format("Cannot send delta state events against bitfield controls: {0}", control));
|
||||
|
||||
// Make sure device is actually in the system.
|
||||
var device = control.device;
|
||||
if (device.m_DeviceIndex == InputDevice.kInvalidDeviceIndex)
|
||||
throw new InvalidOperationException(
|
||||
$"Cannot queue state event for control '{control}' on device '{device}' because device has not been added to system");
|
||||
string.Format(
|
||||
"Cannot queue state event for control '{0}' on device '{1}' because device has not been added to system",
|
||||
control, device));
|
||||
|
||||
if (time < 0)
|
||||
time = Time.time;
|
||||
|
@ -353,8 +363,9 @@ namespace ISX
|
|||
var deltaSize = UnsafeUtility.SizeOf<TDelta>();
|
||||
if (deltaSize > DeltaStateEventBuffer.kMaxSize)
|
||||
throw new ArgumentException(
|
||||
$"Size of state delta '{typeof(TDelta).Name}' exceeds maximum supported state size of {DeltaStateEventBuffer.kMaxSize}",
|
||||
nameof(delta));
|
||||
string.Format("Size of state delta '{0}' exceeds maximum supported state size of {1}",
|
||||
typeof(TDelta).Name, DeltaStateEventBuffer.kMaxSize),
|
||||
"delta");
|
||||
|
||||
////TODO: recognize a matching C# representation of a state format and convert to what we expect for trivial cases
|
||||
if (deltaSize != control.stateBlock.alignedSizeInBytes)
|
||||
|
@ -382,7 +393,7 @@ namespace ISX
|
|||
public static void QueueDisconnectEvent(InputDevice device, double time = -1)
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException(nameof(device));
|
||||
throw new ArgumentNullException("device");
|
||||
if (device.id == InputDevice.kInvalidDeviceId)
|
||||
throw new InvalidOperationException("Device has not been added");
|
||||
|
||||
|
@ -396,7 +407,7 @@ namespace ISX
|
|||
public static void QueueConnectEvent(InputDevice device, double time = -1)
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException(nameof(device));
|
||||
throw new ArgumentNullException("device");
|
||||
if (device.id == InputDevice.kInvalidDeviceId)
|
||||
throw new InvalidOperationException("Device has not been added");
|
||||
|
||||
|
@ -467,12 +478,32 @@ namespace ISX
|
|||
public static int FindAllEnabledActions(List<InputAction> actions)
|
||||
{
|
||||
if (actions == null)
|
||||
throw new ArgumentNullException(nameof(actions));
|
||||
throw new ArgumentNullException("actions");
|
||||
return InputActionSet.FindEnabledActions(actions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Plugins
|
||||
|
||||
private static IInputPlugin[] s_Plugins;
|
||||
|
||||
public static void RegisterPlugin(IInputPlugin plugin)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static void IntializeModules()
|
||||
{
|
||||
}
|
||||
|
||||
private static List<MethodInfo> ScanForInitializeMethods()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Remoting
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -71,6 +71,9 @@ namespace ISX
|
|||
Assert.Fail("Input system should not have devices after reset");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restore the state of the input system it had when the test was started.
|
||||
/// </summary>
|
||||
[TearDown]
|
||||
public virtual void TearDown()
|
||||
{
|
||||
|
|
|
@ -127,7 +127,10 @@ namespace ISX
|
|||
}
|
||||
}
|
||||
|
||||
public bool isBitfield => sizeInBits % 8 != 0;
|
||||
public bool isBitfield
|
||||
{
|
||||
get { return sizeInBits % 8 != 0; }
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum Flags
|
||||
|
@ -137,6 +140,9 @@ namespace ISX
|
|||
|
||||
private Flags m_Flags;
|
||||
|
||||
internal int alignedSizeInBytes => (int)(sizeInBits / 8) + (sizeInBits % 8 > 0 ? 1 : 0);
|
||||
internal int alignedSizeInBytes
|
||||
{
|
||||
get { return (int)(sizeInBits / 8) + (sizeInBits % 8 > 0 ? 1 : 0); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,10 @@ namespace ISX
|
|||
// has its buffers swapped individually with SwapDeviceBuffers().
|
||||
public void** deviceToBufferMapping;
|
||||
|
||||
public bool valid => deviceToBufferMapping != null;
|
||||
public bool valid
|
||||
{
|
||||
get { return deviceToBufferMapping != null; }
|
||||
}
|
||||
|
||||
public void SetFrontBuffer(int deviceIndex, IntPtr ptr)
|
||||
{
|
||||
|
@ -235,9 +238,9 @@ namespace ISX
|
|||
private unsafe DoubleBuffers SetUpDeviceToBufferMappings(InputDevice[] devices, ref IntPtr bufferPtr, int sizePerBuffer, int mappingTableSizePerBuffer)
|
||||
{
|
||||
var front = bufferPtr;
|
||||
var back = bufferPtr + sizePerBuffer;
|
||||
var mappings = (void**)(bufferPtr + sizePerBuffer * 2).ToPointer(); // Put mapping table at end.
|
||||
bufferPtr += sizePerBuffer * 2 + mappingTableSizePerBuffer;
|
||||
var back = new IntPtr(bufferPtr.ToInt64() + sizePerBuffer);
|
||||
var mappings = (void**)new IntPtr(bufferPtr.ToInt64() + sizePerBuffer * 2).ToPointer(); // Put mapping table at end.
|
||||
bufferPtr = new IntPtr(bufferPtr.ToInt64() + sizePerBuffer * 2 + mappingTableSizePerBuffer);
|
||||
|
||||
var buffers = new DoubleBuffers {deviceToBufferMapping = mappings};
|
||||
|
||||
|
@ -330,7 +333,7 @@ namespace ISX
|
|||
|
||||
// Migrate every device that has allocated state blocks.
|
||||
var newDeviceCount = devices.Length;
|
||||
var oldDeviceCount = oldDeviceIndices?.Length ?? newDeviceCount;
|
||||
var oldDeviceCount = oldDeviceIndices != null ? oldDeviceIndices.Length : newDeviceCount;
|
||||
for (var i = 0; i < newDeviceCount && i < oldDeviceCount; ++i)
|
||||
{
|
||||
var device = devices[i];
|
||||
|
@ -342,15 +345,15 @@ namespace ISX
|
|||
|
||||
////FIXME: this is not protecting against devices that have changed their formats between domain reloads
|
||||
|
||||
var oldDeviceIndex = oldDeviceIndices ? [i] ?? i;
|
||||
var oldDeviceIndex = oldDeviceIndices != null ? oldDeviceIndices[i] : i;
|
||||
var newDeviceIndex = i;
|
||||
var numBytes = device.m_StateBlock.alignedSizeInBytes;
|
||||
|
||||
var oldFrontPtr = oldBuffer.GetFrontBuffer(oldDeviceIndex) + (int)device.m_StateBlock.byteOffset;
|
||||
var oldBackPtr = oldBuffer.GetBackBuffer(oldDeviceIndex) + (int)device.m_StateBlock.byteOffset;
|
||||
var oldFrontPtr = new IntPtr(oldBuffer.GetFrontBuffer(oldDeviceIndex).ToInt64() + (int)device.m_StateBlock.byteOffset);
|
||||
var oldBackPtr = new IntPtr(oldBuffer.GetBackBuffer(oldDeviceIndex).ToInt64() + (int)device.m_StateBlock.byteOffset);
|
||||
|
||||
var newFrontPtr = newBuffer.GetFrontBuffer(newDeviceIndex) + (int)newStateBlockOffsets[i];
|
||||
var newBackPtr = newBuffer.GetBackBuffer(newDeviceIndex) + (int)newStateBlockOffsets[i];
|
||||
var newFrontPtr = new IntPtr(newBuffer.GetFrontBuffer(newDeviceIndex).ToInt64() + (int)newStateBlockOffsets[i]);
|
||||
var newBackPtr = new IntPtr(newBuffer.GetBackBuffer(newDeviceIndex).ToInt64() + (int)newStateBlockOffsets[i]);
|
||||
|
||||
// Copy state.
|
||||
UnsafeUtility.MemCpy(newFrontPtr, oldFrontPtr, numBytes);
|
||||
|
@ -376,7 +379,7 @@ namespace ISX
|
|||
var size = devices[i].m_StateBlock.alignedSizeInBytes;
|
||||
////REVIEW: what should we do about this case? silently accept it and just give the device the current offset?
|
||||
if (size == 0)
|
||||
throw new Exception($"Device '{devices[i]}' has a zero-size state buffer");
|
||||
throw new Exception(string.Format("Device '{0}' has a zero-size state buffer", devices[i]));
|
||||
sizeInBytes += size;
|
||||
result[i] = currentOffset;
|
||||
currentOffset += (uint)size;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ISX
|
||||
|
@ -39,7 +40,8 @@ namespace ISX
|
|||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"{(char)(m_Code>>24)}{(char)((m_Code&0xff0000)>>16)}{(char)((m_Code&0xff00)>>8)}{(char)(m_Code&0xff)}";
|
||||
string.Format("{0}{1}{2}{3}", (char)(m_Code >> 24), (char)((m_Code & 0xff0000) >> 16),
|
||||
(char)((m_Code & 0xff00) >> 8), (char)(m_Code & 0xff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace ISX
|
|||
return new InlinedArray<TValue>
|
||||
{
|
||||
firstValue = firstValue,
|
||||
additionalValues = (TValue[])additionalValues?.Clone()
|
||||
additionalValues = additionalValues != null ? (TValue[])additionalValues.Clone() : null
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,10 @@ namespace ISX
|
|||
private readonly string m_StringOriginalCase;
|
||||
private readonly string m_StringLowerCase;
|
||||
|
||||
public int length => m_StringLowerCase?.Length ?? 0;
|
||||
public int length
|
||||
{
|
||||
get { return m_StringLowerCase != null ? m_StringLowerCase.Length : 0; }
|
||||
}
|
||||
|
||||
public InternedString(string text)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
#if !NET_4_0
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
// Replacements for some of .NET 4 APIs to bridge us over to when we can switch the codebase
|
||||
// over to C# 6 and .NET 4 (and get rid of a ton of string.Formats and lots of new IntPtr()).
|
||||
|
||||
// NOTE: When switching fully back to 4, also:
|
||||
// - Get rid of all the .ToArray() expressions on string.Joins.
|
||||
|
||||
namespace ISX.Net35Compatibility
|
||||
{
|
||||
public interface IObservable<out T>
|
||||
{
|
||||
IDisposable Subscribe(IObserver<T> observer);
|
||||
}
|
||||
|
||||
public interface IObserver<in T>
|
||||
{
|
||||
void OnNext(T value);
|
||||
void OnCompleted();
|
||||
void OnError(Exception exception);
|
||||
}
|
||||
|
||||
public interface IReadOnlyList<T> : IEnumerable<T>
|
||||
{
|
||||
int Count { get; }
|
||||
T this[int index] { get; }
|
||||
}
|
||||
|
||||
internal static class Net35Compatibility
|
||||
{
|
||||
public static T GetCustomAttribute<T>(this MemberInfo element, bool inherit)
|
||||
where T : Attribute
|
||||
{
|
||||
if (element == null)
|
||||
throw new ArgumentNullException("element");
|
||||
|
||||
var attributes = element.GetCustomAttributes(typeof(T), inherit);
|
||||
|
||||
var numMatches = attributes.Length;
|
||||
if (numMatches == 0)
|
||||
return null;
|
||||
if (numMatches > 1)
|
||||
throw new AmbiguousMatchException();
|
||||
|
||||
return (T)attributes[0];
|
||||
}
|
||||
|
||||
public static IEnumerable<T> GetCustomAttributes<T>(this MemberInfo element, bool inherit)
|
||||
where T : Attribute
|
||||
{
|
||||
if (element == null)
|
||||
throw new ArgumentNullException("element");
|
||||
|
||||
var attributes = element.GetCustomAttributes(typeof(T), inherit);
|
||||
|
||||
foreach (var attribute in attributes)
|
||||
yield return (T)attribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !NET_4_0
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1cce3a5ef3f54cef82bece5d46ab5940
|
||||
timeCreated: 1511721701
|
|
@ -2,6 +2,10 @@ using System;
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if !NET_4_0
|
||||
using ISX.Net35Compatibility;
|
||||
#endif
|
||||
|
||||
namespace ISX
|
||||
{
|
||||
// Read-only access to an array. Additionally allows to expose only
|
||||
|
@ -49,7 +53,10 @@ namespace ISX
|
|||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public int Count => m_Length;
|
||||
public int Count
|
||||
{
|
||||
get { return m_Length; }
|
||||
}
|
||||
|
||||
public TValue this[int index]
|
||||
{
|
||||
|
@ -106,7 +113,10 @@ namespace ISX
|
|||
}
|
||||
}
|
||||
|
||||
object IEnumerator.Current => Current;
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get { return Current; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@ using System;
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if !NET_4_0
|
||||
using ISX.Net35Compatibility;
|
||||
#endif
|
||||
|
||||
namespace ISX
|
||||
{
|
||||
// Variation of ReadOnlyArray that has the slicing ability but
|
||||
|
@ -44,7 +48,10 @@ namespace ISX
|
|||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public int Count => m_Length;
|
||||
public int Count
|
||||
{
|
||||
get { return m_Length; }
|
||||
}
|
||||
|
||||
public TValue this[int index]
|
||||
{
|
||||
|
|
|
@ -99,8 +99,15 @@ namespace ISX
|
|||
return new Substring(s);
|
||||
}
|
||||
|
||||
public int length => m_Length;
|
||||
public int index => m_Index;
|
||||
public int length
|
||||
{
|
||||
get { return m_Length; }
|
||||
}
|
||||
|
||||
public int index
|
||||
{
|
||||
get { return m_Index; }
|
||||
}
|
||||
|
||||
public char this[int index]
|
||||
{
|
||||
|
|
|
@ -86,14 +86,24 @@ $(document).ready(function(){initNavTree('annotated.html','');});
|
|||
<div class="contents">
|
||||
<div class="textblock">Here are the classes, structs, unions and interfaces with brief descriptions:</div><div class="directory">
|
||||
<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span><span onclick="javascript:toggleLevel(3);">3</span>]</div><table class="directory">
|
||||
<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_i_s_x.html" target="_self">ISX</a></td><td class="desc"></td></tr>
|
||||
<tr id="row_0_0_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_i_s_x_1_1_gamepad.html" target="_self">Gamepad</a></td><td class="desc">An Xbox-style gamepad with two switcks, a D-Pad, four face buttons, two triggers, two shoulder buttons, and two menu buttons. </td></tr>
|
||||
<tr id="row_0_1_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_i_s_x_1_1_gamepad_state.html" target="_self">GamepadState</a></td><td class="desc">Default state layout gamepads. </td></tr>
|
||||
<tr id="row_0_2_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_i_s_x_1_1_input_device.html" target="_self">InputDevice</a></td><td class="desc">The root of a control hierarchy. </td></tr>
|
||||
<tr id="row_0_3_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_0_3_" class="arrow" onclick="toggleFolder('0_3_')">▼</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_i_s_x_1_1_input_remoting.html" target="_self">InputRemoting</a></td><td class="desc">Makes the activity and data of an InputManager observable in message form. </td></tr>
|
||||
<tr id="row_0_3_0_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_i_s_x_1_1_input_remoting_1_1_message.html" target="_self">Message</a></td><td class="desc">A message exchanged between two <a class="el" href="class_i_s_x_1_1_input_remoting.html" title="Makes the activity and data of an InputManager observable in message form. ">InputRemoting</a> instances. </td></tr>
|
||||
<tr id="row_0_4_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_i_s_x_1_1_input_system.html" target="_self">InputSystem</a></td><td class="desc">This is the central hub for the input system. </td></tr>
|
||||
<tr id="row_0_5_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_i_s_x_1_1_input_test_fixture.html" target="_self">InputTestFixture</a></td><td class="desc">A test fixture for writing tests that use the input system. Can be derived from or simply instantiated from another test fixture. </td></tr>
|
||||
<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceISX.html" target="_self">ISX</a></td><td class="desc"></td></tr>
|
||||
<tr id="row_0_0_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_0_0_" class="arrow" onclick="toggleFolder('0_0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceISX_1_1HID.html" target="_self">HID</a></td><td class="desc"></td></tr>
|
||||
<tr id="row_0_0_0_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classISX_1_1HID_1_1HID.html" target="_self">HID</a></td><td class="desc">A generic <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> input device. </td></tr>
|
||||
<tr id="row_0_0_1_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classISX_1_1HID_1_1HIDSupport.html" target="_self">HIDSupport</a></td><td class="desc">Adds support for generic <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> devices to the input system. </td></tr>
|
||||
<tr id="row_0_1_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classISX_1_1Gamepad.html" target="_self">Gamepad</a></td><td class="desc">An Xbox-style gamepad with two switcks, a D-Pad, four face buttons, two triggers, two shoulder buttons, and two menu buttons. </td></tr>
|
||||
<tr id="row_0_2_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="structISX_1_1GamepadState.html" target="_self">GamepadState</a></td><td class="desc">Default state layout gamepads. </td></tr>
|
||||
<tr id="row_0_3_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classISX_1_1InputControl.html" target="_self">InputControl</a></td><td class="desc">A typed and named value in a hierarchy of controls. </td></tr>
|
||||
<tr id="row_0_4_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classISX_1_1InputDevice.html" target="_self">InputDevice</a></td><td class="desc">The root of a control hierarchy. </td></tr>
|
||||
<tr id="row_0_5_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="structISX_1_1InputEvent.html" target="_self">InputEvent</a></td><td class="desc">A chunk of memory signaling a data transfer in the input system. </td></tr>
|
||||
<tr id="row_0_6_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="structISX_1_1InputEventBuffer.html" target="_self">InputEventBuffer</a></td><td class="desc">A buffer containing InputEvents. </td></tr>
|
||||
<tr id="row_0_7_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="structISX_1_1InputEventQueue.html" target="_self">InputEventQueue</a></td><td class="desc">An <a class="el" href="structISX_1_1InputEventBuffer.html" title="A buffer containing InputEvents. ">InputEventBuffer</a> that can be concurrently written to and read from in FIFO order. </td></tr>
|
||||
<tr id="row_0_8_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classISX_1_1InputPluginAttribute.html" target="_self">InputPluginAttribute</a></td><td class="desc">Marks a class that initializes an input plugin. </td></tr>
|
||||
<tr id="row_0_9_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_0_9_" class="arrow" onclick="toggleFolder('0_9_')">▼</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classISX_1_1InputRemoting.html" target="_self">InputRemoting</a></td><td class="desc">Makes the activity and data of an InputManager observable in message form. </td></tr>
|
||||
<tr id="row_0_9_0_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="structISX_1_1InputRemoting_1_1Message.html" target="_self">Message</a></td><td class="desc">A message exchanged between two <a class="el" href="classISX_1_1InputRemoting.html" title="Makes the activity and data of an InputManager observable in message form. ">InputRemoting</a> instances. </td></tr>
|
||||
<tr id="row_0_10_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classISX_1_1InputSystem.html" target="_self">InputSystem</a></td><td class="desc">This is the central hub for the input system. </td></tr>
|
||||
<tr id="row_0_11_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_0_11_" class="arrow" onclick="toggleFolder('0_11_')">▼</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classISX_1_1InputTemplate.html" target="_self">InputTemplate</a></td><td class="desc">A template lays out the composition of an input control. </td></tr>
|
||||
<tr id="row_0_11_0_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="structISX_1_1InputTemplate_1_1Builder.html" target="_self">Builder</a></td><td class="desc">Build a template programmatically. Primarily for use by template constructors registered with the system. </td></tr>
|
||||
<tr id="row_0_12_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classISX_1_1InputTestFixture.html" target="_self">InputTestFixture</a></td><td class="desc">A test fixture for writing tests that use the input system. Can be derived from or simply instantiated from another test fixture. </td></tr>
|
||||
</table>
|
||||
</div><!-- directory -->
|
||||
</div><!-- contents -->
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var annotated_dup =
|
||||
[
|
||||
[ "ISX", "namespace_i_s_x.html", "namespace_i_s_x" ]
|
||||
[ "ISX", "namespaceISX.html", "namespaceISX" ]
|
||||
];
|
|
@ -62,7 +62,7 @@ $(function() {
|
|||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){initNavTree('class_i_s_x_1_1_gamepad.html','');});
|
||||
$(document).ready(function(){initNavTree('classISX_1_1Gamepad.html','');});
|
||||
</script>
|
||||
<div id="doc-content">
|
||||
<!-- window showing the filter options -->
|
||||
|
@ -85,7 +85,7 @@ $(document).ready(function(){initNavTree('class_i_s_x_1_1_gamepad.html','');});
|
|||
</div><!--header-->
|
||||
<div class="contents">
|
||||
|
||||
<p>This is the complete list of members for <a class="el" href="class_i_s_x_1_1_gamepad.html">ISX.Gamepad</a>, including all inherited members.</p>
|
||||
<p>This is the complete list of members for <a class="el" href="classISX_1_1Gamepad.html">ISX.Gamepad</a>, including all inherited members.</p>
|
||||
<table class="directory">
|
||||
</table></div><!-- contents -->
|
||||
</div><!-- doc-content -->
|
|
@ -62,7 +62,7 @@ $(function() {
|
|||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){initNavTree('class_i_s_x_1_1_gamepad.html','');});
|
||||
$(document).ready(function(){initNavTree('classISX_1_1Gamepad.html','');});
|
||||
</script>
|
||||
<div id="doc-content">
|
||||
<!-- window showing the filter options -->
|
||||
|
@ -81,32 +81,33 @@ $(document).ready(function(){initNavTree('class_i_s_x_1_1_gamepad.html','');});
|
|||
|
||||
<div class="header">
|
||||
<div class="summary">
|
||||
<a href="class_i_s_x_1_1_gamepad-members.html">List of all members</a> </div>
|
||||
<a href="classISX_1_1Gamepad-members.html">List of all members</a> </div>
|
||||
<div class="headertitle">
|
||||
<div class="title">ISX.Gamepad Class Reference</div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
|
||||
<p>An Xbox-style gamepad with two switcks, a D-Pad, four face buttons, two triggers, two shoulder buttons, and two menu buttons.
|
||||
<a href="class_i_s_x_1_1_gamepad.html#details">More...</a></p>
|
||||
<a href="classISX_1_1Gamepad.html#details">More...</a></p>
|
||||
<div class="dynheader">
|
||||
Inheritance diagram for ISX.Gamepad:</div>
|
||||
<div class="dyncontent">
|
||||
<div class="center">
|
||||
<img src="class_i_s_x_1_1_gamepad.png" usemap="#ISX.Gamepad_map" alt=""/>
|
||||
<img src="classISX_1_1Gamepad.png" usemap="#ISX.Gamepad_map" alt=""/>
|
||||
<map id="ISX.Gamepad_map" name="ISX.Gamepad_map">
|
||||
<area href="class_i_s_x_1_1_input_device.html" title="The root of a control hierarchy. " alt="ISX.InputDevice" shape="rect" coords="0,0,103,24"/>
|
||||
<area href="classISX_1_1InputDevice.html" title="The root of a control hierarchy. " alt="ISX.InputDevice" shape="rect" coords="0,56,104,80"/>
|
||||
<area href="classISX_1_1InputControl.html" title="A typed and named value in a hierarchy of controls. " alt="ISX.InputControl" shape="rect" coords="0,0,104,24"/>
|
||||
</map>
|
||||
</div></div>
|
||||
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
|
||||
<div class="textblock"><p>An Xbox-style gamepad with two switcks, a D-Pad, four face buttons, two triggers, two shoulder buttons, and two menu buttons. </p>
|
||||
<dl class="section see"><dt>See also</dt><dd><a class="el" href="struct_i_s_x_1_1_gamepad_state.html" title="Default state layout gamepads. ">GamepadState</a></dd></dl>
|
||||
<dl class="section see"><dt>See also</dt><dd><a class="el" href="structISX_1_1GamepadState.html" title="Default state layout gamepads. ">GamepadState</a></dd></dl>
|
||||
</div></div><!-- contents -->
|
||||
</div><!-- doc-content -->
|
||||
<!-- start footer part -->
|
||||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
<li class="navelem"><a class="el" href="namespace_i_s_x.html">ISX</a></li><li class="navelem"><a class="el" href="class_i_s_x_1_1_gamepad.html">Gamepad</a></li>
|
||||
<li class="navelem"><a class="el" href="namespaceISX.html">ISX</a></li><li class="navelem"><a class="el" href="classISX_1_1Gamepad.html">Gamepad</a></li>
|
||||
<li class="footer">Generated by
|
||||
<a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.13 </li>
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 733 B |
|
@ -0,0 +1,101 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen 1.8.13"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>Input System: Member List</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="navtree.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="resize.js"></script>
|
||||
<script type="text/javascript" src="navtreedata.js"></script>
|
||||
<script type="text/javascript" src="navtree.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(initResizable);
|
||||
</script>
|
||||
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="search/searchdata.js"></script>
|
||||
<script type="text/javascript" src="search/search.js"></script>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<td id="projectalign" style="padding-left: 0.5em;">
|
||||
<div id="projectname">Input System
|
||||
 <span id="projectnumber">v0.1</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- end header part -->
|
||||
<!-- Generated by Doxygen 1.8.13 -->
|
||||
<script type="text/javascript">
|
||||
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
||||
</script>
|
||||
<script type="text/javascript" src="menudata.js"></script>
|
||||
<script type="text/javascript" src="menu.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
initMenu('',true,false,'search.php','Search');
|
||||
$(document).ready(function() { init_search(); });
|
||||
});
|
||||
</script>
|
||||
<div id="main-nav"></div>
|
||||
</div><!-- top -->
|
||||
<div id="side-nav" class="ui-resizable side-nav-resizable">
|
||||
<div id="nav-tree">
|
||||
<div id="nav-tree-contents">
|
||||
<div id="nav-sync" class="sync"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="splitbar" style="-moz-user-select:none;"
|
||||
class="ui-resizable-handle">
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){initNavTree('classISX_1_1HID_1_1HID.html','');});
|
||||
</script>
|
||||
<div id="doc-content">
|
||||
<!-- window showing the filter options -->
|
||||
<div id="MSearchSelectWindow"
|
||||
onmouseover="return searchBox.OnSearchSelectShow()"
|
||||
onmouseout="return searchBox.OnSearchSelectHide()"
|
||||
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
||||
</div>
|
||||
|
||||
<!-- iframe showing the search results (closed by default) -->
|
||||
<div id="MSearchResultsWindow">
|
||||
<iframe src="javascript:void(0)" frameborder="0"
|
||||
name="MSearchResults" id="MSearchResults">
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
<div class="header">
|
||||
<div class="headertitle">
|
||||
<div class="title">ISX.HID.HID Member List</div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
|
||||
<p>This is the complete list of members for <a class="el" href="classISX_1_1HID_1_1HID.html">ISX.HID.HID</a>, including all inherited members.</p>
|
||||
<table class="directory">
|
||||
</table></div><!-- contents -->
|
||||
</div><!-- doc-content -->
|
||||
<!-- start footer part -->
|
||||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
<li class="footer">Generated by
|
||||
<a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.13 </li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -5,7 +5,7 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen 1.8.13"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>Input System: ISX.Remote.InputRemoting Class Reference</title>
|
||||
<title>Input System: ISX.HID.HID Class Reference</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
|
@ -62,7 +62,7 @@ $(function() {
|
|||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){initNavTree('class_i_s_x_1_1_remote_1_1_input_remoting.html','');});
|
||||
$(document).ready(function(){initNavTree('classISX_1_1HID_1_1HID.html','');});
|
||||
</script>
|
||||
<div id="doc-content">
|
||||
<!-- window showing the filter options -->
|
||||
|
@ -81,25 +81,33 @@ $(document).ready(function(){initNavTree('class_i_s_x_1_1_remote_1_1_input_remot
|
|||
|
||||
<div class="header">
|
||||
<div class="summary">
|
||||
<a href="class_i_s_x_1_1_remote_1_1_input_remoting-members.html">List of all members</a> </div>
|
||||
<a href="classISX_1_1HID_1_1HID-members.html">List of all members</a> </div>
|
||||
<div class="headertitle">
|
||||
<div class="title">ISX.Remote.InputRemoting Class Reference</div> </div>
|
||||
<div class="title">ISX.HID.HID Class Reference</div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
|
||||
<p>Makes the activity and data of an InputManager observable in message form. Can act as both the sender and receiver of these message so the flow is fully bidirectional, i.e. the InputManager on either end can mirror its templates, devices, and events over to the other end. This permits streaming input not just from the player to the editor but also feeding input from the editor back into the player.
|
||||
<a href="class_i_s_x_1_1_remote_1_1_input_remoting.html#details">More...</a></p>
|
||||
|
||||
<p>Inherits IObservable< InputRemoting.Message >, and IObserver< InputRemoting.Message >.</p>
|
||||
<p>A generic <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> input device.
|
||||
<a href="classISX_1_1HID_1_1HID.html#details">More...</a></p>
|
||||
<div class="dynheader">
|
||||
Inheritance diagram for ISX.HID.HID:</div>
|
||||
<div class="dyncontent">
|
||||
<div class="center">
|
||||
<img src="classISX_1_1HID_1_1HID.png" usemap="#ISX.HID.HID_map" alt=""/>
|
||||
<map id="ISX.HID.HID_map" name="ISX.HID.HID_map">
|
||||
<area href="classISX_1_1InputDevice.html" title="The root of a control hierarchy. " alt="ISX.InputDevice" shape="rect" coords="0,56,104,80"/>
|
||||
<area href="classISX_1_1InputControl.html" title="A typed and named value in a hierarchy of controls. " alt="ISX.InputControl" shape="rect" coords="0,0,104,24"/>
|
||||
</map>
|
||||
</div></div>
|
||||
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
|
||||
<div class="textblock"><p>Makes the activity and data of an InputManager observable in message form. Can act as both the sender and receiver of these message so the flow is fully bidirectional, i.e. the InputManager on either end can mirror its templates, devices, and events over to the other end. This permits streaming input not just from the player to the editor but also feeding input from the editor back into the player. </p>
|
||||
<p>Remoting sits entirely on top of the input system as an optional piece of functionality. In development players and the editor, we enable it automatically but in non-development players it has to be explicitly requested by the user. </p>
|
||||
<div class="textblock"><p>A generic <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> input device. </p>
|
||||
<p>This class represents a best effort to mirror the control setup of a <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> discovered in the system. It is used only as a fallback where we cannot match the device to a specific product we know of. Wherever possible we construct more specific device representations such as <a class="el" href="classISX_1_1Gamepad.html" title="An Xbox-style gamepad with two switcks, a D-Pad, four face buttons, two triggers, two shoulder button...">Gamepad</a>. </p>
|
||||
</div></div><!-- contents -->
|
||||
</div><!-- doc-content -->
|
||||
<!-- start footer part -->
|
||||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
<li class="navelem"><a class="el" href="namespace_i_s_x.html">ISX</a></li><li class="navelem"><a class="el" href="namespace_i_s_x_1_1_remote.html">Remote</a></li><li class="navelem"><a class="el" href="class_i_s_x_1_1_remote_1_1_input_remoting.html">InputRemoting</a></li>
|
||||
<li class="navelem"><a class="el" href="namespaceISX.html">ISX</a></li><li class="navelem"><a class="el" href="namespaceISX_1_1HID.html">HID</a></li><li class="navelem"><a class="el" href="classISX_1_1HID_1_1HID.html">HID</a></li>
|
||||
<li class="footer">Generated by
|
||||
<a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.13 </li>
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 688 B |
|
@ -0,0 +1,102 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen 1.8.13"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>Input System: Member List</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="navtree.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="resize.js"></script>
|
||||
<script type="text/javascript" src="navtreedata.js"></script>
|
||||
<script type="text/javascript" src="navtree.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(initResizable);
|
||||
</script>
|
||||
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="search/searchdata.js"></script>
|
||||
<script type="text/javascript" src="search/search.js"></script>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<td id="projectalign" style="padding-left: 0.5em;">
|
||||
<div id="projectname">Input System
|
||||
 <span id="projectnumber">v0.1</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- end header part -->
|
||||
<!-- Generated by Doxygen 1.8.13 -->
|
||||
<script type="text/javascript">
|
||||
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
||||
</script>
|
||||
<script type="text/javascript" src="menudata.js"></script>
|
||||
<script type="text/javascript" src="menu.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
initMenu('',true,false,'search.php','Search');
|
||||
$(document).ready(function() { init_search(); });
|
||||
});
|
||||
</script>
|
||||
<div id="main-nav"></div>
|
||||
</div><!-- top -->
|
||||
<div id="side-nav" class="ui-resizable side-nav-resizable">
|
||||
<div id="nav-tree">
|
||||
<div id="nav-tree-contents">
|
||||
<div id="nav-sync" class="sync"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="splitbar" style="-moz-user-select:none;"
|
||||
class="ui-resizable-handle">
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){initNavTree('classISX_1_1HID_1_1HIDSupport.html','');});
|
||||
</script>
|
||||
<div id="doc-content">
|
||||
<!-- window showing the filter options -->
|
||||
<div id="MSearchSelectWindow"
|
||||
onmouseover="return searchBox.OnSearchSelectShow()"
|
||||
onmouseout="return searchBox.OnSearchSelectHide()"
|
||||
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
||||
</div>
|
||||
|
||||
<!-- iframe showing the search results (closed by default) -->
|
||||
<div id="MSearchResultsWindow">
|
||||
<iframe src="javascript:void(0)" frameborder="0"
|
||||
name="MSearchResults" id="MSearchResults">
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
<div class="header">
|
||||
<div class="headertitle">
|
||||
<div class="title">ISX.HID.HIDSupport Member List</div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
|
||||
<p>This is the complete list of members for <a class="el" href="classISX_1_1HID_1_1HIDSupport.html">ISX.HID.HIDSupport</a>, including all inherited members.</p>
|
||||
<table class="directory">
|
||||
<tr class="even"><td class="entry"><a class="el" href="classISX_1_1HID_1_1HIDSupport.html#aa2e9a0a6254844461347652dd980156a">Initialize</a>()</td><td class="entry"><a class="el" href="classISX_1_1HID_1_1HIDSupport.html">ISX.HID.HIDSupport</a></td><td class="entry"><span class="mlabel">static</span></td></tr>
|
||||
</table></div><!-- contents -->
|
||||
</div><!-- doc-content -->
|
||||
<!-- start footer part -->
|
||||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
<li class="footer">Generated by
|
||||
<a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.13 </li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -5,7 +5,7 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen 1.8.13"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>Input System: ISX.HID.HIDTests Class Reference</title>
|
||||
<title>Input System: ISX.HID.HIDSupport Class Reference</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
|
@ -62,7 +62,7 @@ $(function() {
|
|||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){initNavTree('class_i_s_x_1_1_h_i_d_1_1_h_i_d_tests.html','');});
|
||||
$(document).ready(function(){initNavTree('classISX_1_1HID_1_1HIDSupport.html','');});
|
||||
</script>
|
||||
<div id="doc-content">
|
||||
<!-- window showing the filter options -->
|
||||
|
@ -81,36 +81,29 @@ $(document).ready(function(){initNavTree('class_i_s_x_1_1_h_i_d_1_1_h_i_d_tests.
|
|||
|
||||
<div class="header">
|
||||
<div class="summary">
|
||||
<a href="#pub-methods">Public Member Functions</a> |
|
||||
<a href="class_i_s_x_1_1_h_i_d_1_1_h_i_d_tests-members.html">List of all members</a> </div>
|
||||
<a href="#pub-static-methods">Static Public Member Functions</a> |
|
||||
<a href="classISX_1_1HID_1_1HIDSupport-members.html">List of all members</a> </div>
|
||||
<div class="headertitle">
|
||||
<div class="title">ISX.HID.HIDTests Class Reference</div> </div>
|
||||
<div class="title">ISX.HID.HIDSupport Class Reference</div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
|
||||
<p>Tests for the <a class="el" href="namespace_i_s_x_1_1_h_i_d.html">HID</a> input support module.
|
||||
<a href="class_i_s_x_1_1_h_i_d_1_1_h_i_d_tests.html#details">More...</a></p>
|
||||
<div class="dynheader">
|
||||
Inheritance diagram for ISX.HID.HIDTests:</div>
|
||||
<div class="dyncontent">
|
||||
<div class="center">
|
||||
<img src="class_i_s_x_1_1_h_i_d_1_1_h_i_d_tests.png" usemap="#ISX.HID.HIDTests_map" alt=""/>
|
||||
<map id="ISX.HID.HIDTests_map" name="ISX.HID.HIDTests_map">
|
||||
<area href="class_i_s_x_1_1_input_test_fixture.html" title="A test fixture for writing tests that use the input system. Can be derived from or simply instantiate..." alt="ISX.InputTestFixture" shape="rect" coords="0,0,125,24"/>
|
||||
</map>
|
||||
</div></div>
|
||||
<p>Adds support for generic <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> devices to the input system.
|
||||
<a href="classISX_1_1HID_1_1HIDSupport.html#details">More...</a></p>
|
||||
<table class="memberdecls">
|
||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-methods"></a>
|
||||
Public Member Functions</h2></td></tr>
|
||||
<tr class="memitem:ab43aee320952f89b30bd2867e9f65deb"><td class="memItemLeft" align="right" valign="top">override void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_i_s_x_1_1_h_i_d_1_1_h_i_d_tests.html#ab43aee320952f89b30bd2867e9f65deb">Setup</a> ()</td></tr>
|
||||
<tr class="memdesc:ab43aee320952f89b30bd2867e9f65deb"><td class="mdescLeft"> </td><td class="mdescRight">Put <a class="el" href="class_i_s_x_1_1_input_system.html" title="This is the central API for the input system. ">InputSystem</a> into a known state where it only has a basic set of templates and does not have any input devices. <a href="#ab43aee320952f89b30bd2867e9f65deb">More...</a><br /></td></tr>
|
||||
<tr class="separator:ab43aee320952f89b30bd2867e9f65deb"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-static-methods"></a>
|
||||
Static Public Member Functions</h2></td></tr>
|
||||
<tr class="memitem:aa2e9a0a6254844461347652dd980156a"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="classISX_1_1HID_1_1HIDSupport.html#aa2e9a0a6254844461347652dd980156a">Initialize</a> ()</td></tr>
|
||||
<tr class="memdesc:aa2e9a0a6254844461347652dd980156a"><td class="mdescLeft"> </td><td class="mdescRight">Add support for generic HIDs to <a class="el" href="classISX_1_1InputSystem.html" title="This is the central hub for the input system. ">InputSystem</a>. <a href="#aa2e9a0a6254844461347652dd980156a">More...</a><br /></td></tr>
|
||||
<tr class="separator:aa2e9a0a6254844461347652dd980156a"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
</table>
|
||||
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
|
||||
<div class="textblock"><p>Tests for the <a class="el" href="namespace_i_s_x_1_1_h_i_d.html">HID</a> input support module. </p>
|
||||
<div class="textblock"><p>Adds support for generic <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> devices to the input system. </p>
|
||||
<p>Even without this module, HIDs can be used on platforms where we support <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> has a native backend (Windows and OSX, at the moment). However, each support <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> requires a template specifically targeting it as a product.</p>
|
||||
<p>What this module adds is the ability to turn any <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> with usable controls into an <a class="el" href="classISX_1_1InputDevice.html" title="The root of a control hierarchy. ">InputDevice</a>. It will make a best effort to figure out a suitable class for the device and will use the <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> elements present in the <a class="el" href="classISX_1_1HID_1_1HID.html" title="A generic HID input device. ">HID</a> descriptor to populate the device. </p>
|
||||
</div><h2 class="groupheader">Member Function Documentation</h2>
|
||||
<a id="ab43aee320952f89b30bd2867e9f65deb"></a>
|
||||
<h2 class="memtitle"><span class="permalink"><a href="#ab43aee320952f89b30bd2867e9f65deb">◆ </a></span>Setup()</h2>
|
||||
<a id="aa2e9a0a6254844461347652dd980156a"></a>
|
||||
<h2 class="memtitle"><span class="permalink"><a href="#aa2e9a0a6254844461347652dd980156a">◆ </a></span>Initialize()</h2>
|
||||
|
||||
<div class="memitem">
|
||||
<div class="memproto">
|
||||
|
@ -119,7 +112,7 @@ Public Member Functions</h2></td></tr>
|
|||
<td class="mlabels-left">
|
||||
<table class="memname">
|
||||
<tr>
|
||||
<td class="memname">override void ISX.HID.HIDTests.Setup </td>
|
||||
<td class="memname">static void ISX.HID.HIDSupport.Initialize </td>
|
||||
<td>(</td>
|
||||
<td class="paramname"></td><td>)</td>
|
||||
<td></td>
|
||||
|
@ -127,15 +120,12 @@ Public Member Functions</h2></td></tr>
|
|||
</table>
|
||||
</td>
|
||||
<td class="mlabels-right">
|
||||
<span class="mlabels"><span class="mlabel">virtual</span></span> </td>
|
||||
<span class="mlabels"><span class="mlabel">static</span></span> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</div><div class="memdoc">
|
||||
|
||||
<p>Put <a class="el" href="class_i_s_x_1_1_input_system.html" title="This is the central API for the input system. ">InputSystem</a> into a known state where it only has a basic set of templates and does not have any input devices. </p>
|
||||
<p>If you derive your own test fixture directly from <a class="el" href="class_i_s_x_1_1_input_test_fixture.html" title="A test fixture for writing tests that use the input system. Can be derived from or simply instantiate...">InputTestFixture</a>, this method will automatically be called. If you embed <a class="el" href="class_i_s_x_1_1_input_test_fixture.html" title="A test fixture for writing tests that use the input system. Can be derived from or simply instantiate...">InputTestFixture</a> into your fixture, you have to explicitly call this method yourself. </p>
|
||||
|
||||
<p>Reimplemented from <a class="el" href="class_i_s_x_1_1_input_test_fixture.html#ad8df73510739278c5c0e2023d43b4dae">ISX.InputTestFixture</a>.</p>
|
||||
<p>Add support for generic HIDs to <a class="el" href="classISX_1_1InputSystem.html" title="This is the central hub for the input system. ">InputSystem</a>. </p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -144,7 +134,7 @@ Public Member Functions</h2></td></tr>
|
|||
<!-- start footer part -->
|
||||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
<li class="navelem"><a class="el" href="namespace_i_s_x.html">ISX</a></li><li class="navelem"><a class="el" href="namespace_i_s_x_1_1_h_i_d.html">HID</a></li><li class="navelem"><a class="el" href="class_i_s_x_1_1_h_i_d_1_1_h_i_d_tests.html">HIDTests</a></li>
|
||||
<li class="navelem"><a class="el" href="namespaceISX.html">ISX</a></li><li class="navelem"><a class="el" href="namespaceISX_1_1HID.html">HID</a></li><li class="navelem"><a class="el" href="classISX_1_1HID_1_1HIDSupport.html">HIDSupport</a></li>
|
||||
<li class="footer">Generated by
|
||||
<a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.13 </li>
|
|
@ -0,0 +1,4 @@
|
|||
var classISX_1_1HID_1_1HIDSupport =
|
||||
[
|
||||
[ "Initialize", "classISX_1_1HID_1_1HIDSupport.html#aa2e9a0a6254844461347652dd980156a", null ]
|
||||
];
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче