Files
aibis-dream/Assets/Scripts/Framework/ActionKit/ActionKitMonoBehaviourEvents.cs
T
2026-01-28 16:20:19 +08:00

134 lines
3.9 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using AibisDream.Framework;
using UnityEngine;
namespace AibisDream.Kit
{
public class ActionKitMonoBehaviourEvents : Singleton<ActionKitMonoBehaviourEvents>
{
public EasyEvent OnUpdate { get; private set; }
private readonly EasyEvent _onFixedUpdate = new();
private readonly EasyEvent _onLateUpdate = new();
private readonly EasyEvent _onGUIEvent = new();
private readonly EasyEvent<bool> _onApplicationFocusEvent = new();
private readonly EasyEvent<bool> _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<IActionQueueCallback> _actionQueueCallbacks = new();
/// <summary>
/// 确保存在可用的 <see cref="ActionKitMonoBehaviourEvents"/> 实例。
/// 由于 <see cref="Singleton{T}"/> 不会自动创建对象,当场景里没有该组件时,某些 Action 的 Deinit 回收入队会触发 NRE。
/// </summary>
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<ActionKitMonoBehaviourEvents>();
}
/// <summary>
/// 获取或创建全局事件载体(用于 StartGlobal、回收队列等)。
/// </summary>
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
}
}