using System.Collections.Generic; using UnityEngine; namespace AxibugEmuOnline.Client.InputDevices { public class InputDevicesManager { InputResolver m_inputResolver = InputResolver.Create(); Dictionary m_devices = new Dictionary(); public InputDevicesManager() { m_inputResolver.OnDeviceConnected += OnDeviceConnected; m_inputResolver.OnDeviceLost += OnDeviceLost; foreach (var device in m_inputResolver.GetDevices()) AddDevice(device); } private void OnDeviceLost(InputDevice lostDevice) { RemoveDevice(lostDevice); } private void OnDeviceConnected(InputDevice connectDevice) { AddDevice(connectDevice); } public void AddDevice(InputDevice device) { m_devices[device.UniqueName] = device; } public void RemoveDevice(InputDevice device) { m_devices.Remove(device.UniqueName); } public InputDevice.InputControl 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.FindControlByName(keyName); return key; } public InputDevice FindDeviceByName(string deviceName) { m_devices.TryGetValue(deviceName, out var device); return device; } /// /// 获得一个键盘设备 /// public KeyBoard GetKeyboard() { foreach (var d in m_devices.Values) { if (d is KeyBoard kb) return kb; } return null; } /// 由外部驱动的逻辑更新入口 public void Update() { foreach (var device in m_devices.Values) device.Update(); } } public abstract class InputDevice { public string UniqueName => m_resolver.GetDeviceName(this); /// 指示该设备是否在线 public bool Online => m_resolver.CheckOnline(this); /// 指示该设备当前帧是否有任意控件被激发 public bool AnyKeyDown { get; private set; } /// 获得输入解决器 internal InputResolver Resolver => m_resolver; protected Dictionary m_controlMapper = new Dictionary(); protected InputResolver m_resolver; public InputDevice(InputResolver resolver) { m_resolver = resolver; foreach (var control in DefineControls()) { m_controlMapper.Add(control.ControlName, control); } } public void Update() { AnyKeyDown = false; foreach (var control in m_controlMapper.Values) { if (control.Start) { AnyKeyDown = true; } } } /// 用于列出这个输入设备的所有输入控件实例 /// protected abstract IEnumerable DefineControls(); /// 通过控件名称,找到对应的控件 /// /// public InputControl FindControlByName(string controlName) { m_controlMapper.TryGetValue(controlName, out var key); return key; } /// /// 输入设备的抽象控件接口 /// public abstract class InputControl { /// 控件所属设备 public InputDevice Device { get; internal set; } /// 获取该控件是否在当前调用帧被激发 public abstract bool Start { get; } /// 获取该控件是否在当前调用帧被释放 public abstract bool Release { get; } /// 获取该控件是否在当前调用帧是否处于活动状态 public abstract bool Performing { get; } /// 获得该控件的以二维向量表达的值 /// public abstract Vector2 GetVector2(); /// 获得该控件的以浮点数表达的值 public abstract float GetFlaot(); /// 控件名,这个控件名称必须是唯一的 public abstract string ControlName { get; } public string GetPath() { return $"{Device.UniqueName}/{ControlName}"; } } } }