1
0

InputControl的实现类挪入基本类型,不再每个设备单独实现

This commit is contained in:
ALIENJACK\alien 2025-03-27 11:54:10 +08:00
parent 924727eb7c
commit 8007af0bc5
14 changed files with 242 additions and 240 deletions

View File

@ -1,6 +1,5 @@
using AxibugEmuOnline.Client.InputDevices;
using AxibugProtobuf;
using AxiInputSP;
using System;
namespace AxibugEmuOnline.Client.Settings

View File

@ -232,7 +232,7 @@ namespace AxibugEmuOnline.Client.Settings
else return totalFloat / totalControl;
}
public class MapSetting : Dictionary<T, List<InputDevice.InputControl>> { }
public class MapSetting : Dictionary<T, List<InputControl>> { }
public class BindingPage
{
@ -277,7 +277,7 @@ namespace AxibugEmuOnline.Client.Settings
m_mapSetting.Remove(device);
}
public void SetBinding(T emuBtn, InputDevice.InputControl key, int settingSlot)
public void SetBinding(T emuBtn, InputControl key, int settingSlot)
{
var device = key.Device;
m_registedDevices.TryGetValue(device.GetType(), out var inputDevice);
@ -287,7 +287,7 @@ namespace AxibugEmuOnline.Client.Settings
var setting = m_mapSetting[inputDevice];
if (!setting.TryGetValue(emuBtn, out var settingList))
{
settingList = new List<InputDevice.InputControl>();
settingList = new List<InputControl>();
setting[emuBtn] = settingList;
}
@ -297,7 +297,7 @@ namespace AxibugEmuOnline.Client.Settings
settingList[settingSlot] = key;
}
public InputDevice.InputControl GetBinding(T emuBtn, InputDevice device, int settingSlot)
public InputControl GetBinding(T emuBtn, InputDevice device, int settingSlot)
{
m_mapSetting.TryGetValue(device, out var mapSetting);
if (mapSetting == null) return null;
@ -308,8 +308,8 @@ namespace AxibugEmuOnline.Client.Settings
return settingList[settingSlot];
}
private List<InputDevice.InputControl> m_caches = new List<InputDevice.InputControl>();
public IEnumerable<InputDevice.InputControl> GetBinding(T emuBtn)
private List<InputControl> m_caches = new List<InputControl>();
public IEnumerable<InputControl> GetBinding(T emuBtn)
{
m_caches.Clear();

View File

@ -0,0 +1,17 @@
namespace AxibugEmuOnline.Client.InputDevices
{
/// <summary>
/// 按键类型的输入控件
/// </summary>
public class Button : InputControl
{
string m_controlName;
public Button(InputDevice device, string controlName) : base(device)
{
m_controlName = controlName;
}
public override string ControlName => m_controlName;
}
}

View File

@ -0,0 +1,59 @@
using UnityEngine;
namespace AxibugEmuOnline.Client.InputDevices
{
/// <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 virtual bool Performing => Device.Resolver.CheckPerforming(this);
/// <summary> 获得该控件的以二维向量表达的值 </summary>
/// <returns></returns>
public virtual Vector2 GetVector2() => Device.Resolver.GetVector2(this);
/// <summary> 获得该控件的以浮点数表达的值 </summary>
public virtual float GetFlaot() => Device.Resolver.GetFloat(this);
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;
}
}
}

View File

@ -0,0 +1,70 @@
using UnityEngine;
namespace AxibugEmuOnline.Client.InputDevices
{
/// <summary>
/// 摇杆类型的输入控件,支持的返回值为Vector2
/// </summary>
public class Stick : InputControl
{
string m_controlName;
public override string ControlName => m_controlName;
public VirtualButton UP { get; private set; }
public VirtualButton Down { get; private set; }
public VirtualButton Left { get; private set; }
public VirtualButton Right { get; private set; }
public Stick(InputDevice device, string controlName) : base(device)
{
m_controlName = controlName;
UP = new VirtualButton(device);
Down = new VirtualButton(device);
Left = new VirtualButton(device);
Right = new VirtualButton(device);
}
protected override void OnUpdate()
{
var axis = GetVector2();
UP.m_performing = axis.y > 0f;
UP.Update();
Down.m_performing = axis.y < 0f;
Down.Update();
Left.m_performing = axis.x < 0f;
Left.Update();
Right.m_performing = axis.x > 0f;
Right.Update();
}
public class VirtualButton : InputControl
{
internal bool m_performing;
public VirtualButton(InputDevice device) : base(device) { }
public override bool Performing
{
get => m_performing;
}
public override Vector2 GetVector2()
{
return default;
}
public override float GetFlaot()
{
return Performing ? 1 : 0;
}
public override string ControlName => "VirtualStickButton";
}
}
}

