using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AppleHills.Core.Settings;
using Core;
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;
LogDebugMessage("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);
LogDebugMessage("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
LogDebugMessage($"Executing late registration: {name} (Priority: {priority})");
try
{
action();
}
catch (Exception ex)
{
LogDebugMessage($"Error executing init action '{name}': {ex}");
}
}
else
{
// Otherwise add to the queue
_initializationActions.Add(initAction);
LogDebugMessage($"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
{
LogDebugMessage($"Executing: {action.Name} (Priority: {action.Priority})");
action.Action();
}
catch (Exception ex)
{
LogDebugMessage($"Error executing init action '{action.Name}': {ex}");
}
}
// Clear the list after execution
_initializationActions.Clear();
}
private static void LogDebugMessage(string message)
{
if (DeveloperSettingsProvider.Instance.GetSettings().bootstrapLogVerbosity <=
LogVerbosity.Debug)
{
Logging.Debug($"[BootCompletionService] {message}");
}
}
}
}