2025-10-13 20:20:01 +08:00
|
|
|
|
#if INPUTSYSTEM_SUPPORT
|
2025-12-09 20:30:11 +08:00
|
|
|
|
using System;
|
2025-12-24 15:13:57 +08:00
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
|
using System.Runtime.InteropServices;
|
2025-10-13 20:20:01 +08:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.InputSystem;
|
2025-12-24 15:13:57 +08:00
|
|
|
|
using Unity.Collections;
|
|
|
|
|
|
using Unity.Collections.LowLevel.Unsafe;
|
2025-12-19 20:26:22 +08:00
|
|
|
|
using UnityEngine.UI;
|
2025-12-09 15:08:41 +08:00
|
|
|
|
|
2025-12-19 20:26:22 +08:00
|
|
|
|
namespace UnityEngine.UI
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
internal enum EHotkeyPressType : byte
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
Started = 0,
|
|
|
|
|
|
Performed = 1
|
2025-12-09 20:30:11 +08:00
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
// 优化1: 使用struct减少GC
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
|
|
|
|
|
internal struct HotkeyRegistration
|
2025-12-09 20:30:11 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
public IHotkeyTrigger button;
|
|
|
|
|
|
public EHotkeyPressType pressType;
|
2025-12-09 20:30:11 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
public HotkeyRegistration(IHotkeyTrigger btn, EHotkeyPressType pressType)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.button = btn;
|
|
|
|
|
|
this.pressType = pressType;
|
2025-10-13 20:20:01 +08:00
|
|
|
|
}
|
2025-12-24 15:13:57 +08:00
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
// 优化2: 使用struct存储handler信息
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
|
|
internal struct HandlerInfo
|
|
|
|
|
|
{
|
|
|
|
|
|
public Action<InputAction.CallbackContext> handler;
|
|
|
|
|
|
public InputActionReference action;
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
public HandlerInfo(Action<InputAction.CallbackContext> handler, InputActionReference action)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.handler = handler;
|
|
|
|
|
|
this.action = action;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
internal static class UXHotkeyRegisterManager
|
|
|
|
|
|
{
|
|
|
|
|
|
// 优化3: 使用数组池替代List,避免频繁扩容
|
|
|
|
|
|
private const int INITIAL_CAPACITY = 32;
|
|
|
|
|
|
private const int MAX_REGISTRATIONS_PER_ACTION = 16;
|
|
|
|
|
|
|
|
|
|
|
|
// 优化4: 使用固定大小的数组池
|
|
|
|
|
|
private static HotkeyRegistration[][] _registrationPool;
|
|
|
|
|
|
private static int[] _registrationCounts;
|
|
|
|
|
|
private static string[] _actionIds;
|
|
|
|
|
|
private static int _actionCount;
|
|
|
|
|
|
private static int _actionCapacity;
|
|
|
|
|
|
|
|
|
|
|
|
// 优化5: 使用数组替代Dictionary(更快的查找)
|
|
|
|
|
|
private static HandlerInfo[] _handlers;
|
|
|
|
|
|
private static InputActionReference[] _actionRefs;
|
|
|
|
|
|
|
|
|
|
|
|
// 优化6: Button到ActionId的映射(使用数组索引)
|
|
|
|
|
|
private static IHotkeyTrigger[] _buttons;
|
|
|
|
|
|
private static int[] _buttonToActionIndex;
|
|
|
|
|
|
private static int _buttonCount;
|
|
|
|
|
|
private static int _buttonCapacity;
|
|
|
|
|
|
|
|
|
|
|
|
// 优化7: 缓存委托,避免每次创建
|
|
|
|
|
|
private static Action<InputAction.CallbackContext>[] _cachedHandlers;
|
|
|
|
|
|
private static int _cachedHandlerCount;
|
|
|
|
|
|
|
|
|
|
|
|
static UXHotkeyRegisterManager()
|
|
|
|
|
|
{
|
|
|
|
|
|
_actionCapacity = INITIAL_CAPACITY;
|
|
|
|
|
|
_registrationPool = new HotkeyRegistration[_actionCapacity][];
|
|
|
|
|
|
_registrationCounts = new int[_actionCapacity];
|
|
|
|
|
|
_actionIds = new string[_actionCapacity];
|
|
|
|
|
|
_handlers = new HandlerInfo[_actionCapacity];
|
|
|
|
|
|
_actionRefs = new InputActionReference[_actionCapacity];
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
_buttonCapacity = 64;
|
|
|
|
|
|
_buttons = new IHotkeyTrigger[_buttonCapacity];
|
|
|
|
|
|
_buttonToActionIndex = new int[_buttonCapacity];
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
_cachedHandlers = new Action<InputAction.CallbackContext>[INITIAL_CAPACITY];
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
for (int i = 0; i < _actionCapacity; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
_registrationPool[i] = new HotkeyRegistration[MAX_REGISTRATIONS_PER_ACTION];
|
|
|
|
|
|
_buttonToActionIndex[i] = -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
2025-12-15 19:38:08 +08:00
|
|
|
|
[UnityEditor.Callbacks.DidReloadScripts]
|
2025-12-09 20:30:11 +08:00
|
|
|
|
internal static void ClearHotkeyRegistry()
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
for (int i = 0; i < _buttonCount; i++)
|
2025-12-09 20:30:11 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
if (_buttons[i] != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
UnregisterHotkey(_buttons[i]);
|
|
|
|
|
|
}
|
2025-12-09 20:30:11 +08:00
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
Array.Clear(_registrationCounts, 0, _actionCount);
|
|
|
|
|
|
Array.Clear(_actionIds, 0, _actionCount);
|
|
|
|
|
|
Array.Clear(_handlers, 0, _actionCount);
|
|
|
|
|
|
Array.Clear(_actionRefs, 0, _actionCount);
|
|
|
|
|
|
Array.Clear(_buttons, 0, _buttonCount);
|
|
|
|
|
|
Array.Clear(_buttonToActionIndex, 0, _buttonCount);
|
|
|
|
|
|
|
|
|
|
|
|
_actionCount = 0;
|
|
|
|
|
|
_buttonCount = 0;
|
|
|
|
|
|
_cachedHandlerCount = 0;
|
2025-12-09 20:30:11 +08:00
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2025-12-19 20:26:22 +08:00
|
|
|
|
internal static void RegisterHotkey(IHotkeyTrigger button, InputActionReference action, EHotkeyPressType pressType)
|
2025-12-09 20:30:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (action == null || action.action == null || button == null)
|
|
|
|
|
|
return;
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-09 20:30:11 +08:00
|
|
|
|
string actionId = action.action.id.ToString();
|
2025-12-24 15:13:57 +08:00
|
|
|
|
int actionIndex = FindOrCreateActionIndex(actionId);
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
// 添加注册信息
|
|
|
|
|
|
ref int count = ref _registrationCounts[actionIndex];
|
|
|
|
|
|
if (count >= MAX_REGISTRATIONS_PER_ACTION)
|
2025-12-09 20:30:11 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
Debug.LogWarning($"Max registrations reached for action: {actionId}");
|
|
|
|
|
|
return;
|
2025-12-09 20:30:11 +08:00
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
_registrationPool[actionIndex][count] = new HotkeyRegistration(button, pressType);
|
|
|
|
|
|
count++;
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
// 记录button映射
|
|
|
|
|
|
int buttonIndex = FindOrCreateButtonIndex(button);
|
|
|
|
|
|
_buttonToActionIndex[buttonIndex] = actionIndex;
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
// 优化8: 只在第一次注册时创建handler
|
|
|
|
|
|
if (count == 1)
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
Action<InputAction.CallbackContext> handler = GetOrCreateHandler(actionIndex);
|
|
|
|
|
|
_handlers[actionIndex] = new HandlerInfo(handler, action);
|
|
|
|
|
|
_actionRefs[actionIndex] = action;
|
2025-12-09 20:30:11 +08:00
|
|
|
|
|
|
|
|
|
|
switch (pressType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case EHotkeyPressType.Started:
|
|
|
|
|
|
action.action.started += handler;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case EHotkeyPressType.Performed:
|
|
|
|
|
|
action.action.performed += handler;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-09 20:30:11 +08:00
|
|
|
|
action.action.Enable();
|
|
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2025-12-19 20:26:22 +08:00
|
|
|
|
public static void UnregisterHotkey(IHotkeyTrigger button)
|
2025-12-09 20:30:11 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
if (button == null)
|
2025-12-09 20:30:11 +08:00
|
|
|
|
return;
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
int buttonIndex = FindButtonIndex(button);
|
|
|
|
|
|
if (buttonIndex < 0)
|
|
|
|
|
|
return;
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
int actionIndex = _buttonToActionIndex[buttonIndex];
|
|
|
|
|
|
if (actionIndex < 0)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
// 从注册列表中移除
|
|
|
|
|
|
ref int count = ref _registrationCounts[actionIndex];
|
|
|
|
|
|
HotkeyRegistration[] registrations = _registrationPool[actionIndex];
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = count - 1; i >= 0; i--)
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
if (ReferenceEquals(registrations[i].button, button))
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
EHotkeyPressType pressType = registrations[i].pressType;
|
|
|
|
|
|
|
|
|
|
|
|
// 优化9: Swap-remove,避免数组移动
|
|
|
|
|
|
registrations[i] = registrations[count - 1];
|
|
|
|
|
|
registrations[count - 1] = default;
|
|
|
|
|
|
count--;
|
|
|
|
|
|
|
|
|
|
|
|
// 如果是最后一个注册,清理handler
|
|
|
|
|
|
if (count == 0)
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
ref HandlerInfo handlerInfo = ref _handlers[actionIndex];
|
|
|
|
|
|
InputActionReference actionRef = _actionRefs[actionIndex];
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
if (actionRef != null && actionRef.action != null)
|
2025-12-09 20:30:11 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
switch (pressType)
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
case EHotkeyPressType.Started:
|
|
|
|
|
|
actionRef.action.started -= handlerInfo.handler;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case EHotkeyPressType.Performed:
|
|
|
|
|
|
actionRef.action.performed -= handlerInfo.handler;
|
|
|
|
|
|
break;
|
2025-10-13 20:20:01 +08:00
|
|
|
|
}
|
2025-12-24 15:13:57 +08:00
|
|
|
|
|
|
|
|
|
|
actionRef.action.Disable();
|
2025-10-13 20:20:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
handlerInfo = default;
|
|
|
|
|
|
_actionRefs[actionIndex] = null;
|
|
|
|
|
|
_actionIds[actionIndex] = null;
|
2025-12-09 20:30:11 +08:00
|
|
|
|
}
|
2025-12-24 15:13:57 +08:00
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 清理button映射
|
|
|
|
|
|
_buttons[buttonIndex] = null;
|
|
|
|
|
|
_buttonToActionIndex[buttonIndex] = -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 优化10: 使用缓存的委托,避免闭包分配
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
private static Action<InputAction.CallbackContext> GetOrCreateHandler(int actionIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (actionIndex < _cachedHandlers.Length && _cachedHandlers[actionIndex] != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return _cachedHandlers[actionIndex];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (actionIndex >= _cachedHandlers.Length)
|
|
|
|
|
|
{
|
|
|
|
|
|
Array.Resize(ref _cachedHandlers, actionIndex + 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 优化11: 使用静态方法 + 参数传递,避免闭包
|
|
|
|
|
|
int capturedIndex = actionIndex;
|
|
|
|
|
|
_cachedHandlers[actionIndex] = ctx => OnHotkeyTriggered(capturedIndex);
|
|
|
|
|
|
return _cachedHandlers[actionIndex];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
private static void OnHotkeyTriggered(int actionIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
int count = _registrationCounts[actionIndex];
|
|
|
|
|
|
if (count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 触发最后一个注册的button(栈顶)
|
|
|
|
|
|
ref HotkeyRegistration registration = ref _registrationPool[actionIndex][count - 1];
|
|
|
|
|
|
registration.button?.HotkeyActionTrigger();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 优化12: 线性查找(小数据集比Dictionary更快)
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
private static int FindOrCreateActionIndex(string actionId)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 查找现有
|
|
|
|
|
|
for (int i = 0; i < _actionCount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_actionIds[i] == actionId)
|
|
|
|
|
|
return i;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建新的
|
|
|
|
|
|
if (_actionCount >= _actionCapacity)
|
|
|
|
|
|
{
|
|
|
|
|
|
ExpandActionCapacity();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int index = _actionCount++;
|
|
|
|
|
|
_actionIds[index] = actionId;
|
|
|
|
|
|
return index;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
private static int FindOrCreateButtonIndex(IHotkeyTrigger button)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 查找现有
|
|
|
|
|
|
for (int i = 0; i < _buttonCount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ReferenceEquals(_buttons[i], button))
|
|
|
|
|
|
return i;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 查找空槽
|
|
|
|
|
|
for (int i = 0; i < _buttonCapacity; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_buttons[i] == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_buttons[i] = button;
|
|
|
|
|
|
if (i >= _buttonCount)
|
|
|
|
|
|
_buttonCount = i + 1;
|
|
|
|
|
|
return i;
|
2025-10-13 20:20:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
// 扩容
|
|
|
|
|
|
if (_buttonCount >= _buttonCapacity)
|
|
|
|
|
|
{
|
|
|
|
|
|
ExpandButtonCapacity();
|
|
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
int index = _buttonCount++;
|
|
|
|
|
|
_buttons[index] = button;
|
|
|
|
|
|
return index;
|
2025-12-09 20:30:11 +08:00
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
private static int FindButtonIndex(IHotkeyTrigger button)
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
for (int i = 0; i < _buttonCount; i++)
|
2025-12-09 20:30:11 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
if (ReferenceEquals(_buttons[i], button))
|
|
|
|
|
|
return i;
|
2025-12-09 20:30:11 +08:00
|
|
|
|
}
|
2025-12-24 15:13:57 +08:00
|
|
|
|
|
|
|
|
|
|
return -1;
|
2025-10-13 20:20:01 +08:00
|
|
|
|
}
|
2025-12-24 15:13:57 +08:00
|
|
|
|
|
|
|
|
|
|
private static void ExpandActionCapacity()
|
|
|
|
|
|
{
|
|
|
|
|
|
int newCapacity = _actionCapacity * 2;
|
|
|
|
|
|
Array.Resize(ref _registrationPool, newCapacity);
|
|
|
|
|
|
Array.Resize(ref _registrationCounts, newCapacity);
|
|
|
|
|
|
Array.Resize(ref _actionIds, newCapacity);
|
|
|
|
|
|
Array.Resize(ref _handlers, newCapacity);
|
|
|
|
|
|
Array.Resize(ref _actionRefs, newCapacity);
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = _actionCapacity; i < newCapacity; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
_registrationPool[i] = new HotkeyRegistration[MAX_REGISTRATIONS_PER_ACTION];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_actionCapacity = newCapacity;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static void ExpandButtonCapacity()
|
|
|
|
|
|
{
|
|
|
|
|
|
int newCapacity = _buttonCapacity * 2;
|
|
|
|
|
|
Array.Resize(ref _buttons, newCapacity);
|
|
|
|
|
|
Array.Resize(ref _buttonToActionIndex, newCapacity);
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = _buttonCapacity; i < newCapacity; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
_buttonToActionIndex[i] = -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_buttonCapacity = newCapacity;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 优化13: 批量操作API
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
public static void RegisterHotkeyBatch(Span<IHotkeyTrigger> buttons, InputActionReference action, EHotkeyPressType pressType)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < buttons.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
RegisterHotkey(buttons[i], action, pressType);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
public static void UnregisterHotkeyBatch(Span<IHotkeyTrigger> buttons)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < buttons.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
UnregisterHotkey(buttons[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 调试信息
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
public static string GetDebugInfo()
|
|
|
|
|
|
{
|
|
|
|
|
|
return $"Actions: {_actionCount}/{_actionCapacity}, Buttons: {_buttonCount}/{_buttonCapacity}";
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
2025-10-13 20:20:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static class UXHotkeyHotkeyExtension
|
|
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2025-12-19 20:26:22 +08:00
|
|
|
|
public static void BindHotKey(this IHotkeyTrigger button)
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
if (button?.HotkeyAction != null)
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
|
|
|
|
|
UXHotkeyRegisterManager.RegisterHotkey(
|
|
|
|
|
|
button,
|
2025-12-19 20:26:22 +08:00
|
|
|
|
button.HotkeyAction,
|
|
|
|
|
|
button.HotkeyPressType
|
2025-10-13 20:20:01 +08:00
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-24 15:13:57 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2025-12-19 20:26:22 +08:00
|
|
|
|
public static void UnBindHotKey(this IHotkeyTrigger button)
|
2025-10-13 20:20:01 +08:00
|
|
|
|
{
|
2025-12-24 15:13:57 +08:00
|
|
|
|
if (button?.HotkeyAction != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
UXHotkeyRegisterManager.UnregisterHotkey(button);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 优化14: 批量绑定
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
public static void BindHotKeyBatch(this IHotkeyTrigger[] buttons)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (buttons == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < buttons.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
buttons[i]?.BindHotKey();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
public static void UnBindHotKeyBatch(this IHotkeyTrigger[] buttons)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (buttons == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < buttons.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
buttons[i]?.UnBindHotKey();
|
|
|
|
|
|
}
|
2025-10-13 20:20:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|