com.alicizax.unity.framework/Runtime/ABase/Base/Service/Unity/MonoServiceBehaviour.cs

99 lines
2.9 KiB
C#

using UnityEngine;
namespace AlicizaX
{
/// <summary>
/// Mono 服务基类(不自动注册,适合需要手动控制注册时机的场景)。
/// </summary>
public abstract class MonoServiceBehaviour : MonoBehaviour, IMonoService
{
public ServiceContext Context { get; private set; }
public bool IsInitialized { get; private set; }
protected ServiceWorld World => Context.World;
protected ServiceScope Scope => Context.Scope;
void IService.Initialize(ServiceContext context)
{
if (IsInitialized)
throw new System.InvalidOperationException($"{GetType().FullName} is already initialized.");
Context = context;
IsInitialized = true;
OnServiceInitialize();
}
void IService.Destroy()
{
if (!IsInitialized) return;
OnServiceDestroy();
IsInitialized = false;
Context = default;
}
protected virtual void OnServiceInitialize() { }
protected virtual void OnServiceDestroy() { }
}
/// <summary>
/// Mono 服务基类(自动注册到 <typeparamref name="TScope"/>)。
/// <para>
/// 场景服务:<c>_dontDestroyOnLoad = false</c>(默认),销毁时自动注销。<br/>
/// 跨场景服务:<c>_dontDestroyOnLoad = true</c>,首个实例持久化并注册;
/// 后续场景中出现的重复实例自动销毁自身。
/// </para>
/// <para>
/// 子类通过 <see cref="OnAwake"/> 执行额外的 Awake 逻辑,
/// 通过 <see cref="OnServiceInitialize"/> 执行注册后的初始化,
/// 通过 <see cref="OnServiceDestroy"/> 执行注销前的清理。
/// </para>
/// </summary>
public abstract class MonoServiceBehaviour<TScope> : MonoServiceBehaviour
where TScope : class
{
[SerializeField] private bool _dontDestroyOnLoad = false;
private void Awake()
{
OnAwake();
}
private void Start()
{
var scope = AppServices.GetOrCreateScope<TScope>();
// 跨场景重复实例检测:契约已被占用则销毁自身
if (scope.HasContract(GetType()))
{
Destroy(gameObject);
return;
}
if (_dontDestroyOnLoad)
DontDestroyOnLoad(gameObject);
scope.Register(this);
}
private void OnDestroy()
{
if (!IsInitialized) return;
if (!AppServices.HasWorld) return;
if (!AppServices.TryGetScope<TScope>(out var scope)) return;
scope.Unregister(this);
}
/// <summary>
/// 在 Awake 阶段执行(早于 Start 中的自动注册)。
/// 适合缓存组件引用等不依赖服务系统的初始化。
/// </summary>
protected virtual void OnAwake() { }
}
}