View File

@ -0,0 +1,56 @@
using System.Collections.Generic;
namespace AxibugEmuOnline.Client.InputDevices
{
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;
}
}
}

View File

@ -23,17 +23,15 @@ namespace AxibugEmuOnline.Client.InputDevices
return keys;
}
public class KeyboardKey : InputControl
public class KeyboardKey : Button
{
internal KeyCode m_keycode;
internal KeyboardKey(KeyCode listenKey, KeyBoard keyboard)
: base(keyboard)
: base(keyboard, listenKey.ToString())
{
m_keycode = listenKey;
}
public override string ControlName => m_keycode.ToString();
}
}

View File

@ -1,5 +1,4 @@
using System.Collections.Generic;
using UnityEngine;
namespace AxibugEmuOnline.Client.InputDevices
{
@ -46,82 +45,10 @@ namespace AxibugEmuOnline.Client.InputDevices
Down = new Button(this, "DOWN");
Left = new Button(this, "LEFT");
LeftStick = new Stick(this, nameof(LeftStick));
RightStick = new Stick(this, nameof(RightStick));
return result;
}
public class Button : InputControl
{
internal string m_controlName;
public Button(InputDevice device, string controlName) : base(device)
{
m_controlName = controlName;
}
public override string ControlName => m_controlName;
}
public class Stick : InputControl
{
internal bool m_left;
public VirtualButton UP { get; private set; }
public VirtualButton Down { get; private set; }
public VirtualButton Left { get; private set; }
public VirtualButton Right { get; private set; }
public Stick(InputDevice device, bool left) : base(device)
{
m_left = left;
UP = new VirtualButton(device);
Down = new VirtualButton(device);
Left = new VirtualButton(device);
Right = new VirtualButton(device);
}
protected override void OnUpdate()
{
var axis = GetVector2();
UP.m_performing = axis.y > 0f;
UP.Update();
Down.m_performing = axis.y < 0f;
Down.Update();
Left.m_performing = axis.x < 0f;
Left.Update();
Right.m_performing = axis.x > 0f;
Right.Update();
}
public override string ControlName => $"{nameof(Stick)}_{(m_left ? "left" : "right")}";
public class VirtualButton : InputControl
{
internal bool m_performing;
public VirtualButton(InputDevice device) : base(device) { }
public override bool Performing
{
get => m_performing;
}
public override Vector2 GetVector2()
{
return default;
}
public override float GetFlaot()
{
return Performing ? 1 : 0;
}
public override string ControlName => "VirtualStickButton";
}
}
}
}

View File

@ -62,111 +62,4 @@ namespace AxibugEmuOnline.Client.InputDevices
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 virtual bool Performing => Device.Resolver.CheckPerforming(this);
/// <summary> 获得该控件的以二维向量表达的值 </summary>
/// <returns></returns>
public virtual Vector2 GetVector2() => Device.Resolver.GetVector2(this);
/// <summary> 获得该控件的以浮点数表达的值 </summary>
public virtual float GetFlaot() => Device.Resolver.GetFloat(this);
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;
}
}
}
}

View File

@ -56,9 +56,9 @@ namespace AxibugEmuOnline.Client.InputDevices
OnDeviceConnected?.Invoke(connectDevice);
}
public abstract bool CheckPerforming<CONTROLLER>(CONTROLLER control) where CONTROLLER : InputDevice.InputControl;
public abstract Vector2 GetVector2<CONTROLLER>(CONTROLLER control) where CONTROLLER : InputDevice.InputControl;
public abstract float GetFloat<CONTROLLER>(CONTROLLER control) where CONTROLLER : InputDevice.InputControl;
public abstract bool CheckPerforming<CONTROLLER>(CONTROLLER control) where CONTROLLER : InputControl;
public abstract Vector2 GetVector2<CONTROLLER>(CONTROLLER control) where CONTROLLER : InputControl;
public abstract float GetFloat<CONTROLLER>(CONTROLLER control) where CONTROLLER : InputControl;
/// <summary>
/// 获得输入设备的唯一名称
/// </summary>

View File

@ -1,7 +1,6 @@
#if ENABLE_INPUT_SYSTEM
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using IP = UnityEngine.InputSystem.InputSystem;
using IPDevice = UnityEngine.InputSystem.InputDevice;
@ -9,8 +8,8 @@ using IPKeyboard = UnityEngine.InputSystem.Keyboard;
namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
{
/// <summary> InputSystem对接类 </summary>
public partial class InputSystemResolver : InputResolver
/// <summary> 基于UnityInputSystem实现的输入解决器 </summary>
public class InputSystemResolver : InputResolver
{
DualWayDictionary<IPDevice, InputDevice> m_devices = new DualWayDictionary<IPDevice, InputDevice>();
@ -101,10 +100,7 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
{
throw new System.NotImplementedException();
}
}
public partial class InputSystemResolver : InputResolver
{
static ButtonControl GetIPKeyboardKey(IPKeyboard keyboard, KeyCode key)
{
switch (key)
@ -228,6 +224,7 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
throw new System.NotImplementedException($"Not Find KeyCode Mapper Code from {key}");
}
}
}
}
#endif

