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

111 lines
3.2 KiB
C#
Raw Normal View History

using Cysharp.Text;
2026-03-26 10:49:41 +08:00
using UnityEngine;
namespace AlicizaX
{
2026-04-20 13:46:44 +08:00
public abstract class MonoServiceBehaviour : MonoBehaviour, IMonoService, IServiceLifecycle
2026-03-26 10:49:41 +08:00
{
2026-04-20 13:46:44 +08:00
protected ServiceContext Context { get; private set; }
2026-03-26 10:49:41 +08:00
2026-04-20 13:46:44 +08:00
protected bool IsInitialized { get; private set; }
2026-03-26 10:49:41 +08:00
2026-04-20 13:46:44 +08:00
void IServiceLifecycle.Initialize(ServiceContext context)
2026-03-26 10:49:41 +08:00
{
if (IsInitialized)
throw new System.InvalidOperationException(ZString.Format("{0} is already initialized.", GetType().FullName));
2026-03-26 10:49:41 +08:00
Context = context;
IsInitialized = true;
2026-03-26 19:55:46 +08:00
OnInitialize();
2026-03-26 10:49:41 +08:00
}
2026-04-20 13:46:44 +08:00
void IServiceLifecycle.Destroy()
2026-03-26 10:49:41 +08:00
{
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()
{
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);
scope.RegisterSelf(this);
2026-03-26 10:49:41 +08:00
}
private void OnDestroy()
{
if (!IsInitialized) return;
if (!AppServices.HasWorld) return;
if (!TryResolveScope(out var scope)) return;
2026-03-26 10:49:41 +08:00
scope.Unregister(this);
}
private static ServiceScope ResolveOrCreateScope()
{
var kind = ScopeKindCache<TScope>.Kind;
if (kind == ServiceScopeKind.App) return AppServices.RequireWorld().App;
if (kind == ServiceScopeKind.Scene) return AppServices.EnsureScene();
return AppServices.EnsureGameplay();
}
private static bool TryResolveScope(out ServiceScope scope)
{
var kind = ScopeKindCache<TScope>.Kind;
if (kind == ServiceScopeKind.App)
{
2026-04-20 13:46:44 +08:00
scope = AppServices.RequireWorld().App;
return true;
}
if (kind == ServiceScopeKind.Scene)
return AppServices.TryGetScene(out scope);
return AppServices.TryGetGameplay(out scope);
}
2026-03-26 10:49:41 +08:00
protected virtual void OnAwake() { }
}
internal static class ScopeKindCache<TScope>
where TScope : IScope
{
public static readonly ServiceScopeKind Kind = Resolve();
private static ServiceScopeKind Resolve()
{
if (typeof(TScope) == typeof(AppScope)) return ServiceScopeKind.App;
if (typeof(TScope) == typeof(SceneScope)) return ServiceScopeKind.Scene;
if (typeof(TScope) == typeof(GameplayScope)) return ServiceScopeKind.Gameplay;
throw new System.InvalidOperationException(ZString.Format("Unsupported service scope: {0}.", typeof(TScope).FullName));
}
}
2026-03-26 10:49:41 +08:00
}