2026-03-26 10:49:41 +08:00
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
namespace AlicizaX
|
|
|
|
|
{
|
|
|
|
|
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;
|
2026-03-26 19:55:46 +08:00
|
|
|
OnInitialize();
|
2026-03-26 10:49:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void IService.Destroy()
|
|
|
|
|
{
|
|
|
|
|
if (!IsInitialized) return;
|
|
|
|
|
|
2026-03-26 19:55:46 +08:00
|
|
|
OnDestroyService();
|
2026-03-26 10:49:41 +08:00
|
|
|
IsInitialized = false;
|
|
|
|
|
Context = default;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 19:55:46 +08:00
|
|
|
protected virtual void OnInitialize() { }
|
2026-03-26 10:49:41 +08:00
|
|
|
|
2026-03-26 19:55:46 +08:00
|
|
|
protected virtual void OnDestroyService() { }
|
2026-03-26 10:49:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public abstract class MonoServiceBehaviour<TScope> : MonoServiceBehaviour
|
2026-03-26 19:50:59 +08:00
|
|
|
where TScope : IScope
|
2026-03-26 10:49:41 +08:00
|
|
|
{
|
|
|
|
|
[SerializeField] private bool _dontDestroyOnLoad = false;
|
|
|
|
|
|
|
|
|
|
private void Awake()
|
|
|
|
|
{
|
|
|
|
|
OnAwake();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Start()
|
|
|
|
|
{
|
2026-03-31 17:25:20 +08:00
|
|
|
var scope = ResolveOrCreateScope();
|
2026-03-26 10:49:41 +08:00
|
|
|
|
|
|
|
|
if (scope.HasContract(GetType()))
|
|
|
|
|
{
|
|
|
|
|
Destroy(gameObject);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 13:51:09 +08:00
|
|
|
if (_dontDestroyOnLoad)
|
|
|
|
|
DontDestroyOnLoad(gameObject);
|
|
|
|
|
|
2026-03-26 10:49:41 +08:00
|
|
|
scope.Register(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnDestroy()
|
|
|
|
|
{
|
|
|
|
|
if (!IsInitialized) return;
|
|
|
|
|
if (!AppServices.HasWorld) return;
|
2026-03-31 17:25:20 +08:00
|
|
|
if (!TryResolveScope(out var scope)) return;
|
2026-03-26 10:49:41 +08:00
|
|
|
|
|
|
|
|
scope.Unregister(this);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 17:25:20 +08:00
|
|
|
private static ServiceScope ResolveOrCreateScope()
|
|
|
|
|
{
|
|
|
|
|
if (typeof(TScope) == typeof(AppScope))
|
|
|
|
|
return AppServices.App;
|
|
|
|
|
|
|
|
|
|
if (typeof(TScope) == typeof(SceneScope))
|
|
|
|
|
return AppServices.EnsureScene();
|
|
|
|
|
|
|
|
|
|
if (typeof(TScope) == typeof(GameplayScope))
|
|
|
|
|
return AppServices.EnsureGameplay();
|
|
|
|
|
|
|
|
|
|
throw new System.InvalidOperationException($"Unsupported service scope: {typeof(TScope).FullName}.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static bool TryResolveScope(out ServiceScope scope)
|
|
|
|
|
{
|
|
|
|
|
if (typeof(TScope) == typeof(AppScope))
|
|
|
|
|
{
|
|
|
|
|
scope = AppServices.App;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typeof(TScope) == typeof(SceneScope))
|
|
|
|
|
return AppServices.TryGetScene(out scope);
|
|
|
|
|
|
|
|
|
|
if (typeof(TScope) == typeof(GameplayScope))
|
|
|
|
|
return AppServices.TryGetGameplay(out scope);
|
|
|
|
|
|
|
|
|
|
scope = null;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 10:49:41 +08:00
|
|
|
protected virtual void OnAwake() { }
|
|
|
|
|
}
|
|
|
|
|
}
|