168 lines
5.1 KiB
C#
168 lines
5.1 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
namespace VersionFlow.Runtime
|
|
{
|
|
public class OptionalBundleDownloader
|
|
{
|
|
/// <summary> 总体积,字节数 </summary>
|
|
public ulong TotalSize { get; private set; }
|
|
|
|
private ulong m_downloadedBytes;
|
|
/// <summary> 已下载字节数 </summary>
|
|
public ulong DownloadedBytes
|
|
{
|
|
get
|
|
{
|
|
ulong downloadingBytes = 0;
|
|
|
|
if (m_downloadingAB != null && m_downloadingAB.IsDownloading)
|
|
{
|
|
downloadingBytes = m_downloadingAB.abAsyncDownloader.downloadingBytes;
|
|
}
|
|
|
|
return m_downloadedBytes + downloadingBytes;
|
|
}
|
|
set => m_downloadedBytes = value;
|
|
}
|
|
|
|
private ABEntity m_downloadingAB;
|
|
|
|
EnumDownloadState m_state;
|
|
/// <summary> 下载器状态 </summary>
|
|
public EnumDownloadState State
|
|
{
|
|
get => m_state;
|
|
set
|
|
{
|
|
if (m_state == value) return;
|
|
|
|
m_state = value;
|
|
OnStateChange?.Invoke();
|
|
}
|
|
}
|
|
public string Group { get; private set; }
|
|
private List<ABEntity> entities = new List<ABEntity>();
|
|
|
|
public Action OnStateChange;
|
|
|
|
public OptionalBundleDownloader(string group)
|
|
{
|
|
Group = group;
|
|
}
|
|
|
|
public void CollectAB(ABEntity abEntity)
|
|
{
|
|
entities.Add(abEntity);
|
|
}
|
|
|
|
internal void CalcState()
|
|
{
|
|
//收集依赖的AB
|
|
HashSet<ABEntity> temp = new HashSet<ABEntity>(entities);
|
|
foreach (var entity in entities)
|
|
{
|
|
foreach (var depAB in entity.m_dependencyAB)
|
|
temp.Add(depAB);
|
|
}
|
|
entities = temp.ToList();
|
|
|
|
foreach (var entity in entities)
|
|
{
|
|
TotalSize += (ulong)entity.m_manifestBundleInfo.Size;
|
|
if (entity.m_isDownloaded)
|
|
DownloadedBytes += (ulong)entity.m_manifestBundleInfo.Size;
|
|
}
|
|
|
|
if (DownloadedBytes == TotalSize)
|
|
State = EnumDownloadState.Complete;
|
|
else
|
|
State = EnumDownloadState.Idle;
|
|
}
|
|
|
|
private Coroutine m_downloadingFlow;
|
|
public void BeginDownload()
|
|
{
|
|
if (State == EnumDownloadState.Downloading || State == EnumDownloadState.Complete) return;
|
|
|
|
m_downloadingFlow = VersionFlowX.BeginCoroutine(DownloadFlow());
|
|
}
|
|
|
|
public void CancelDownload()
|
|
{
|
|
if (State != EnumDownloadState.Downloading) return;
|
|
if (m_downloadingFlow == null) return;
|
|
|
|
VersionFlowX.Stop(m_downloadingFlow);
|
|
if (m_downloadingAB != null && m_downloadingAB.IsDownloading)
|
|
{
|
|
m_downloadingAB.abAsyncDownloader.Cancel();
|
|
}
|
|
}
|
|
|
|
private IEnumerator DownloadFlow()
|
|
{
|
|
State = EnumDownloadState.Downloading;
|
|
|
|
while (true)
|
|
{
|
|
m_downloadingAB = entities.FirstOrDefault(ab => !ab.m_isDownloaded);
|
|
if (m_downloadingAB == null)
|
|
{
|
|
State = EnumDownloadState.Complete;
|
|
yield break;
|
|
}
|
|
|
|
if (m_downloadingAB.IsDownloading)
|
|
yield return new WaitUntil(() =>
|
|
{
|
|
return !m_downloadingAB.IsDownloading;
|
|
});
|
|
else
|
|
{
|
|
m_downloadingAB.abAsyncDownloader = VersionFlowX.DownloadBundleAsync(m_downloadingAB.m_manifestBundleInfo);
|
|
yield return m_downloadingAB.abAsyncDownloader;
|
|
if (m_downloadingAB.abAsyncDownloader.Success)
|
|
{
|
|
m_downloadingAB.m_isDownloaded = true;
|
|
m_downloadingAB.abAsyncDownloader = null;
|
|
}
|
|
else
|
|
{
|
|
var msg = m_downloadingAB.abAsyncDownloader.Error;
|
|
m_downloadingAB.abAsyncDownloader = null;
|
|
State = EnumDownloadState.Idle;
|
|
m_downloadingAB = null;
|
|
m_downloadingFlow = null;
|
|
|
|
throw new System.Exception($"下载 AB {this} 失败 \n {msg}");
|
|
}
|
|
}
|
|
|
|
DownloadedBytes += (ulong)m_downloadingAB.m_manifestBundleInfo.Size;
|
|
m_downloadingAB = null;
|
|
}
|
|
}
|
|
|
|
public static string GetByteSizeString(ulong byteCount)
|
|
{
|
|
if (byteCount < 1024) return $"{byteCount}B";
|
|
|
|
if (byteCount < 1024 * 1024) return $"{byteCount / (1024f):.00}KB";
|
|
|
|
else return $"{byteCount / (1024f * 1024):.00}MB";
|
|
}
|
|
|
|
|
|
public enum EnumDownloadState
|
|
{
|
|
Idle,
|
|
Downloading,
|
|
Complete
|
|
}
|
|
}
|
|
}
|