【Unity3d】【項目學習心得】從資源服務器下載資源(二)

繼上篇的基礎準備 從資源服務器下載資源(一) 

我們現在繼續進一步完成 LoadManager 管理類。

管理類因爲在全局中都是存在的,所以應該作爲單例存在。

因爲LoadManager 類是管理多個 LoadRequest的,所以我們需要存儲當前正在下載的LoadRequest,以及下載完成的 LoadRequest。

另外,我們爲了防止太多下載線程佔用過多資源,我們對於下載的線程個數做一定的限制,如項目裏面的最大線程數爲2,所以我們需要一個存儲LoadRequest的等待隊列。

根據以上分析,分別如下:


[csharp] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. public static LoadManager instance;  

  2.    public int MAX_LOAD_REQUEST = 2;  

  3.   

  4.    private Dictionary<string, LoadRequest> loadDict = new Dictionary<string, LoadRequest>();  

  5.    private Dictionary<string, LoadRequest> waitDict = new Dictionary<string, LoadRequest>();  

  6.    private Dictionary<string, LoadParam> completeDict = new Dictionary<string, LoadParam>();  


另外,既然有下載隊列的存在,就有下載優先級,我們可以多一個存儲下載任務的優先級,然後根據優先級進行下載。


當然,項目裏面雖然有了下載優先級的存儲,但是並沒有進行排序,在進行下載任務創建的時候,也都統一使用了Normal優先級。

所以在此我們先跟着創建,等到以後需要使用優先級的時候再進行排序。


[csharp] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. private List<string> priorityList = new List<string>();  


接下來我們開始實現代碼:


1. 首先實現單例:


[csharp] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. /// <summary>  

  2. ///  返回實例  

  3. /// </summary>  

  4. /// <returns></returns>  

  5. public static LoadManager getInstance() {  

  6.     if (instance == null) {  

  7.         instance = new LoadManager();  

  8.     }  

  9.     return instance;  

  10. }  


2. 我們實現一個函數,功能是根據優先級,從等待隊列裏面移除一個任務到下載隊列裏。



[csharp] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. /// <summary>  

  2. /// 根據優先級,從等待隊列裏面移除一個任務到下載隊列裏  

  3. /// </summary>  

  4. public void MoveRequestFromWaitDictToLoadDict() {  

  5.     isLoading = loadDict.Count > 0;  

  6.     if (priorityList.Count > 0) {  

  7.         if (waitDict.ContainsKey(priorityList[0])) {  

  8.             LoadRequest request = waitDict[priorityList[0]];  

  9.             waitDict.Remove(priorityList[0]);  

  10.             priorityList.RemoveAt(0);  

  11.             Load(request.requestURL, request.completeFunction, request.customParams, request.fileType, request.priotiry, request.errorFunction, request.processFunction);  

  12.         }  

  13.     }  

  14. }  



3.上面的Load()函數是加載新的LoadRequest。

在加載新的LoadRequest時,我們要進行判斷,例如同個下載任務可能是由不同的組件請求發起的;

① 這個時候我們當然不能再去下載一次,所以只需判斷completeDict裏面是否已經下載過了,如果是,就直接使用即可。

② 另外,當有相同的請求時,不過此時下載還沒完成(正在下載中),此時我們只需把回調函數加進回調隊列即可。

③ 相同的,如果相同的請求在等待隊列,也跟②一樣處理。

④ 最後就剩下是,從沒下載過的情況,此時我們要看當前下載的線程是否超過最大限制,如果是,則把任務加到等待隊列,如果不是,則可馬上下載

具體實現爲下:


[csharp] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. /// <summary>  

  2.     /// 讀取資源  

  3.     /// </summary>  

  4.     public void Load(string url, LoadRequest.DownCompleteDelegate completeFunc, object customParam = nullstring fileType = ""int  priority = 2, LoadRequest.ErrorDelegate errorFunc = null, LoadRequest.ProcessDelegate processFunc = null) {  

  5.         url = url.Trim();  

  6.         if (string.IsNullOrEmpty(url)) return;  

  7.          

  8.         if (completeDict.ContainsKey(url)) {  

  9.             // 已下載資源,直接調用回調函數  

  10.             if (customParam != null) {  

  11.                 completeDict[url].param = customParam;  

  12.             }  

  13.             try {  

  14.                 completeFunc.Invoke(completeDict[url]);  

  15.             } catch (Exception exception) {  

  16.                 Debug.LogWarning("exception:" + exception.Message);  

  17.             }  

  18.         } else if (loadDict.ContainsKey(url)) {  

  19.             // 已經提交相同請求,但是沒有下載完成  

  20.             loadDict[url].completeFunction += completeFunc;  

  21.             loadDict[url].processFunction += processFunc;  

  22.             loadDict[url].errorFunction += errorFunc;  

  23.             loadDict[url].customParams.Add(customParam);  

  24.         } else if (waitDict.ContainsKey(url)) {  

  25.             // 已經提交相同請求,但是還沒輪到加載  

  26.             loadDict[url].completeFunction += completeFunc;  

  27.             loadDict[url].processFunction += processFunc;  

  28.             loadDict[url].errorFunction += errorFunc;  

  29.             loadDict[url].customParams.Add(customParam);  

  30.         } else {  

  31.             // 未加載過的  

  32.             if (loadDict.Count < MAX_LOAD_REQUEST) {  

  33.                 isLoading = true;  

  34.                 LoadRequest loadRequest = new LoadRequest(url, customParam, fileType, completeFunc, errorFunc, processFunc);  

  35.                 if (customParam != null && customParam.GetType().ToString() == "System.Collections.Generic.List`1[System.Object]") {  

  36.                     loadRequest.customParams = (List<object>)customParam;  

  37.                 }  

  38.                 loadDict.Add(url, loadRequest);  

  39.             } else {  

  40.                 // 已達到最大加載數目,加入等待隊列  

  41.                 LoadRequest loadRequest = new LoadRequest();  

  42.                 loadRequest.requestURL = url;  

  43.                 loadRequest.completeFunction = completeFunc;  

  44.                 loadRequest.errorFunction = errorFunc;  

  45.                 loadRequest.processFunction = processFunc;  

  46.                 loadRequest.customParams.Add(customParam);  

  47.                 loadRequest.fileType = fileType;  

  48.                 loadRequest.priotiry = priority;  

  49.                 waitDict.Add(url, loadRequest);  

  50.                 priorityList.Add(url);  

  51.                 priorityList = priorityList.OrderBy(s => waitDict[s].priotiry).ToList();  

  52.             }  

  53.         }  

  54.     }  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章