using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using UnityEngine; namespace Bootstrap { /// /// Service that provides notification and management of boot completion status. /// Allows systems to subscribe to boot completion events, register initialization actions with priorities, /// or await boot completion asynchronously. /// public static class BootCompletionService { /// /// Indicates if the boot process has completed /// public static bool IsBootComplete { get; private set; } = false; /// /// Event triggered when boot completes /// public static event Action OnBootComplete; /// /// Represents an initialization action with priority /// private class InitializationAction { public Action Action { get; } public int Priority { get; } public string Name { get; } public InitializationAction(Action action, int priority, string name) { Action = action; Priority = priority; Name = name; } } // List of initialization actions to be executed once boot completes private static List _initializationActions = new List(); // TaskCompletionSource for async await pattern private static TaskCompletionSource _bootCompletionTask = new TaskCompletionSource(); /// /// Called by CustomBoot when the boot process is complete /// internal static void HandleBootCompleted() { if (IsBootComplete) return; IsBootComplete = true; Debug.Log("[BootCompletionService] Boot process completed, executing initialization actions"); // Execute initialization actions in priority order (lower number = higher priority) ExecuteInitializationActions(); // Trigger the event OnBootComplete?.Invoke(); // Complete the task for async waiters _bootCompletionTask.TrySetResult(true); Debug.Log("[BootCompletionService] All boot completion handlers executed"); } /// /// Register an action to be executed when boot completes. /// Lower priority numbers run first. /// /// The action to execute /// Priority (lower numbers run first) /// Name for debugging public static void RegisterInitAction(Action action, int priority = 100, string name = null) { if (action == null) return; if (string.IsNullOrEmpty(name)) name = $"Action_{_initializationActions.Count}"; var initAction = new InitializationAction(action, priority, name); if (IsBootComplete) { // If boot is already complete, execute immediately Debug.Log($"[BootCompletionService] Executing late registration: {name} (Priority: {priority})"); try { action(); } catch (Exception ex) { Debug.LogError($"[BootCompletionService] Error executing init action '{name}': {ex}"); } } else { // Otherwise add to the queue _initializationActions.Add(initAction); Debug.Log($"[BootCompletionService] Registered init action: {name} (Priority: {priority})"); } } /// /// Wait asynchronously for boot completion /// /// Task that completes when boot is complete public static Task WaitForBootCompletionAsync() { if (IsBootComplete) return Task.CompletedTask; return _bootCompletionTask.Task; } /// /// Execute all registered initialization actions in priority order /// private static void ExecuteInitializationActions() { // Sort by priority (lowest first) var sortedActions = _initializationActions .OrderBy(a => a.Priority) .ToList(); foreach (var action in sortedActions) { try { Debug.Log($"[BootCompletionService] Executing: {action.Name} (Priority: {action.Priority})"); action.Action(); } catch (Exception ex) { Debug.LogError($"[BootCompletionService] Error executing init action '{action.Name}': {ex}"); } } // Clear the list after execution _initializationActions.Clear(); } } }