diff --git a/Assets/Scripts/Bootstrap/BootCompletionService.cs b/Assets/Scripts/Bootstrap/BootCompletionService.cs index 60015087..71be1e09 100644 --- a/Assets/Scripts/Bootstrap/BootCompletionService.cs +++ b/Assets/Scripts/Bootstrap/BootCompletionService.cs @@ -1,166 +1,150 @@ -using System; +using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using UnityEngine; namespace Bootstrap { /// - /// A service that provides information about the boot completion status - /// and allows systems to register for callbacks when boot is complete. + /// 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 { /// - /// True if the boot process has fully completed + /// Indicates if the boot process has completed /// - public static bool IsBootComplete { get; private set; } + public static bool IsBootComplete { get; private set; } = false; /// - /// Timestamp when the boot completed (Time.realtimeSinceStartup) - /// - public static float BootCompletionTime { get; private set; } - - /// - /// Event triggered when boot process completes. - /// Will be triggered immediately for new subscribers if boot is already complete. + /// Event triggered when boot completes /// public static event Action OnBootComplete; /// - /// Actions to be executed in a specific order once boot completes + /// Represents an initialization action with priority /// - private static readonly List _orderedInitActions = new List(); - - /// - /// Task completion source for async boot completion waiting - /// - private static TaskCompletionSource _bootCompletionTask; - - /// - /// Initialize the service - called by CustomBoot - /// - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] - private static void Initialize() + private class InitializationAction { - // Reset state - IsBootComplete = false; - _bootCompletionTask = new TaskCompletionSource(); + public Action Action { get; } + public int Priority { get; } + public string Name { get; } - // Subscribe to CustomBoot completion event - CustomBoot.OnBootCompleted += HandleBootCompleted; - - Debug.Log("[BootCompletionService] Initialized and waiting for boot completion"); + 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(); + /// - /// Handler for when CustomBoot reports completion + /// Called by CustomBoot when the boot process is complete /// - private static void HandleBootCompleted() + internal static void HandleBootCompleted() { - if (IsBootComplete) return; // Avoid duplicate triggers + if (IsBootComplete) + return; IsBootComplete = true; - BootCompletionTime = Time.realtimeSinceStartup; - Debug.Log($"[BootCompletionService] Boot completed at {BootCompletionTime:F2}s since startup"); + Debug.Log("[BootCompletionService] Boot process completed, executing initialization actions"); - // Execute ordered initialization actions - ExecuteOrderedInitActions(); - - // Complete the task - _bootCompletionTask.TrySetResult(true); + // 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"); } /// - /// Execute the registered ordered initialization actions - /// - private static void ExecuteOrderedInitActions() - { - // Sort actions by priority - _orderedInitActions.Sort((a, b) => a.Priority.CompareTo(b.Priority)); - - foreach (var action in _orderedInitActions) - { - try - { - Debug.Log($"[BootCompletionService] Executing priority {action.Priority} initialization: {action.Name}"); - action.Action?.Invoke(); - } - catch (Exception e) - { - Debug.LogError($"[BootCompletionService] Error executing initialization action '{action.Name}': {e.Message}\n{e.StackTrace}"); - } - } - - // Clear the list after execution - _orderedInitActions.Clear(); - } - - /// - /// Register an action to be executed when boot is complete. - /// If boot is already complete, the action will execute immediately. + /// Register an action to be executed when boot completes. + /// Lower priority numbers run first. /// /// The action to execute - /// Lower numbers execute first (default: 100) - /// Optional name for debugging + /// 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 (action == null) + return; - name = name ?? $"Anonymous_{_orderedInitActions.Count}"; + if (string.IsNullOrEmpty(name)) + name = $"Action_{_initializationActions.Count}"; + + var initAction = new InitializationAction(action, priority, name); if (IsBootComplete) { - // Boot already completed, execute immediately - Debug.Log($"[BootCompletionService] Executing late initialization: {name} (boot already complete)"); + // If boot is already complete, execute immediately + Debug.Log($"[BootCompletionService] Executing late registration: {name} (Priority: {priority})"); try { - action.Invoke(); + action(); } - catch (Exception e) + catch (Exception ex) { - Debug.LogError($"[BootCompletionService] Error executing late initialization action '{name}': {e.Message}\n{e.StackTrace}"); + Debug.LogError($"[BootCompletionService] Error executing init action '{name}': {ex}"); } } else { - // Add to ordered list - _orderedInitActions.Add(new OrderedInitAction - { - Action = action, - Priority = priority, - Name = name - }); - Debug.Log($"[BootCompletionService] Registered initialization action: {name} with priority {priority}"); + // Otherwise add to the queue + _initializationActions.Add(initAction); + Debug.Log($"[BootCompletionService] Registered init action: {name} (Priority: {priority})"); } } /// - /// Returns a task that completes when the boot process is complete. - /// If boot is already complete, returns a completed task. + /// Wait asynchronously for boot completion /// + /// Task that completes when boot is complete public static Task WaitForBootCompletionAsync() { if (IsBootComplete) - { return Task.CompletedTask; - } - + return _bootCompletionTask.Task; } /// - /// Structure for ordered initialization actions + /// Execute all registered initialization actions in priority order /// - private class OrderedInitAction + private static void ExecuteInitializationActions() { - public Action Action; - public int Priority; - public string Name; + // 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(); } } }