using AxibugEmuOnline.Client.ClientCore; using AxibugEmuOnline.Client.Event; using AxiInputSP.UGUI; using System; using System.Collections.Generic; using UnityEngine; namespace AxibugEmuOnline.Client.InputDevices { public abstract class InputResolver { public static InputResolver Create() { #if ENABLE_INPUT_SYSTEM //InputSystem return new ForInputSystem.InputSystemResolver(); #elif UNITY_PSP2 //特化实现 return new ForPSV.PSVResolver(); #elif UNITY_PS3 //SDK throw new System.NotImplementedException(); #else throw new System.NotImplementedException(); #endif } DualWayDictionary m_devices = new DualWayDictionary(); /// 禁止外部构造 protected InputResolver() { AxiScreenGamepad.OnGamepadActive += AxiScreenGamepad_OnGamepadActive; AxiScreenGamepad.OnGamepadDisactive += AxiScreenGamepad_OnGamepadDisactive; Eventer.Instance.RegisterEvent(EEvent.OnEmuBeginGame, OnEmuBeginGame); OnInit(); } private void OnEmuBeginGame() { ClearLastCheckPerformingValue(); } private void AxiScreenGamepad_OnGamepadDisactive(AxiScreenGamepad sender) { if (m_devices.TryGetValue(sender, out var device)) { m_devices.Remove(sender); RaiseDeviceLost(device); } } private void AxiScreenGamepad_OnGamepadActive(AxiScreenGamepad sender) { var newDevice = new ScreenGamepad_D(sender, this); m_devices[sender] = newDevice; RaiseDeviceConnected(newDevice); } protected abstract void OnInit(); List m_devicesResultCache = new List(); /// /// 获得所有当前已连入的输入设备 /// /// public List GetDevices() { m_devicesResultCache.Clear(); m_devicesResultCache.AddRange(m_devices.Values); m_devicesResultCache.AddRange(OnGetDevices()); return m_devicesResultCache; } /// protected abstract IEnumerable OnGetDevices(); /// 检查指定输入设备是否还保持着连接 public bool CheckOnline(InputDevice_D device) { if (device is ScreenGamepad_D) { return m_devices.TryGetKey(device as ScreenGamepad_D, out var _); } else { return OnCheckOnline(device); } } /// protected abstract bool OnCheckOnline(InputDevice_D device); /// 丢失的设备 public delegate void OnDeviceLostHandle(InputDevice_D lostDevice); /// 当设备丢失时触发 public event OnDeviceLostHandle OnDeviceLost; protected void RaiseDeviceLost(InputDevice_D lostDevice) { OnDeviceLost?.Invoke(lostDevice); } /// 建立连接的设备 public delegate void OnDeviceConnectedHandle(InputDevice_D connectDevice); /// 当设备连接时触发 public event OnDeviceConnectedHandle OnDeviceConnected; protected void RaiseDeviceConnected(InputDevice_D connectDevice) { OnDeviceConnected?.Invoke(connectDevice); } long last_CheckPerformingFrameIdx = -100; bool last_CheckPerformingValue = false; void ClearLastCheckPerformingValue() { last_CheckPerformingFrameIdx = -100; last_CheckPerformingValue = false; } public bool CheckPerforming(CONTROLLER control) where CONTROLLER : InputControl_C { //减少遍历开销,因为每帧200+次的调用 居然CPU占用了2~3% if (App.emu?.Core == null || last_CheckPerformingFrameIdx != App.emu.Core.Frame) { if (control.Device is ScreenGamepad_D) { ScreenGamepad_D device = control.Device as ScreenGamepad_D; last_CheckPerformingValue = device.CheckPerforming(control); } else last_CheckPerformingValue = OnCheckPerforming(control); if (App.emu?.Core != null) last_CheckPerformingFrameIdx = App.emu.Core.Frame; } return last_CheckPerformingValue; //if (control.Device is ScreenGamepad_D) //{ // ScreenGamepad_D device = control.Device as ScreenGamepad_D; // return device.CheckPerforming(control); //} //else return OnCheckPerforming(control); } protected abstract bool OnCheckPerforming(CONTROLLER control) where CONTROLLER : InputControl_C; public Vector2 GetVector2(CONTROLLER control) where CONTROLLER : InputControl_C { if (control.Device is ScreenGamepad_D) { ScreenGamepad_D device = control.Device as ScreenGamepad_D; return device.GetVector2(control); } return OnGetVector2(control); } protected abstract Vector2 OnGetVector2(CONTROLLER control) where CONTROLLER : InputControl_C; public float GetFloat(CONTROLLER control) where CONTROLLER : InputControl_C { return OnGetFloat(control); } protected abstract float OnGetFloat(CONTROLLER control) where CONTROLLER : InputControl_C; /// /// 获得输入设备的唯一名称 /// /// 这个设备必须是由resolver提供,并且保持着连接 /// public string GetDeviceName(InputDevice_D inputDevice) { if (inputDevice is ScreenGamepad_D) { m_devices.TryGetKey(inputDevice as ScreenGamepad_D, out var realDeviceScript); return $"{realDeviceScript.GetType().Name}_{realDeviceScript.GetHashCode()}"; } else return OnGetDeviceName(inputDevice); } /// protected abstract string OnGetDeviceName(InputDevice_D inputDevice); } }