using System; using System.Collections; using System.Collections.Generic; using AibisDream.Framework; using UnityEngine; namespace AibisDream.Kit { public class ActionKitMonoBehaviourEvents : Singleton { public EasyEvent OnUpdate { get; private set; } private readonly EasyEvent _onFixedUpdate = new(); private readonly EasyEvent _onLateUpdate = new(); private readonly EasyEvent _onGUIEvent = new(); private readonly EasyEvent _onApplicationFocusEvent = new(); private readonly EasyEvent _onApplicationPauseEvent = new(); private readonly EasyEvent _onApplicationQuitEvent = new(); public override void OnSingletonInit() { hideFlags = HideFlags.HideInHierarchy; OnUpdate = new EasyEvent(); } public override void OnSingletonDestroy() { OnUpdate.UnRegisterAll(); } private void Update() { OnUpdate?.Trigger(); QueueUpdate(); } private void OnGUI() { _onGUIEvent?.Trigger(); } private void FixedUpdate() { _onFixedUpdate?.Trigger(); } private void LateUpdate() { _onLateUpdate?.Trigger(); } private void OnApplicationFocus(bool hasFocus) { _onApplicationFocusEvent?.Trigger(hasFocus); } private void OnApplicationPause(bool pauseStatus) { _onApplicationPauseEvent?.Trigger(pauseStatus); } private void OnApplicationQuit() { _onApplicationQuitEvent?.Trigger(); } public void ExecuteCoroutine(IEnumerator coroutine, Action onFinish) { StartCoroutine(DoExecuteCoroutine(coroutine, onFinish)); } IEnumerator DoExecuteCoroutine(IEnumerator coroutine, Action onFinish) { yield return coroutine; onFinish?.Invoke(); } #region ActionQueue移植 private readonly List _actionQueueCallbacks = new(); /// /// 确保存在可用的 实例。 /// 由于 不会自动创建对象,当场景里没有该组件时,某些 Action 的 Deinit 回收入队会触发 NRE。 /// private static ActionKitMonoBehaviourEvents EnsureInstance() { if (Instance != null) return Instance; if (!Application.isPlaying) return null; var go = new GameObject(nameof(ActionKitMonoBehaviourEvents)); DontDestroyOnLoad(go); return go.AddComponent(); } /// /// 获取或创建全局事件载体(用于 StartGlobal、回收队列等)。 /// public static ActionKitMonoBehaviourEvents GetOrCreate() { return EnsureInstance(); } public static void AddCallback(IActionQueueCallback actionQueueCallback) { var inst = EnsureInstance(); // 在退出/非运行态等情况下无法创建实例时,直接执行回调避免 NRE(回收/清理类回调通常是幂等的)。 if (inst == null) { actionQueueCallback?.Call(); return; } inst._actionQueueCallbacks.Add(actionQueueCallback); } // Update is called once per frame private void QueueUpdate() { if (_actionQueueCallbacks.Count > 0) { foreach (var actionQueueCallback in _actionQueueCallbacks) { actionQueueCallback.Call(); } _actionQueueCallbacks.Clear(); } } #endregion } }