AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Script/UI/CommandDispatcher/CommandDispatcher.cs
2024-11-26 17:18:20 +08:00

132 lines
3.8 KiB
C#

using AxibugEmuOnline.Client.ClientCore;
using System.Collections.Generic;
using UnityEngine;
namespace AxibugEmuOnline.Client
{
public class CommandDispatcher : MonoBehaviour
{
public static CommandDispatcher Instance { get; private set; }
/// <summary> 平级注册对象,都会响应指令 </summary>
List<CommandExecuter> m_register = new List<CommandExecuter>();
/// <summary> 独占注册对象,指令会被列表中最后一个对象独占 </summary>
List<CommandExecuter> m_registerHigh = new List<CommandExecuter>();
ICommandListener m_listener;
/// <summary> 标准UI操作 </summary>
public IKeyMapperChanger Normal { get; private set; }
/// <summary> 游戏中UI操作 </summary>
public IKeyMapperChanger Gaming { get; private set; }
private IKeyMapperChanger m_current;
public IKeyMapperChanger Current
{
get => m_current;
set
{
m_current = value;
SetKeyMapper(m_current);
}
}
private void Awake()
{
Instance = this;
//初始化command监视器
m_listener = new CommandListener();
//初始化键位修改器
Normal = new NormalChanger();
Gaming = new GamingChanger();
}
private void OnDestroy()
{
Instance = null;
}
public void RegistController(CommandExecuter controller)
{
if (!controller.AloneMode)
{
if (m_register.Contains(controller)) { return; }
m_register.Add(controller);
}
else
{
if (m_registerHigh.Contains(controller)) { return; }
m_registerHigh.Add(controller);
}
}
public void UnRegistController(CommandExecuter menuItemController)
{
if (!menuItemController.AloneMode)
m_register.Remove(menuItemController);
else
m_registerHigh.Remove(menuItemController);
}
readonly List<CommandExecuter> oneFrameRegister = new List<CommandExecuter>();
private void Update()
{
peekRegister(oneFrameRegister);
m_listener.Update(oneFrameRegister);
//键位映射在按键响应的堆栈结束后处理,防止迭代器修改问题
if (m_waitMapperSetting != null)
{
m_listener.ApplyKeyMapper(m_waitMapperSetting);
m_waitMapperSetting = null;
}
}
IKeyMapperChanger m_waitMapperSetting = null;
void SetKeyMapper(IKeyMapperChanger keyMapChanger)
{
m_waitMapperSetting = keyMapChanger;
}
private List<CommandExecuter> peekRegister(List<CommandExecuter> results)
{
results.Clear();
if (m_registerHigh.Count > 0)
{
for (int i = m_registerHigh.Count - 1; i >= 0; i--)
{
var controller = m_registerHigh[i];
if (controller.Enable)
{
results.Add(controller);
return results;
}
}
}
foreach (var controller in m_register)
{
if (!controller.Enable) continue;
results.Add(controller);
}
return results;
}
#if UNITY_EDITOR
public void GetRegisters(out IReadOnlyList<CommandExecuter> normal, out IReadOnlyList<CommandExecuter> alone)
{
normal = m_register;
alone = m_registerHigh;
}
#endif
}
}