using System; using System.Collections; using System.Collections.Generic; #if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; using UnityEngine.UIElements; namespace BITKit.UX { /// /// 适用于Unity的UX Service /// public class UXService : MonoBehaviour, IUXService { [RuntimeInitializeOnLoadMethod] private static void Initialized() { RegistryQueue.Clear(); UnRegistryQueue.Clear(); Panels.Clear(); EntryQueue.Clear(); EntryCompletedPanels.Clear(); History.Clear(); } /// /// 内部注册面板队列 /// private static readonly Queue RegistryQueue = new(); /// /// 内部注销面板队列 /// private static readonly Queue UnRegistryQueue = new(); /// /// 已注册面板字典 /// internal static readonly Dictionary Panels = new(); /// /// 等待启用的面板队列 /// private static readonly Stack EntryQueue = new(); /// /// 已启用面板 /// internal static readonly Stack EntryCompletedPanels = new(); /// /// 历史面板 /// private static readonly Stack History = new(); public static void Register(IUXPanel panel) => RegistryQueue.Enqueue(panel); public static void UnRegister(IUXPanel panel) => UnRegistryQueue.Enqueue(panel); public static void Entry() where T : IUXPanel => EntryQueue.Push(Panels[typeof(T).Name]); public static void Return() { if (!History.TryPop(out _)) return; if (History.TryPop(out var returnPanel)) { Entry(returnPanel); } } public static void Entry(IUXPanel panel) => EntryQueue.Push(panel); public static void Entry(string panelName) => EntryQueue.Push(Panels[panelName]); [SerializeReference, SubclassSelector] private IUXPanel initialPanel; private bool initialized; private void Awake() { DI.Register(this); } private void Update() { while (UnRegistryQueue.TryDequeue(out var result)) { if (result is null) continue; Panels.Remove(result.Index); } while (RegistryQueue.TryDequeue(out var result)) { if (result is null) continue; Panels.Set(result.Index, result); result.Exit(); } if (initialized is false && initialPanel is not null) { initialized = true; Entry(initialPanel); } if (!EntryQueue.TryPop(out var next)) return; while (EntryCompletedPanels.TryPop(out var entryCompletedPanel)) { entryCompletedPanel?.Exit(); } next.Entry(); BITAppForUnity.AllowCursor.SetElements(this, next.AllowCursor); BITInputSystem.AllowInput.SetElements(this, next.AllowInput); EntryCompletedPanels.Push(next); History.Push(next); } void IUXService.Register(IUXPanel panel) => Register(panel); void IUXService.UnRegister(IUXPanel panel) => UnRegister(panel); void IUXService.Entry() => Entry(); void IUXService.Return() => Return(); void IUXService.Entry(IUXPanel panel) => Entry(panel); void IUXService.Entry(string panelName) => Entry(panelName); } #if UNITY_EDITOR [CustomEditor(typeof(UXService))] public class UXServiceInspector:BITInspector { private Label currentPanelLabel; private Label panelsLabel; public override VisualElement CreateInspectorGUI() { FillDefaultInspector(); CreateSubTitle("States"); currentPanelLabel = root.Create