348 lines
10 KiB
C#
348 lines
10 KiB
C#
|
namespace Thousandto.Update.Download
|
|||
|
{
|
|||
|
using Thousandto.Update.Data;
|
|||
|
using System;
|
|||
|
|
|||
|
public class DataPool<T> where T: new()
|
|||
|
{
|
|||
|
//高优先级下载队列
|
|||
|
private SyncQueue<T> _highPriorityQueue;
|
|||
|
//下载失败的数据,在高优先级队列前自动下载
|
|||
|
private SyncQueue<T> _highPriorityFailQueue;
|
|||
|
//当前场景的下载队列
|
|||
|
private SyncQueue<T> _curSceneQueue;
|
|||
|
//下载失败的数据,在当前场景下载前自动下载
|
|||
|
private SyncQueue<T> _curSceneFailQueue;
|
|||
|
//下一场景的预下载队列
|
|||
|
private SyncQueue<T> _nextSceneQueue;
|
|||
|
//下载失败的数据,在预下载队列前自动下载
|
|||
|
private SyncQueue<T> _nextSceneFailQueue;
|
|||
|
//低优先级,静默下载队列
|
|||
|
private SyncQueue<T> _lowQueue;
|
|||
|
//下载失败的数据,在静默下载队列前下载
|
|||
|
private SyncQueue<T> _lowFailQueue;
|
|||
|
|
|||
|
//下载失败的数据,非中断操作和切换网络操作造成的
|
|||
|
//在合适的时间,自动做下载(比如所有资源下载完成后)
|
|||
|
private SyncQueue<T> _allFailQueue;
|
|||
|
|
|||
|
private object _lockObj;
|
|||
|
|
|||
|
//暂停低优先级队列,即总资源队列
|
|||
|
private bool _pauseLowQueue;
|
|||
|
//暂停当前场景
|
|||
|
private bool _pauseCurSceneQueue;
|
|||
|
//暂停下一个场景队列
|
|||
|
private bool _pauseNextSceneQueue;
|
|||
|
//暂停高优先级队列
|
|||
|
private bool _pauseHighPriorityQueue;
|
|||
|
|
|||
|
public DataPool()
|
|||
|
{
|
|||
|
_lockObj = new object();
|
|||
|
|
|||
|
_highPriorityQueue = new SyncQueue<T>();
|
|||
|
_highPriorityFailQueue = new SyncQueue<T>();
|
|||
|
|
|||
|
_curSceneQueue = new SyncQueue<T>();
|
|||
|
_curSceneFailQueue = new SyncQueue<T>();
|
|||
|
|
|||
|
_nextSceneQueue = new SyncQueue<T>();
|
|||
|
_nextSceneFailQueue = new SyncQueue<T>();
|
|||
|
|
|||
|
_lowQueue = new SyncQueue<T>();
|
|||
|
_lowFailQueue = new SyncQueue<T>();
|
|||
|
|
|||
|
_allFailQueue = new SyncQueue<T>();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 添加数据 level:数据类型 fail:是否下载失败的数据
|
|||
|
/// </summary>
|
|||
|
/// <param name="data"></param>
|
|||
|
/// <param name="level"></param>
|
|||
|
/// <param name="fail"></param>
|
|||
|
internal void AddData(T data, DataLevel level, bool fail = false)
|
|||
|
{
|
|||
|
lock (this._lockObj)
|
|||
|
{
|
|||
|
switch (level)
|
|||
|
{
|
|||
|
case DataLevel.High:
|
|||
|
if (fail)
|
|||
|
_highPriorityFailQueue.Enqueue(data);
|
|||
|
else
|
|||
|
_highPriorityQueue.Enqueue(data);
|
|||
|
break;
|
|||
|
|
|||
|
case DataLevel.CurScene:
|
|||
|
if (fail)
|
|||
|
_curSceneFailQueue.Enqueue(data);
|
|||
|
else
|
|||
|
_curSceneQueue.Enqueue(data);
|
|||
|
break;
|
|||
|
|
|||
|
case DataLevel.NextScene:
|
|||
|
if (fail)
|
|||
|
_nextSceneFailQueue.Enqueue(data);
|
|||
|
else
|
|||
|
_nextSceneQueue.Enqueue(data);
|
|||
|
break;
|
|||
|
case DataLevel.Low:
|
|||
|
if (fail)
|
|||
|
_lowFailQueue.Enqueue(data);
|
|||
|
else
|
|||
|
_lowQueue.Enqueue(data);
|
|||
|
break;
|
|||
|
default:
|
|||
|
if (fail)
|
|||
|
_lowFailQueue.Enqueue(data);
|
|||
|
else
|
|||
|
_lowQueue.Enqueue(data);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
internal void AddFailData(T data)
|
|||
|
{
|
|||
|
_allFailQueue.Enqueue(data);
|
|||
|
}
|
|||
|
|
|||
|
public void Clear()
|
|||
|
{
|
|||
|
this._curSceneQueue.Clear();
|
|||
|
this._highPriorityQueue.Clear();
|
|||
|
this._nextSceneQueue.Clear();
|
|||
|
this._lowQueue.Clear();
|
|||
|
_curSceneFailQueue.Clear();
|
|||
|
_highPriorityFailQueue.Clear();
|
|||
|
_nextSceneFailQueue.Clear();
|
|||
|
_lowFailQueue.Clear();
|
|||
|
_allFailQueue.Clear();
|
|||
|
}
|
|||
|
|
|||
|
internal void ClearQueue(DataLevel level)
|
|||
|
{
|
|||
|
lock (this._lockObj)
|
|||
|
{
|
|||
|
switch (level)
|
|||
|
{
|
|||
|
case DataLevel.High:
|
|||
|
this._highPriorityQueue.Clear();
|
|||
|
_highPriorityFailQueue.Clear();
|
|||
|
break;
|
|||
|
|
|||
|
case DataLevel.CurScene:
|
|||
|
this._curSceneQueue.Clear();
|
|||
|
_curSceneFailQueue.Clear();
|
|||
|
break;
|
|||
|
|
|||
|
case DataLevel.NextScene:
|
|||
|
this._nextSceneQueue.Clear();
|
|||
|
_nextSceneFailQueue.Clear();
|
|||
|
break;
|
|||
|
case DataLevel.Low:
|
|||
|
this._lowQueue.Clear();
|
|||
|
_lowFailQueue.Clear();
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
internal int GetHighPriorityQueueCount()
|
|||
|
{
|
|||
|
lock (this._lockObj)
|
|||
|
{
|
|||
|
int count = GetDataCount(DataLevel.High);
|
|||
|
return count;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
internal int GetDataCount(DataLevel level)
|
|||
|
{
|
|||
|
lock (_lockObj)
|
|||
|
{
|
|||
|
int count = 0;
|
|||
|
switch (level)
|
|||
|
{
|
|||
|
case DataLevel.Low:
|
|||
|
count = _lowQueue.Count + _lowFailQueue.Count;
|
|||
|
break;
|
|||
|
case DataLevel.NextScene:
|
|||
|
count = _nextSceneQueue.Count + _nextSceneFailQueue.Count;
|
|||
|
break;
|
|||
|
case DataLevel.CurScene:
|
|||
|
count = _curSceneQueue.Count + _curSceneFailQueue.Count;
|
|||
|
break;
|
|||
|
case DataLevel.High:
|
|||
|
count = _highPriorityQueue.Count + _highPriorityFailQueue.Count;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return count;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
internal bool IsBaseResPaused()
|
|||
|
{
|
|||
|
return _pauseLowQueue;
|
|||
|
}
|
|||
|
|
|||
|
internal bool IsCurScenePaused()
|
|||
|
{
|
|||
|
return _pauseCurSceneQueue;
|
|||
|
}
|
|||
|
|
|||
|
internal void PauseLevel(DataLevel level)
|
|||
|
{
|
|||
|
SetLevelPause(level, true);
|
|||
|
}
|
|||
|
|
|||
|
internal void ResumeLevel(DataLevel level)
|
|||
|
{
|
|||
|
SetLevelPause(level, false);
|
|||
|
}
|
|||
|
|
|||
|
private void SetLevelPause(DataLevel level, bool pause)
|
|||
|
{
|
|||
|
switch (level)
|
|||
|
{
|
|||
|
case DataLevel.Low:
|
|||
|
_pauseLowQueue = pause;
|
|||
|
break;
|
|||
|
case DataLevel.NextScene:
|
|||
|
_pauseNextSceneQueue = pause;
|
|||
|
break;
|
|||
|
case DataLevel.CurScene:
|
|||
|
_pauseCurSceneQueue = pause;
|
|||
|
break;
|
|||
|
case DataLevel.High:
|
|||
|
_pauseHighPriorityQueue = pause;
|
|||
|
break;
|
|||
|
case DataLevel.All:
|
|||
|
_pauseHighPriorityQueue = pause;
|
|||
|
_pauseLowQueue = pause;
|
|||
|
_pauseNextSceneQueue = pause;
|
|||
|
_pauseCurSceneQueue = pause;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public T PopData()
|
|||
|
{
|
|||
|
lock (this._lockObj)
|
|||
|
{
|
|||
|
T data = default(T);
|
|||
|
if (GetHighPriorityData(out data))
|
|||
|
return data;
|
|||
|
if (GetCurSceneData(out data))
|
|||
|
return data;
|
|||
|
if (GetNextSceneData(out data))
|
|||
|
return data;
|
|||
|
if (GetLowPriorityData(out data))
|
|||
|
return data;
|
|||
|
|
|||
|
return data;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private bool GetHighPriorityData(out T data)
|
|||
|
{
|
|||
|
bool ret = false;
|
|||
|
data = default(T);
|
|||
|
|
|||
|
if (_pauseHighPriorityQueue)
|
|||
|
{
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
if (_highPriorityFailQueue.Count > 0)
|
|||
|
{
|
|||
|
data = _highPriorityFailQueue.Dequeue();
|
|||
|
ret = true;
|
|||
|
}
|
|||
|
else if (_highPriorityQueue.Count > 0)
|
|||
|
{
|
|||
|
data = _highPriorityQueue.Dequeue();
|
|||
|
ret = true;
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
private bool GetCurSceneData(out T data)
|
|||
|
{
|
|||
|
bool ret = false;
|
|||
|
data = default(T);
|
|||
|
|
|||
|
if (_pauseCurSceneQueue)
|
|||
|
{
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
if (_curSceneFailQueue.Count > 0)
|
|||
|
{
|
|||
|
data = _curSceneFailQueue.Dequeue();
|
|||
|
ret = true;
|
|||
|
}
|
|||
|
else if (_curSceneQueue.Count > 0)
|
|||
|
{
|
|||
|
data = _curSceneQueue.Dequeue();
|
|||
|
ret = true;
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
private bool GetNextSceneData(out T data)
|
|||
|
{
|
|||
|
bool ret = false;
|
|||
|
data = default(T);
|
|||
|
|
|||
|
if (_pauseNextSceneQueue)
|
|||
|
{
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
if (_nextSceneFailQueue.Count > 0)
|
|||
|
{
|
|||
|
data = _nextSceneFailQueue.Dequeue();
|
|||
|
ret = true;
|
|||
|
}
|
|||
|
else if (_nextSceneQueue.Count > 0)
|
|||
|
{
|
|||
|
data = _nextSceneQueue.Dequeue();
|
|||
|
ret = true;
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
private bool GetLowPriorityData(out T data)
|
|||
|
{
|
|||
|
bool ret = false;
|
|||
|
data = default(T);
|
|||
|
|
|||
|
if (_pauseLowQueue)
|
|||
|
{
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
if (_lowFailQueue.Count > 0)
|
|||
|
{
|
|||
|
data = _lowFailQueue.Dequeue();
|
|||
|
ret = true;
|
|||
|
}
|
|||
|
else if (_lowQueue.Count > 0)
|
|||
|
{
|
|||
|
data = _lowQueue.Dequeue();
|
|||
|
ret = true;
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|