173 lines
5.7 KiB
C#
173 lines
5.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace AxibugEmuOnline.Client.InputDevices
|
|
{
|
|
public class InputDevicesManager
|
|
{
|
|
InputResolver m_inputResolver = InputResolver.Create();
|
|
Dictionary<string, InputDevice> m_devices = new Dictionary<string, InputDevice>();
|
|
|
|
public delegate void OnDeviceConnectedHandle(InputDevice connectDevice);
|
|
public event OnDeviceConnectedHandle OnDeviceConnected;
|
|
public delegate void OnDeviceLostHandle(InputDevice lostDevice);
|
|
public event OnDeviceLostHandle OnDeviceLost;
|
|
|
|
public InputDevicesManager()
|
|
{
|
|
m_inputResolver.OnDeviceConnected += Resolver_OnDeviceConnected;
|
|
m_inputResolver.OnDeviceLost += Resolver_OnDeviceLost;
|
|
foreach (var device in m_inputResolver.GetDevices())
|
|
AddDevice(device);
|
|
}
|
|
|
|
private void Resolver_OnDeviceLost(InputDevice lostDevice)
|
|
{
|
|
RemoveDevice(lostDevice);
|
|
}
|
|
|
|
private void Resolver_OnDeviceConnected(InputDevice connectDevice)
|
|
{
|
|
AddDevice(connectDevice);
|
|
}
|
|
|
|
void AddDevice(InputDevice device)
|
|
{
|
|
m_devices[device.UniqueName] = device;
|
|
OnDeviceConnected?.Invoke(device);
|
|
}
|
|
|
|
void RemoveDevice(InputDevice device)
|
|
{
|
|
m_devices.Remove(device.UniqueName);
|
|
OnDeviceLost?.Invoke(device);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获得一个指定类型的设备
|
|
/// </summary>
|
|
public T GetDevice<T>() where T : InputDevice
|
|
{
|
|
foreach (var d in m_devices.Values)
|
|
{
|
|
if (d is T) return d as T;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary> 由外部驱动的逻辑更新入口 </summary>
|
|
public void Update()
|
|
{
|
|
foreach (var device in m_devices.Values) device.Update();
|
|
}
|
|
}
|
|
|
|
public abstract class InputDevice
|
|
{
|
|
public string UniqueName => m_resolver.GetDeviceName(this);
|
|
|
|
/// <summary> 指示该设备是否在线 </summary>
|
|
public bool Online => m_resolver.CheckOnline(this);
|
|
/// <summary> 指示该设备当前帧是否有任意控件被激发 </summary>
|
|
public bool AnyKeyDown { get; private set; }
|
|
/// <summary> 获得输入解决器 </summary>
|
|
internal InputResolver Resolver => m_resolver;
|
|
|
|
protected Dictionary<string, InputControl> m_controlMapper = new Dictionary<string, InputControl>();
|
|
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)
|
|
{
|
|
control.Update();
|
|
if (control.Start)
|
|
{
|
|
AnyKeyDown = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary> 用于列出这个输入设备的所有输入控件实例 </summary>
|
|
/// <returns></returns>
|
|
protected abstract List<InputControl> DefineControls();
|
|
|
|
/// <summary> 通过控件名称,找到对应的控件 </summary>
|
|
/// <param name="keyName"></param>
|
|
/// <returns></returns>
|
|
public InputControl FindControlByName(string controlName)
|
|
{
|
|
m_controlMapper.TryGetValue(controlName, out var key);
|
|
return key;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 输入设备的抽象控件接口
|
|
/// </summary>
|
|
public abstract class InputControl
|
|
{
|
|
/// <summary> 控件所属设备 </summary>
|
|
public InputDevice Device { get; internal set; }
|
|
|
|
/// <summary> 获取该控件是否在当前调用帧被激发 </summary>
|
|
public bool Start { get; private set; }
|
|
/// <summary> 获取该控件是否在当前调用帧被释放 </summary>
|
|
public bool Release { get; private set; }
|
|
|
|
bool m_performingLastFrame;
|
|
/// <summary> 获取该控件是否在当前调用帧是否处于活动状态 </summary>
|
|
public abstract bool Performing { get; }
|
|
|
|
/// <summary> 获得该控件的以二维向量表达的值 </summary>
|
|
/// <returns></returns>
|
|
public abstract Vector2 GetVector2();
|
|
/// <summary> 获得该控件的以浮点数表达的值 </summary>
|
|
public abstract float GetFlaot();
|
|
|
|
internal void Update()
|
|
{
|
|
UpdateReleaseStartState();
|
|
OnUpdate();
|
|
}
|
|
|
|
private void UpdateReleaseStartState()
|
|
{
|
|
var oldPerforming = m_performingLastFrame;
|
|
var newPerforming = Performing;
|
|
|
|
Start = false;
|
|
Release = false;
|
|
if (oldPerforming != newPerforming)
|
|
{
|
|
if (oldPerforming == false) Start = true;
|
|
else Release = true;
|
|
}
|
|
m_performingLastFrame = Performing;
|
|
}
|
|
|
|
protected virtual void OnUpdate() { }
|
|
|
|
/// <summary> 控件名,这个控件名称必须是唯一的 </summary>
|
|
public abstract string ControlName { get; }
|
|
|
|
internal InputControl(InputDevice device)
|
|
{
|
|
Device = device;
|
|
}
|
|
}
|
|
|
|
}
|
|
} |