#nullable enable using System; using Cysharp.Threading.Tasks; using UnityEngine; namespace ShrinkApp { public static class ShrinkApp { public static ShrinkAppHost? Host { get; private set; } public static ShrinkAppContext? Context { get; private set; } public static ShrinkAppSettings Settings => ShrinkAppSettings.Instance; public static ShrinkAppServices Services => Context?.Services ?? throw new System.InvalidOperationException("ShrinkApp is not initialized."); public static bool IsRunning => (Host != null && Host.IsRunning) || _externalHostRunning; private static bool _externalHostRunning; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void ResetStaticState() { Host = null; Context = null; _externalHostRunning = false; ShrinkAppSettings.ResetCachedInstance(); } [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] private static void Bootstrap() { if (Host != null) return; var settings = ShrinkAppSettings.Instance; if (settings.hostingMode == ShrinkAppHostingMode.ContextLoader) { // 阶段 2 过渡:经典宿主让位,由 ShrinkContext 加载器宿主(ShrinkContext.AppAdapter)接管启动 return; } var hostGameObject = new GameObject("ShrinkAppHost"); var host = hostGameObject.AddComponent(); if (settings.dontDestroyOnLoad) UnityEngine.Object.DontDestroyOnLoad(hostGameObject); var services = new ShrinkAppServices(); var context = new ShrinkAppContext(host, settings, services); host.Configure(context); Host = host; Context = context; host.StartAppAsync().Forget(ex => { Debug.LogException(ex); Debug.LogError("[ShrinkApp] 启动失败: " + ex.Message); }); } /// /// 阶段 2 过渡:由外部宿主(如 ShrinkContext 加载器宿主)提供已初始化的服务容器。 /// Host 保持 null——外部宿主不经过 ShrinkAppHost 生命周期,IsRunning 以外部宿主为准。 /// public static void InitializeForExternalHost(ShrinkAppServices services, ShrinkAppSettings? settings = null) { if (services == null) throw new ArgumentNullException(nameof(services)); Context = new ShrinkAppContext(null!, settings ?? Settings, services); _externalHostRunning = false; } /// /// Lets a non- orchestrator expose its lifecycle through /// the legacy static facade while the migration is in progress. /// public static void SetExternalHostRunning(bool running) { _externalHostRunning = running; } } }