View File

@ -1,11 +1,9 @@
using NUnit.Framework.Internal;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
using static Essgee.Emulation.Audio.DMGAudio;
using static VirtualNes.Core.APU_INTERNAL;
namespace AxibugEmuOnline.Client.InputDevices.ForPSV
{
/// <summary> PSV特化输入解决器,只能用于PSV平台,并且只支持PSV控制器 </summary>
public class PSVResolver : InputResolver
{
List<InputDevice> m_devices = new List<InputDevice>();
@ -38,24 +36,21 @@ namespace AxibugEmuOnline.Client.InputDevices.ForPSV
{
if (control.Device is PSVController psvCon)
{
if (control is PSVController.Button button)
if (control == psvCon.Cross) return Input.GetKey(KeyCode.Joystick1Button0);
else if (control == psvCon.Circle) return Input.GetKey(KeyCode.Joystick1Button1);
else if (control == psvCon.Square) return Input.GetKey(KeyCode.Joystick1Button2);
else if (control == psvCon.Triangle) return Input.GetKey(KeyCode.Joystick1Button3);
else if (control == psvCon.L) return Input.GetKey(KeyCode.Joystick1Button4);
else if (control == psvCon.R) return Input.GetKey(KeyCode.Joystick1Button5);
else if (control == psvCon.Select) return Input.GetKey(KeyCode.Joystick1Button6);
else if (control == psvCon.Start) return Input.GetKey(KeyCode.Joystick1Button7);
else if (control == psvCon.Up) return Input.GetKey(KeyCode.Joystick1Button8);
else if (control == psvCon.Right) return Input.GetKey(KeyCode.Joystick1Button9);
else if (control == psvCon.Down) return Input.GetKey(KeyCode.Joystick1Button10);
else if (control == psvCon.Left) return Input.GetKey(KeyCode.Joystick1Button11);
else if (control == psvCon.LeftStick || control == psvCon.RightStick)
{
if (button == psvCon.Cross) return Input.GetKey(KeyCode.Joystick1Button0);
else if (button == psvCon.Circle) return Input.GetKey(KeyCode.Joystick1Button1);
else if (button == psvCon.Square) return Input.GetKey(KeyCode.Joystick1Button2);
else if (button == psvCon.Triangle) return Input.GetKey(KeyCode.Joystick1Button3);
else if (button == psvCon.L) return Input.GetKey(KeyCode.Joystick1Button4);
else if (button == psvCon.R) return Input.GetKey(KeyCode.Joystick1Button5);
else if (button == psvCon.Select) return Input.GetKey(KeyCode.Joystick1Button6);
else if (button == psvCon.Start) return Input.GetKey(KeyCode.Joystick1Button7);
else if (button == psvCon.Up) return Input.GetKey(KeyCode.Joystick1Button8);
else if (button == psvCon.Right) return Input.GetKey(KeyCode.Joystick1Button9);
else if (button == psvCon.Down) return Input.GetKey(KeyCode.Joystick1Button10);
else if (button == psvCon.Left) return Input.GetKey(KeyCode.Joystick1Button11);
}
else if (control is PSVController.Stick stick)
{
var vec2 = stick.GetVector2();
var vec2 = control.GetVector2();
return vec2.x != 0 || vec2.y != 0;
}
}
@ -65,24 +60,15 @@ namespace AxibugEmuOnline.Client.InputDevices.ForPSV
public override Vector2 GetVector2<CONTROLLER>(CONTROLLER control)
{
if (control.Device is PSVController)
if (control.Device is PSVController psvCon)
{
if (control is PSVController.Stick stick)
if (control == psvCon.LeftStick)
{
Vector2 result = Vector2.zero;
if (stick.m_left)
{
result.x = Input.GetAxis("Joy1 Axis X");
result.y = Input.GetAxis("Joy1 Axis Y");
}
else
{
result.x = Input.GetAxis("Joy1 Axis 4");
result.y = Input.GetAxis("Joy1 Axis 5");
}
return result;
return new Vector2(Input.GetAxis("Joy1 Axis X"), Input.GetAxis("Joy1 Axis Y"));
}
else if (control == psvCon.RightStick)
{
return new Vector2(Input.GetAxis("Joy1 Axis 4"), Input.GetAxis("Joy1 Axis 5"));
}
}