2025-10-16 19:43:19 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Threading.Tasks;
|
2025-10-28 14:31:17 +01:00
|
|
|
|
using AppleHills.Core.Settings;
|
|
|
|
|
|
using Core;
|
2025-10-16 19:43:19 +02:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Bootstrap
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 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.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static class BootCompletionService
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Indicates if the boot process has completed
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static bool IsBootComplete { get; private set; } = false;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Event triggered when boot completes
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static event Action OnBootComplete;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Represents an initialization action with priority
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
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<InitializationAction> _initializationActions = new List<InitializationAction>();
|
|
|
|
|
|
|
|
|
|
|
|
// TaskCompletionSource for async await pattern
|
|
|
|
|
|
private static TaskCompletionSource<bool> _bootCompletionTask = new TaskCompletionSource<bool>();
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Called by CustomBoot when the boot process is complete
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
internal static void HandleBootCompleted()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsBootComplete)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
IsBootComplete = true;
|
|
|
|
|
|
|
2025-10-28 14:31:17 +01:00
|
|
|
|
LogDebugMessage("Boot process completed, executing initialization actions");
|
2025-10-16 19:43:19 +02:00
|
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
|
|
2025-10-28 14:31:17 +01:00
|
|
|
|
LogDebugMessage("All boot completion handlers executed");
|
2025-10-16 19:43:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Register an action to be executed when boot completes.
|
|
|
|
|
|
/// Lower priority numbers run first.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="action">The action to execute</param>
|
|
|
|
|
|
/// <param name="priority">Priority (lower numbers run first)</param>
|
|
|
|
|
|
/// <param name="name">Name for debugging</param>
|
|
|
|
|
|
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
|
2025-10-28 14:31:17 +01:00
|
|
|
|
LogDebugMessage($"Executing late registration: {name} (Priority: {priority})");
|
2025-10-16 19:43:19 +02:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
action();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
2025-10-28 14:31:17 +01:00
|
|
|
|
LogDebugMessage($"Error executing init action '{name}': {ex}");
|
2025-10-16 19:43:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Otherwise add to the queue
|
|
|
|
|
|
_initializationActions.Add(initAction);
|
2025-10-28 14:31:17 +01:00
|
|
|
|
LogDebugMessage($"Registered init action: {name} (Priority: {priority})");
|
2025-10-16 19:43:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Wait asynchronously for boot completion
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>Task that completes when boot is complete</returns>
|
|
|
|
|
|
public static Task WaitForBootCompletionAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsBootComplete)
|
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
|
|
|
|
|
|
|
return _bootCompletionTask.Task;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Execute all registered initialization actions in priority order
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private static void ExecuteInitializationActions()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Sort by priority (lowest first)
|
|
|
|
|
|
var sortedActions = _initializationActions
|
|
|
|
|
|
.OrderBy(a => a.Priority)
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var action in sortedActions)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2025-10-28 14:31:17 +01:00
|
|
|
|
LogDebugMessage($"Executing: {action.Name} (Priority: {action.Priority})");
|
2025-10-16 19:43:19 +02:00
|
|
|
|
action.Action();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
2025-10-28 14:31:17 +01:00
|
|
|
|
LogDebugMessage($"Error executing init action '{action.Name}': {ex}");
|
2025-10-16 19:43:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Clear the list after execution
|
|
|
|
|
|
_initializationActions.Clear();
|
|
|
|
|
|
}
|
2025-10-28 14:31:17 +01:00
|
|
|
|
|
|
|
|
|
|
private static void LogDebugMessage(string message)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DeveloperSettingsProvider.Instance.GetSettings<DebugSettings>().bootstrapLogVerbosity <=
|
|
|
|
|
|
LogVerbosity.Debug)
|
|
|
|
|
|
{
|
|
|
|
|
|
Logging.Debug($"[BootCompletionService] {message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-16 19:43:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|