You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
544 lines
29 KiB
544 lines
29 KiB
//========= Copyright 2016-2018, HTC Corporation. All rights reserved. =========== |
|
|
|
using HTC.UnityPlugin.Utility; |
|
using HTC.UnityPlugin.VRModuleManagement; |
|
using System; |
|
using UnityEngine; |
|
|
|
namespace HTC.UnityPlugin.Vive |
|
{ |
|
// Data structure for storing buttons status. |
|
public partial class ViveInput : SingletonBehaviour<ViveInput> |
|
{ |
|
public delegate void RoleEventListener<TRole>(TRole role, ControllerButton button, ButtonEventType eventType); |
|
public delegate void RoleValueEventListener(Type roleType, int roleValue, ControllerButton button, ButtonEventType eventType); |
|
|
|
private interface ICtrlState |
|
{ |
|
bool Update(); // return true if frame skipped |
|
void AddListener(ControllerButton button, Action listener, ButtonEventType type = ButtonEventType.Click); |
|
void RemoveListener(ControllerButton button, Action listener, ButtonEventType type = ButtonEventType.Click); |
|
void AddListener(ControllerButton button, RoleValueEventListener listener, ButtonEventType type = ButtonEventType.Click); |
|
void RemoveListener(ControllerButton button, RoleValueEventListener listener, ButtonEventType type = ButtonEventType.Click); |
|
bool GetPress(ControllerButton button, bool usePrevState = false); |
|
bool GetPressDown(ControllerButton button); |
|
bool GetPressUp(ControllerButton button); |
|
float LastPressDownTime(ControllerButton button); |
|
int ClickCount(ControllerButton button); |
|
float GetAxis(ControllerAxis axis, bool usePrevState = false); |
|
Vector2 GetPadAxis(bool usePrevState = false); |
|
Vector2 GetPadPressVector(); |
|
Vector2 GetPadTouchVector(); |
|
Vector2 GetScrollDelta(ScrollType scrollType, Vector2 scale, ControllerAxis xAxis = ControllerAxis.PadX, ControllerAxis yAxis = ControllerAxis.PadY); |
|
} |
|
|
|
private class CtrlState : ICtrlState |
|
{ |
|
public virtual bool Update() { return true; } // return true if frame skipped |
|
public virtual void AddListener(ControllerButton button, Action listener, ButtonEventType type = ButtonEventType.Click) { } |
|
public virtual void RemoveListener(ControllerButton button, Action listener, ButtonEventType type = ButtonEventType.Click) { } |
|
public virtual void AddListener(ControllerButton button, RoleValueEventListener listener, ButtonEventType type = ButtonEventType.Click) { } |
|
public virtual void RemoveListener(ControllerButton button, RoleValueEventListener listener, ButtonEventType type = ButtonEventType.Click) { } |
|
public virtual bool GetPress(ControllerButton button, bool usePrevState = false) { return false; } |
|
public virtual bool GetPressDown(ControllerButton button) { return false; } |
|
public virtual bool GetPressUp(ControllerButton button) { return false; } |
|
public virtual float LastPressDownTime(ControllerButton button) { return 0f; } |
|
public virtual int ClickCount(ControllerButton button) { return 0; } |
|
public virtual float GetAxis(ControllerAxis axis, bool usePrevState = false) { return 0f; } |
|
public virtual Vector2 GetPadAxis(bool usePrevState = false) { return Vector2.zero; } |
|
public virtual Vector2 GetPadPressVector() { return Vector2.zero; } |
|
public virtual Vector2 GetPadTouchVector() { return Vector2.zero; } |
|
public virtual Vector2 GetScrollDelta(ScrollType scrollType, Vector2 scale, ControllerAxis xAxis = ControllerAxis.PadX, ControllerAxis yAxis = ControllerAxis.PadY) { return Vector2.zero; } |
|
} |
|
|
|
private sealed class RCtrlState : CtrlState |
|
{ |
|
public readonly ViveRole.IMap m_map; |
|
public readonly int m_roleValue; |
|
public readonly Type m_roleEnumType; |
|
|
|
private int updatedFrameCount = -1; |
|
private uint prevDeviceIndex; |
|
private VRModuleDeviceModel trackedDeviceModel = VRModuleDeviceModel.Unknown; |
|
|
|
private uint prevButtonPressed; |
|
private uint currButtonPressed; |
|
|
|
private readonly float[] prevAxisValue = new float[CONTROLLER_AXIS_COUNT]; |
|
private readonly float[] currAxisValue = new float[CONTROLLER_AXIS_COUNT]; |
|
|
|
private readonly float[] lastPressDownTime = new float[CONTROLLER_BUTTON_COUNT]; |
|
private readonly int[] clickCount = new int[CONTROLLER_BUTTON_COUNT]; |
|
|
|
private Action[][] listeners; |
|
private RoleValueEventListener[][] typeListeners; |
|
|
|
private Vector2 padDownAxis; |
|
private Vector2 padTouchDownAxis; |
|
|
|
private const float hairDelta = 0.1f; // amount trigger must be pulled or released to change state |
|
private float hairTriggerLimit; |
|
|
|
public RCtrlState(Type roleEnumType, int roleValue) |
|
{ |
|
m_map = ViveRole.GetMap(roleEnumType); |
|
m_roleValue = roleValue; |
|
m_roleEnumType = roleEnumType; |
|
} |
|
|
|
// return true if frame skipped |
|
public override bool Update() |
|
{ |
|
if (!ChangeProp.Set(ref updatedFrameCount, Time.frameCount)) { return true; } |
|
|
|
var deviceIndex = m_map.GetMappedDeviceByRoleValue(m_roleValue); |
|
|
|
// treat this frame as updated if both prevDeviceIndex and currentDeviceIndex are invalid |
|
if (!VRModule.IsValidDeviceIndex(prevDeviceIndex) && !VRModule.IsValidDeviceIndex(deviceIndex)) { return false; } |
|
|
|
// get device state |
|
var currState = VRModule.GetCurrentDeviceState(deviceIndex); |
|
|
|
// copy to previous states |
|
prevDeviceIndex = deviceIndex; |
|
prevButtonPressed = currButtonPressed; |
|
for (int i = CONTROLLER_AXIS_COUNT - 1; i >= 0; --i) { prevAxisValue[i] = currAxisValue[i]; } |
|
|
|
trackedDeviceModel = currState.deviceModel; |
|
|
|
// update button states |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.System, currState.GetButtonPress(VRModuleRawButton.System)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Menu, currState.GetButtonPress(VRModuleRawButton.ApplicationMenu)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.MenuTouch, currState.GetButtonTouch(VRModuleRawButton.ApplicationMenu)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Trigger, currState.GetButtonPress(VRModuleRawButton.Trigger)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.TriggerTouch, currState.GetButtonTouch(VRModuleRawButton.Trigger)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Pad, currState.GetButtonPress(VRModuleRawButton.Touchpad)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.PadTouch, currState.GetButtonTouch(VRModuleRawButton.Touchpad)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Grip, currState.GetButtonPress(VRModuleRawButton.Grip)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.GripTouch, currState.GetButtonTouch(VRModuleRawButton.Grip)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.CapSenseGrip, currState.GetButtonPress(VRModuleRawButton.CapSenseGrip)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.CapSenseGripTouch, currState.GetButtonTouch(VRModuleRawButton.CapSenseGrip)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.AKey, currState.GetButtonPress(VRModuleRawButton.A)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.AKeyTouch, currState.GetButtonTouch(VRModuleRawButton.A)); |
|
|
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Axis3, currState.GetButtonPress(VRModuleRawButton.Axis3)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Axis3Touch, currState.GetButtonTouch(VRModuleRawButton.Axis3)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Axis4, currState.GetButtonPress(VRModuleRawButton.Axis4)); |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Axis4Touch, currState.GetButtonTouch(VRModuleRawButton.Axis4)); |
|
|
|
// update axis values |
|
currAxisValue[(int)ControllerAxis.PadX] = currState.GetAxisValue(VRModuleRawAxis.TouchpadX); |
|
currAxisValue[(int)ControllerAxis.PadY] = currState.GetAxisValue(VRModuleRawAxis.TouchpadY); |
|
currAxisValue[(int)ControllerAxis.Trigger] = currState.GetAxisValue(VRModuleRawAxis.Trigger); |
|
currAxisValue[(int)ControllerAxis.CapSenseGrip] = currState.GetAxisValue(VRModuleRawAxis.CapSenseGrip); |
|
currAxisValue[(int)ControllerAxis.IndexCurl] = currState.GetAxisValue(VRModuleRawAxis.IndexCurl); |
|
currAxisValue[(int)ControllerAxis.MiddleCurl] = currState.GetAxisValue(VRModuleRawAxis.MiddleCurl); |
|
currAxisValue[(int)ControllerAxis.RingCurl] = currState.GetAxisValue(VRModuleRawAxis.RingCurl); |
|
currAxisValue[(int)ControllerAxis.PinkyCurl] = currState.GetAxisValue(VRModuleRawAxis.PinkyCurl); |
|
|
|
// update hair trigger |
|
var currTriggerValue = currAxisValue[(int)ControllerAxis.Trigger]; |
|
|
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.FullTrigger, currTriggerValue == 1f); |
|
if (EnumUtils.GetFlag(prevButtonPressed, (int)ControllerButton.HairTrigger)) |
|
{ |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.HairTrigger, currTriggerValue >= (hairTriggerLimit - hairDelta) && currTriggerValue > 0.0f); |
|
} |
|
else |
|
{ |
|
EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.HairTrigger, currTriggerValue > (hairTriggerLimit + hairDelta) || currTriggerValue >= 1.0f); |
|
} |
|
|
|
if (EnumUtils.GetFlag(currButtonPressed, (int)ControllerButton.HairTrigger)) |
|
{ |
|
hairTriggerLimit = Mathf.Max(hairTriggerLimit, currTriggerValue); |
|
} |
|
else |
|
{ |
|
hairTriggerLimit = Mathf.Min(hairTriggerLimit, currTriggerValue); |
|
} |
|
|
|
// record pad down axis values |
|
if (GetPressDown(ControllerButton.Pad)) |
|
{ |
|
padDownAxis = new Vector2(currAxisValue[(int)ControllerAxis.PadX], currAxisValue[(int)ControllerAxis.PadY]); |
|
} |
|
|
|
if (GetPressDown(ControllerButton.PadTouch)) |
|
{ |
|
padTouchDownAxis = new Vector2(currAxisValue[(int)ControllerAxis.PadX], currAxisValue[(int)ControllerAxis.PadY]); |
|
} |
|
|
|
// record press down time and click count |
|
var timeNow = Time.unscaledTime; |
|
for (int button = 0; button < CONTROLLER_BUTTON_COUNT; ++button) |
|
{ |
|
if (GetPressDown((ControllerButton)button)) |
|
{ |
|
if (timeNow - lastPressDownTime[button] < clickInterval) |
|
{ |
|
++clickCount[button]; |
|
} |
|
else |
|
{ |
|
clickCount[button] = 1; |
|
} |
|
|
|
lastPressDownTime[button] = timeNow; |
|
} |
|
} |
|
|
|
// invoke event listeners |
|
for (ControllerButton button = 0; button < (ControllerButton)CONTROLLER_BUTTON_COUNT; ++button) |
|
{ |
|
if (GetPress(button)) |
|
{ |
|
if (GetPressDown(button)) |
|
{ |
|
// PressDown event |
|
TryInvokeListener(button, ButtonEventType.Down); |
|
TryInvokeTypeListener(button, ButtonEventType.Down); |
|
} |
|
|
|
// Press event |
|
TryInvokeListener(button, ButtonEventType.Press); |
|
TryInvokeTypeListener(button, ButtonEventType.Press); |
|
} |
|
else if (GetPressUp(button)) |
|
{ |
|
// PressUp event |
|
TryInvokeListener(button, ButtonEventType.Up); |
|
TryInvokeTypeListener(button, ButtonEventType.Up); |
|
|
|
if (timeNow - lastPressDownTime[(int)button] < clickInterval) |
|
{ |
|
// Click event |
|
TryInvokeListener(button, ButtonEventType.Click); |
|
TryInvokeTypeListener(button, ButtonEventType.Click); |
|
} |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
private void TryInvokeListener(ControllerButton button, ButtonEventType type) |
|
{ |
|
if (listeners == null) { return; } |
|
if (listeners[(int)button] == null) { return; } |
|
if (listeners[(int)button][(int)type] == null) { return; } |
|
listeners[(int)button][(int)type].Invoke(); |
|
} |
|
|
|
public override void AddListener(ControllerButton button, Action listener, ButtonEventType type = ButtonEventType.Click) |
|
{ |
|
if (listeners == null) { listeners = new Action[CONTROLLER_BUTTON_COUNT][]; } |
|
if (listeners[(int)button] == null) { listeners[(int)button] = new Action[BUTTON_EVENT_COUNT]; } |
|
if (listeners[(int)button][(int)type] == null) |
|
{ |
|
listeners[(int)button][(int)type] = listener; |
|
} |
|
else |
|
{ |
|
listeners[(int)button][(int)type] += listener; |
|
} |
|
} |
|
|
|
public override void RemoveListener(ControllerButton button, Action listener, ButtonEventType type = ButtonEventType.Click) |
|
{ |
|
if (listeners == null) { return; } |
|
if (listeners[(int)button] == null) { return; } |
|
if (listeners[(int)button][(int)type] == null) { return; } |
|
listeners[(int)button][(int)type] -= listener; |
|
} |
|
|
|
private void TryInvokeTypeListener(ControllerButton button, ButtonEventType type) |
|
{ |
|
if (typeListeners == null) { return; } |
|
if (typeListeners[(int)button] == null) { return; } |
|
if (typeListeners[(int)button][(int)type] == null) { return; } |
|
typeListeners[(int)button][(int)type].Invoke(m_roleEnumType, m_roleValue, button, type); |
|
} |
|
|
|
public override void AddListener(ControllerButton button, RoleValueEventListener listener, ButtonEventType type = ButtonEventType.Click) |
|
{ |
|
if (typeListeners == null) { typeListeners = new RoleValueEventListener[CONTROLLER_BUTTON_COUNT][]; } |
|
if (typeListeners[(int)button] == null) { typeListeners[(int)button] = new RoleValueEventListener[BUTTON_EVENT_COUNT]; } |
|
if (typeListeners[(int)button][(int)type] == null) |
|
{ |
|
typeListeners[(int)button][(int)type] = listener; |
|
} |
|
else |
|
{ |
|
typeListeners[(int)button][(int)type] += listener; |
|
} |
|
} |
|
|
|
public override void RemoveListener(ControllerButton button, RoleValueEventListener listener, ButtonEventType type = ButtonEventType.Click) |
|
{ |
|
if (typeListeners == null) { return; } |
|
if (typeListeners[(int)button] == null) { return; } |
|
if (typeListeners[(int)button][(int)type] == null) { return; } |
|
typeListeners[(int)button][(int)type] -= listener; |
|
} |
|
|
|
public override bool GetPress(ControllerButton button, bool usePrevState = false) |
|
{ |
|
return IsValidButton(button) && EnumUtils.GetFlag(usePrevState ? prevButtonPressed : currButtonPressed, (int)button); |
|
} |
|
|
|
public override bool GetPressDown(ControllerButton button) |
|
{ |
|
return IsValidButton(button) && !EnumUtils.GetFlag(prevButtonPressed, (int)button) && EnumUtils.GetFlag(currButtonPressed, (int)button); |
|
} |
|
|
|
public override bool GetPressUp(ControllerButton button) |
|
{ |
|
return IsValidButton(button) && EnumUtils.GetFlag(prevButtonPressed, (int)button) && !EnumUtils.GetFlag(currButtonPressed, (int)button); |
|
} |
|
|
|
public override float LastPressDownTime(ControllerButton button) |
|
{ |
|
return IsValidButton(button) ? lastPressDownTime[(int)button] : 0f; |
|
} |
|
|
|
public override int ClickCount(ControllerButton button) |
|
{ |
|
return IsValidButton(button) ? clickCount[(int)button] : 0; |
|
} |
|
|
|
public override float GetAxis(ControllerAxis axis, bool usePrevState = false) |
|
{ |
|
if (IsValidAxis(axis)) |
|
{ |
|
return usePrevState ? prevAxisValue[(int)axis] : currAxisValue[(int)axis]; |
|
} |
|
else |
|
{ |
|
return 0f; |
|
} |
|
} |
|
|
|
public override Vector2 GetPadAxis(bool usePrevState = false) |
|
{ |
|
if (usePrevState) |
|
{ |
|
return new Vector2(prevAxisValue[(int)ControllerAxis.PadX], prevAxisValue[(int)ControllerAxis.PadY]); |
|
} |
|
else |
|
{ |
|
return new Vector2(currAxisValue[(int)ControllerAxis.PadX], currAxisValue[(int)ControllerAxis.PadY]); |
|
} |
|
} |
|
|
|
public override Vector2 GetPadPressVector() |
|
{ |
|
return GetPress(ControllerButton.Pad) ? (GetPadAxis() - padDownAxis) : Vector2.zero; |
|
} |
|
|
|
public override Vector2 GetPadTouchVector() |
|
{ |
|
return GetPress(ControllerButton.PadTouch) ? (GetPadAxis() - padTouchDownAxis) : Vector2.zero; |
|
} |
|
|
|
public override Vector2 GetScrollDelta(ScrollType scrollType, Vector2 scale, ControllerAxis xAxis = ControllerAxis.PadX, ControllerAxis yAxis = ControllerAxis.PadY) |
|
{ |
|
if (scrollType == ScrollType.None) { return Vector2.zero; } |
|
|
|
// consider scroll mode depends on whitch device platform useed |
|
// OpenVR: finger dragging on the trackpad to scroll, drag faster to scroll faster |
|
// Oculus: leaning the thumbstick to scroll, lean larger angle to scroll faster |
|
ScrollType mode; |
|
if (scrollType == ScrollType.Auto) |
|
{ |
|
switch (trackedDeviceModel) |
|
{ |
|
case VRModuleDeviceModel.KnucklesLeft: |
|
case VRModuleDeviceModel.KnucklesRight: |
|
case VRModuleDeviceModel.ViveController: |
|
case VRModuleDeviceModel.DaydreamController: |
|
case VRModuleDeviceModel.ViveFocusFinch: |
|
mode = ScrollType.Trackpad; break; |
|
case VRModuleDeviceModel.OculusTouchLeft: |
|
case VRModuleDeviceModel.OculusTouchRight: |
|
mode = ScrollType.Thumbstick; break; |
|
default: |
|
mode = ScrollType.None; break; |
|
} |
|
} |
|
else |
|
{ |
|
mode = scrollType; |
|
} |
|
|
|
Vector2 scrollDelta; |
|
switch (mode) |
|
{ |
|
case ScrollType.Trackpad: |
|
{ |
|
var prevX = GetAxis(xAxis, true); |
|
var prevY = GetAxis(yAxis, true); |
|
var currX = GetAxis(xAxis, false); |
|
var currY = GetAxis(yAxis, false); |
|
|
|
// filter out invalid axis values |
|
// assume that valid axis value is never zero |
|
// note: don't know why sometimes even trackpad touched (GetKey(Trackpad)==true), GetAxis(Trackpad) still get zero values |
|
if ((prevX == 0f && prevY == 0f) || (currX == 0f && currY == 0f)) |
|
{ |
|
return Vector2.zero; |
|
} |
|
else |
|
{ |
|
scrollDelta = new Vector2(prevX - currX, prevY - currY) * 50f; |
|
} |
|
|
|
break; |
|
} |
|
case ScrollType.Thumbstick: |
|
{ |
|
var currX = GetAxis(xAxis, false); |
|
var currY = GetAxis(yAxis, false); |
|
|
|
scrollDelta = new Vector2(currX, currY) * 5f; |
|
|
|
break; |
|
} |
|
default: |
|
return Vector2.zero; |
|
} |
|
|
|
return Vector2.Scale(scrollDelta, scale); |
|
} |
|
} |
|
|
|
private interface ICtrlState<TRole> : ICtrlState |
|
{ |
|
void AddListener(ControllerButton button, RoleEventListener<TRole> listener, ButtonEventType type = ButtonEventType.Click); |
|
void RemoveListener(ControllerButton button, RoleEventListener<TRole> listener, ButtonEventType type = ButtonEventType.Click); |
|
} |
|
|
|
private class GCtrlState<TRole> : ICtrlState<TRole> |
|
{ |
|
public virtual bool Update() { return true; } // return true if frame skipped |
|
public virtual void AddListener(ControllerButton button, Action listener, ButtonEventType type = ButtonEventType.Click) { } |
|
public virtual void RemoveListener(ControllerButton button, Action listener, ButtonEventType type = ButtonEventType.Click) { } |
|
public virtual void AddListener(ControllerButton button, RoleValueEventListener listener, ButtonEventType type = ButtonEventType.Click) { } |
|
public virtual void RemoveListener(ControllerButton button, RoleValueEventListener listener, ButtonEventType type = ButtonEventType.Click) { } |
|
public virtual bool GetPress(ControllerButton button, bool usePrevState = false) { return false; } |
|
public virtual bool GetPressDown(ControllerButton button) { return false; } |
|
public virtual bool GetPressUp(ControllerButton button) { return false; } |
|
public virtual float LastPressDownTime(ControllerButton button) { return 0f; } |
|
public virtual int ClickCount(ControllerButton button) { return 0; } |
|
public virtual float GetAxis(ControllerAxis axis, bool usePrevState = false) { return 0f; } |
|
public virtual Vector2 GetPadAxis(bool usePrevState = false) { return Vector2.zero; } |
|
public virtual Vector2 GetPadPressVector() { return Vector2.zero; } |
|
public virtual Vector2 GetPadTouchVector() { return Vector2.zero; } |
|
public virtual Vector2 GetScrollDelta(ScrollType scrollType, Vector2 scale, ControllerAxis xAxis = ControllerAxis.PadX, ControllerAxis yAxis = ControllerAxis.PadY) { return Vector2.zero; } |
|
|
|
public virtual void AddListener(ControllerButton button, RoleEventListener<TRole> listener, ButtonEventType type = ButtonEventType.Click) { } |
|
public virtual void RemoveListener(ControllerButton button, RoleEventListener<TRole> listener, ButtonEventType type = ButtonEventType.Click) { } |
|
|
|
protected virtual void InvokeEvent(ControllerButton button) { } |
|
protected virtual void TryInvokeListener(ControllerButton button, ButtonEventType type) { } |
|
} |
|
|
|
private sealed class RGCtrolState<TRole> : GCtrlState<TRole> |
|
{ |
|
public readonly static GCtrlState<TRole> s_defaultState = new GCtrlState<TRole>(); |
|
public static RGCtrolState<TRole>[] s_roleStates; |
|
|
|
private readonly ICtrlState m_state; |
|
private readonly TRole m_role; |
|
|
|
private RoleEventListener<TRole>[][] listeners; |
|
|
|
public RGCtrolState(TRole role) |
|
{ |
|
var info = ViveRoleEnum.GetInfo<TRole>(); |
|
m_state = GetState(typeof(TRole), info.ToRoleValue(role)); |
|
m_role = role; |
|
} |
|
|
|
// return true if frame skipped |
|
public override bool Update() |
|
{ |
|
if (m_state.Update()) { return true; } |
|
|
|
var timeNow = Time.unscaledTime; |
|
for (ControllerButton button = 0; button < (ControllerButton)CONTROLLER_BUTTON_COUNT; ++button) |
|
{ |
|
if (GetPress(button)) |
|
{ |
|
if (GetPressDown(button)) |
|
{ |
|
// PressDown event |
|
TryInvokeListener(button, ButtonEventType.Down); |
|
} |
|
|
|
// Press event |
|
TryInvokeListener(button, ButtonEventType.Press); |
|
} |
|
else if (GetPressUp(button)) |
|
{ |
|
// PressUp event |
|
TryInvokeListener(button, ButtonEventType.Up); |
|
|
|
if (timeNow - m_state.LastPressDownTime(button) < clickInterval) |
|
{ |
|
// Click event |
|
TryInvokeListener(button, ButtonEventType.Click); |
|
} |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
public override void AddListener(ControllerButton button, Action listener, ButtonEventType type = ButtonEventType.Click) { m_state.AddListener(button, listener, type); } |
|
public override void RemoveListener(ControllerButton button, Action listener, ButtonEventType type = ButtonEventType.Click) { m_state.RemoveListener(button, listener, type); } |
|
public override void AddListener(ControllerButton button, RoleValueEventListener listener, ButtonEventType type = ButtonEventType.Click) { m_state.AddListener(button, listener, type); } |
|
public override void RemoveListener(ControllerButton button, RoleValueEventListener listener, ButtonEventType type = ButtonEventType.Click) { m_state.RemoveListener(button, listener, type); } |
|
public override bool GetPress(ControllerButton button, bool usePrevState = false) { return m_state.GetPress(button, usePrevState); } |
|
public override bool GetPressDown(ControllerButton button) { return m_state.GetPressDown(button); } |
|
public override bool GetPressUp(ControllerButton button) { return m_state.GetPressUp(button); } |
|
public override float LastPressDownTime(ControllerButton button) { return m_state.LastPressDownTime(button); } |
|
public override int ClickCount(ControllerButton button) { return m_state.ClickCount(button); } |
|
public override float GetAxis(ControllerAxis axis, bool usePrevState = false) { return m_state.GetAxis(axis, usePrevState); } |
|
public override Vector2 GetPadAxis(bool usePrevState = false) { return m_state.GetPadAxis(usePrevState); } |
|
public override Vector2 GetPadPressVector() { return m_state.GetPadPressVector(); } |
|
public override Vector2 GetPadTouchVector() { return m_state.GetPadTouchVector(); } |
|
public override Vector2 GetScrollDelta(ScrollType scrollType, Vector2 scale, ControllerAxis xAxis = ControllerAxis.PadX, ControllerAxis yAxis = ControllerAxis.PadY) { return m_state.GetScrollDelta(scrollType, scale, xAxis, yAxis); } |
|
|
|
protected override void TryInvokeListener(ControllerButton button, ButtonEventType type) |
|
{ |
|
if (listeners == null) { return; } |
|
if (listeners[(int)button] == null) { return; } |
|
if (listeners[(int)button][(int)type] == null) { return; } |
|
listeners[(int)button][(int)type].Invoke(m_role, button, type); |
|
} |
|
|
|
public override void AddListener(ControllerButton button, RoleEventListener<TRole> listener, ButtonEventType type = ButtonEventType.Click) |
|
{ |
|
if (listeners == null) { listeners = new RoleEventListener<TRole>[CONTROLLER_BUTTON_COUNT][]; } |
|
if (listeners[(int)button] == null) { listeners[(int)button] = new RoleEventListener<TRole>[BUTTON_EVENT_COUNT]; } |
|
if (listeners[(int)button][(int)type] == null) |
|
{ |
|
listeners[(int)button][(int)type] = listener; |
|
} |
|
else |
|
{ |
|
listeners[(int)button][(int)type] += listener; |
|
} |
|
} |
|
|
|
public override void RemoveListener(ControllerButton button, RoleEventListener<TRole> listener, ButtonEventType type = ButtonEventType.Click) |
|
{ |
|
if (listeners == null) { return; } |
|
if (listeners[(int)button] == null) { return; } |
|
if (listeners[(int)button][(int)type] == null) { return; } |
|
listeners[(int)button][(int)type] -= listener; |
|
} |
|
} |
|
} |
|
} |