using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
namespace BrewMonster.Scripts
{
///
/// Single entry for after gate
/// (version fetch + optional ). Prevents early init from UI code
/// (e.g. AUIManager) hitting remote URLs before CDN rewrite.
///
public static class AddressablesInitService
{
static readonly object s_lock = new();
static UniTaskCompletionSource s_initTcs;
static bool s_initialized;
public static bool IsInitialized => s_initialized;
///
/// Waits bootstrap gate, then initializes Addressables once.
///
public static async UniTask EnsureInitializedAsync()
{
if (s_initialized)
return;
UniTaskCompletionSource waiter;
lock (s_lock)
{
if (s_initialized)
return;
if (s_initTcs != null)
{
waiter = s_initTcs;
}
else
{
waiter = new UniTaskCompletionSource();
s_initTcs = waiter;
}
}
if (waiter != s_initTcs)
{
await waiter.Task;
return;
}
try
{
await GameContentBootstrap.WaitForPreAddressablesSetupIfAnyAsync();
Debug.Log("[Cuong] AddressablesInitService: Bootstrap gate OK — InitializeAsync...");
var handle = Addressables.InitializeAsync();
await handle.ToUniTask();
if (handle.Status != AsyncOperationStatus.Succeeded)
{
var msg = handle.OperationException?.Message ?? "InitializeAsync failed";
waiter.TrySetException(new InvalidOperationException(msg));
lock (s_lock)
s_initTcs = null;
throw handle.OperationException ?? new InvalidOperationException(msg);
}
s_initialized = true;
waiter.TrySetResult(true);
Debug.Log("[Cuong] AddressablesInitService: InitializeAsync xong.");
}
catch (Exception ex)
{
if (!waiter.Task.Status.IsCompleted())
waiter.TrySetException(ex);
lock (s_lock)
s_initTcs = null;
throw;
}
}
///
/// Sync wait for legacy Init() paths. Prefer async when possible.
///
public static void EnsureInitializedBlocking()
{
EnsureInitializedAsync().GetAwaiter().GetResult();
}
}
}