using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Threading; using AssetBundleHub; using Cysharp.Threading.Tasks; using UnityEngine; namespace AssetBundleHubTests { public class MockDownload : IDownloadAsyncDecorator { public async UniTask DownloadAsync(IDownloadRequestContext context, CancellationToken cancellationToken, Func> next) { await UniTask.DelayFrame(10, cancellationToken: cancellationToken); return new DownloadResponseContext(); } } public class BundlePullContextFixture : IBundlePullContext { static string testDir = "Test/BundlePullContextFixture"; public AssetBundleList AssetBundleList { get; set; } public List AssetBundleNames { get; set; } public bool Shuffle { get; set; } = true; public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(10f); public IDownloadAsyncDecorator[] DownloadAsyncDecorators { get; set; } public Exception Error { get; set; } public string baseUrl = "https://teach310.github.io/AssetBundleHubSample/AssetBundles/StandaloneOSX/"; Dictionary downloadProgress = new Dictionary(); public List downloadedAssetBundles = new List(); public List tempAssetBundles = new List(); public List mergedAssetBundles = new List(); public bool broken = false; public string GetDestPath(string assetBundleName) { return testDir + "/Dest/" + assetBundleName; } public string GetTempSavePath(string assetBundleName) { return testDir + "/Temp/" + assetBundleName; } public string GetURL(string assetBundleName) { return baseUrl + assetBundleName; } public void SetDownloadedAssetBundle(string assetBundleName) { downloadedAssetBundles.Add(assetBundleName); tempAssetBundles.Add(assetBundleName); } public void SetDownloadProgress(string assetBundleName, float progress) { downloadProgress[assetBundleName] = progress; } public float CalcProgress() { ulong downloadSize = 0L; ulong downloadedSize = 0L; foreach (var abName in AssetBundleNames) { var abSize = AssetBundleList.Infos[abName].Size; downloadSize += (ulong)abSize; if (!downloadProgress.TryGetValue(abName, out float progress)) { continue; } if (Mathf.Approximately(progress, 1.0f)) { // ダウンロード済みなら計算を省略 downloadedSize += (ulong)abSize; } else if (progress > 0f) { // floatだとint最大値のときにはみ出すので8byteのdoubleを使用 downloadedSize += (ulong)(abSize * (double)progress); } } if (downloadSize == 0L) { return 0f; } return Mathf.Clamp01((float)(downloadedSize / (double)downloadSize)); } public static List DefaultAssetBundleNames() { return new List() { "Prefabs001", "Prefabs002", "Prefabs003" }; } public static BundlePullContextFixture Load(params IDownloadAsyncDecorator[] decorators) { var result = new BundlePullContextFixture() { AssetBundleList = AssetBundleListFixture.Load(), AssetBundleNames = DefaultAssetBundleNames() }; result.DownloadAsyncDecorators = decorators.Length != 0 ? decorators : DefaultDecorators(); return result; } static IDownloadAsyncDecorator[] DefaultDecorators() { return new IDownloadAsyncDecorator[] { new QueueRequestDecorator(runCapacity: 1), // テスト時には順番に実行したほうがテストがやりやすいためキャパを1にする new MockDownload() }; } public IEnumerable GetTempAssetBundles() { return tempAssetBundles; } public void ReportBrokenAssetBundle(string assetBundleName) { tempAssetBundles.Remove(assetBundleName); } public bool ExistsBrokenAssetBundle() => broken; public void SetMergedAssetBundle(string assetBundleName) { mergedAssetBundles.Add(assetBundleName); } public IEnumerable GetMergedAssetBundles() { return mergedAssetBundles; } public static void Clear() { if (Directory.Exists(testDir)) { Directory.Delete(testDir, true); } } } }