using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; namespace AxibugEmuOnline.Client.InputDevices { public class InputDevicesManager { InputResolver m_inputResolver = InputResolver.Create(); Dictionary<string, InputDevice> m_devices = new Dictionary<string, InputDevice>(); public InputDevicesManager() { m_inputResolver.OnDeviceConnected += OnDeviceConnected; m_inputResolver.OnDeviceLost += OnDeviceLost; foreach (var device in m_inputResolver.GetDevices()) AddDevice(device); } private void OnDeviceLost(InputDevice lostDevice) { } private void OnDeviceConnected(InputDevice connectDevice) { throw new System.NotImplementedException(); } public void AddDevice(InputDevice device) { m_devices[device.UniqueName] = device; } public void RemoveDevice(InputDevice device) { m_devices.Remove(device.UniqueName); } public InputDevice.KeyBase GetKeyByPath(string path) { var temp = path.Split("/"); Debug.Assert(temp.Length == 2, "Invalid Path Format"); var deviceName = temp[0]; var keyName = temp[1]; var targetDevice = FindDeviceByName(deviceName); if (targetDevice == null) return null; var key = targetDevice.FindKeyByKeyName(keyName); return key; } public InputDevice FindDeviceByName(string deviceName) { m_devices.TryGetValue(deviceName, out var device); return device; } /// <summary> /// 获得键盘设备 /// <para>键盘设备被设计为有且仅有一个,所以这里应该总是能获得键盘设备</para> /// </summary> public KeyBoard GetKeyboard() { foreach (var d in m_devices.Values) { if (d is KeyBoard kb) return kb; } return null; } /// <summary> 由外部驱动的逻辑更新入口 </summary> public void Update() { foreach (var device in m_devices.Values) device.Update(); } } public abstract class InputDevice { public abstract string UniqueName { get; } public delegate void OnKeyStateChangedHandle(KeyBase sender); public event OnKeyStateChangedHandle OnKeyStateChanged; /// <summary> 指示该设备是否在线 </summary> public abstract bool Online { get; } /// <summary> 指示该设备当前帧是否有任意键被按下 </summary> public bool AnyKeyDown { get; private set; } protected Dictionary<string, KeyBase> m_keyMapper = new Dictionary<string, KeyBase>(); protected InputResolver m_resolver; public InputDevice(InputResolver resolver) { m_resolver = resolver; foreach (var key in DefineKeys()) { m_keyMapper[key.KeyName] = key; } } public void Update() { AnyKeyDown = false; foreach (var key in m_keyMapper.Values) { if (key.GetButtonDown()) { AnyKeyDown = true; RaiseKeyEvent(key); } } } protected abstract IEnumerable<KeyBase> DefineKeys(); protected void RaiseKeyEvent(KeyBase sender) { OnKeyStateChanged?.Invoke(sender); } public KeyBase FindKeyByKeyName(string keyName) { m_keyMapper.TryGetValue(keyName, out var key); return key; } /// <summary> /// 输入设备的键接口 /// </summary> public abstract class KeyBase { public InputDevice HostDevice { get; internal set; } /// <summary> 获取该键是否在当前调用帧被按下 </summary> public abstract bool GetButtonDown(); /// <summary> 获取该键是否在当前调用帧被抬起 </summary> public abstract bool GetButtonUp(); /// <summary> 获取该键是否在当前调用帧是否处于按下状态 </summary> public abstract bool IsPressing(); public virtual Vector2 GetVector2() { throw new System.NotImplementedException(); } public virtual float GetFlaot() { throw new System.NotImplementedException(); } /// <summary> 键名 </summary> public abstract string KeyName { get; } public string GetPath() { return $"{HostDevice.UniqueName}/{KeyName}"; } } } }