繼上篇的基礎準備 從資源服務器下載資源(一)
我們現在繼續進一步完成 LoadManager 管理類。
管理類因爲在全局中都是存在的,所以應該作爲單例存在。
因爲LoadManager 類是管理多個 LoadRequest的,所以我們需要存儲當前正在下載的LoadRequest,以及下載完成的 LoadRequest。
另外,我們爲了防止太多下載線程佔用過多資源,我們對於下載的線程個數做一定的限制,如項目裏面的最大線程數爲2,所以我們需要一個存儲LoadRequest的等待隊列。
根據以上分析,分別如下:
[csharp] view plaincopy
public static LoadManager instance;
public int MAX_LOAD_REQUEST = 2;
private Dictionary<string, LoadRequest> loadDict = new Dictionary<string, LoadRequest>();
private Dictionary<string, LoadRequest> waitDict = new Dictionary<string, LoadRequest>();
private Dictionary<string, LoadParam> completeDict = new Dictionary<string, LoadParam>();
另外,既然有下載隊列的存在,就有下載優先級,我們可以多一個存儲下載任務的優先級,然後根據優先級進行下載。
當然,項目裏面雖然有了下載優先級的存儲,但是並沒有進行排序,在進行下載任務創建的時候,也都統一使用了Normal優先級。
所以在此我們先跟着創建,等到以後需要使用優先級的時候再進行排序。
[csharp] view plaincopy
private List<string> priorityList = new List<string>();
接下來我們開始實現代碼:
1. 首先實現單例:
[csharp] view plaincopy
/// <summary>
/// 返回實例
/// </summary>
/// <returns></returns>
public static LoadManager getInstance() {
if (instance == null) {
instance = new LoadManager();
}
return instance;
}
2. 我們實現一個函數,功能是根據優先級,從等待隊列裏面移除一個任務到下載隊列裏。
[csharp] view plaincopy
/// <summary>
/// 根據優先級,從等待隊列裏面移除一個任務到下載隊列裏
/// </summary>
public void MoveRequestFromWaitDictToLoadDict() {
isLoading = loadDict.Count > 0;
if (priorityList.Count > 0) {
if (waitDict.ContainsKey(priorityList[0])) {
LoadRequest request = waitDict[priorityList[0]];
waitDict.Remove(priorityList[0]);
priorityList.RemoveAt(0);
Load(request.requestURL, request.completeFunction, request.customParams, request.fileType, request.priotiry, request.errorFunction, request.processFunction);
}
}
}
3.上面的Load()函數是加載新的LoadRequest。
在加載新的LoadRequest時,我們要進行判斷,例如同個下載任務可能是由不同的組件請求發起的;
① 這個時候我們當然不能再去下載一次,所以只需判斷completeDict裏面是否已經下載過了,如果是,就直接使用即可。
② 另外,當有相同的請求時,不過此時下載還沒完成(正在下載中),此時我們只需把回調函數加進回調隊列即可。
③ 相同的,如果相同的請求在等待隊列,也跟②一樣處理。
④ 最後就剩下是,從沒下載過的情況,此時我們要看當前下載的線程是否超過最大限制,如果是,則把任務加到等待隊列,如果不是,則可馬上下載
具體實現爲下:
[csharp] view plaincopy
/// <summary>
/// 讀取資源
/// </summary>
public void Load(string url, LoadRequest.DownCompleteDelegate completeFunc, object customParam = null, string fileType = "", int priority = 2, LoadRequest.ErrorDelegate errorFunc = null, LoadRequest.ProcessDelegate processFunc = null) {
url = url.Trim();
if (string.IsNullOrEmpty(url)) return;
if (completeDict.ContainsKey(url)) {
// 已下載資源,直接調用回調函數
if (customParam != null) {
completeDict[url].param = customParam;
}
try {
completeFunc.Invoke(completeDict[url]);
} catch (Exception exception) {
Debug.LogWarning("exception:" + exception.Message);
}
} else if (loadDict.ContainsKey(url)) {
// 已經提交相同請求,但是沒有下載完成
loadDict[url].completeFunction += completeFunc;
loadDict[url].processFunction += processFunc;
loadDict[url].errorFunction += errorFunc;
loadDict[url].customParams.Add(customParam);
} else if (waitDict.ContainsKey(url)) {
// 已經提交相同請求,但是還沒輪到加載
loadDict[url].completeFunction += completeFunc;
loadDict[url].processFunction += processFunc;
loadDict[url].errorFunction += errorFunc;
loadDict[url].customParams.Add(customParam);
} else {
// 未加載過的
if (loadDict.Count < MAX_LOAD_REQUEST) {
isLoading = true;
LoadRequest loadRequest = new LoadRequest(url, customParam, fileType, completeFunc, errorFunc, processFunc);
if (customParam != null && customParam.GetType().ToString() == "System.Collections.Generic.List`1[System.Object]") {
loadRequest.customParams = (List<object>)customParam;
}
loadDict.Add(url, loadRequest);
} else {
// 已達到最大加載數目,加入等待隊列
LoadRequest loadRequest = new LoadRequest();
loadRequest.requestURL = url;
loadRequest.completeFunction = completeFunc;
loadRequest.errorFunction = errorFunc;
loadRequest.processFunction = processFunc;
loadRequest.customParams.Add(customParam);
loadRequest.fileType = fileType;
loadRequest.priotiry = priority;
waitDict.Add(url, loadRequest);
priorityList.Add(url);
priorityList = priorityList.OrderBy(s => waitDict[s].priotiry).ToList();
}
}
}