using UnityEngine;
namespace Aliciza.Services
{
///
/// Mono 服务基类(不自动注册,适合需要手动控制注册时机的场景)。
///
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() { }
}
///
/// Mono 服务基类(自动注册到 )。
///
/// 场景服务:_dontDestroyOnLoad = false(默认),销毁时自动注销。
/// 跨场景服务:_dontDestroyOnLoad = true,首个实例持久化并注册;
/// 后续场景中出现的重复实例自动销毁自身。
///
///
/// 子类通过 执行额外的 Awake 逻辑,
/// 通过 执行注册后的初始化,
/// 通过 执行注销前的清理。
///
///
public abstract class MonoServiceBehaviour : MonoServiceBehaviour
where TScope : class
{
[SerializeField] private bool _dontDestroyOnLoad = false;
// 注意:使用 Start 而非 Awake 注册,确保 GameServiceRoot.Awake(创建 World)必然先于此执行。
// DefaultExecutionOrder 会影响所有生命周期(含 Awake),用 Start 可彻底规避执行顺序陷阱。
private void Awake()
{
if (_dontDestroyOnLoad)
DontDestroyOnLoad(gameObject);
OnAwake();
}
private void Start()
{
var scope = GameServices.GetOrCreateScope();
// 跨场景重复实例检测:契约已被占用则销毁自身
if (scope.HasContract(GetType()))
{
Destroy(gameObject);
return;
}
scope.Register(this);
}
private void OnDestroy()
{
if (!IsInitialized) return;
if (!GameServices.HasWorld) return;
if (!GameServices.TryGetScope(out var scope)) return;
scope.Unregister(this);
}
///
/// 在 Awake 阶段执行(早于 Start 中的自动注册)。
/// 适合缓存组件引用等不依赖服务系统的初始化。
///
protected virtual void OnAwake() { }
}
}