using System.Collections.Generic; using UnityEngine; namespace AxibugEmuOnline.Client { public class CommandDispatcher : MonoBehaviour { public static CommandDispatcher Instance { get; private set; } /// 平级注册对象,都会响应指令 List m_register = new List(); /// 独占注册对象,指令会被列表中最后一个对象独占 List m_registerHigh = new List(); ICommandListener m_listener; /// 标准UI操作 public IKeyMapperChanger Normal { get; private set; } /// 游戏中UI操作 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 bool IsRegisted(CommandExecuter commandExecuter) { return m_register.Contains(commandExecuter) || m_registerHigh.Contains(commandExecuter); } 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 oneFrameRegister = new List(); private void Update() { if (!InputUI.IsInputing) { 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 peekRegister(List 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 normal, out IReadOnlyList alone) { normal = m_register; alone = m_registerHigh; } #endif } }