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; OnInitialize(); } void IService.Destroy() { if (!IsInitialized) return; OnDestroyService(); IsInitialized = false; Context = default; } protected virtual void OnInitialize() { } protected virtual void OnDestroyService() { } } public abstract class MonoServiceBehaviour : MonoServiceBehaviour where TScope : IScope { [SerializeField] private bool _dontDestroyOnLoad = false; private void Awake() { OnAwake(); } private void Start() { var scope = ResolveOrCreateScope(); 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 (!TryResolveScope(out var scope)) return; scope.Unregister(this); } 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; } protected virtual void OnAwake() { } } }