因為公司業(yè)務(wù)需求需要做邊下邊玩的小包下載,在這里記錄一下思路
下載庫我使用的是cocos2dx 4.x的CCDownloader來下載文件
大體思路就是hook住fileutils中的getFileData函數(shù)和isFileExist函數(shù)。
isFileExist:無論初始包里文件是否存在,只要文件是游戲的資源文件這里都要返回“文件存在”
getFileData:這里判斷當(dāng)文件在文件列表中但是游戲包體里不存在該文件時,需要暫停主線程并且去下載文件,文件下載完成時恢復(fù)主線程
當(dāng)暫停主線程時,下載文件的回調(diào)需要在子線程中回調(diào)否則無法回調(diào)成功
除上面的下載文件以外,主線程中根據(jù)缺少的文件列表按照一定策略持續(xù)下載缺少的文件(優(yōu)先下載列表等)。
下面是一些主要的代碼:
1 //使用條件變量暫停主線程 2 //繼承了CCFileUtils文件 3 unsigned char* QFileUtils::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize) 4 { 5 auto download = QDownloadSmallPack::getInstance(); 6 auto index = QIndex::getInstance(); 7 if (download->isStartCheckRes()) 8 { 9 bool hasFile = download->checkFile(pszFileName); 10 if (!hasFile) 11 { 12 QIndex::IndexEntry* filePathInIndex = index->getFilePathByIndex(pszFileName); 13 if (filePathInIndex && !filePathInIndex->name.empty()) 14 { 15 std::unique_lock<std::mutex> lock{_m}; 16 download->downloadFile(filePathInIndex, _cond_var); 17 18 if (!download->isDownloadOK) 19 { 20 _cond_var.wait(lock, [download](){ return download->isDownloadOK; }); 21 } 22 23 } 24 } 25 } 26 27 return CCFileUtils::getFileData(pszFileName, pszMode, pSize); 28 }
- (id)init: (const cocos2d::network::DownloaderApple*)o hints:(const cocos2d::network::DownloaderHints&) hints { DLLOG("Construct DownloaderAppleImpl %p", self); // save outer task ref _outer = o; _hints = hints; // create task dictionary self.taskDict = [NSMutableDictionary dictionary]; // create download session NSURLSessionConfiguration *defaultConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; if (hints.callBackInMainThread) { //在主線程中回調(diào) self.downloadSession = [NSURLSession sessionWithConfiguration:defaultConfig delegate:self delegateQueue:[NSOperationQueue mainQueue]]; } else { //在子線程中回調(diào) self.downloadSession = [NSURLSession sessionWithConfiguration:defaultConfig delegate:self delegateQueue:nil]; } // self.downloadSession.sessionDescription = kCurrentSession; return self; }
//其他兩個回調(diào)做同樣的修改就好 void onProgress(final int id, final long downloadBytes, final long downloadNow, final long downloadTotal) { DownloadTask task = (DownloadTask)_taskMap.get(id); if (null != task) { task.bytesReceived = downloadBytes; task.totalBytesReceived = downloadNow; task.totalBytesExpected = downloadTotal; } if (_callBackInMainThread){ Cocos2dxHelper.getActivity().runOnGLThread(new Runnable() { @Override public void run() { nativeOnProgress(_id, id, downloadBytes, downloadNow, downloadTotal); } }); }else { //在子線程中回調(diào) new Runnable() { @Override public void run() { nativeOnProgress(_id, id, downloadBytes, downloadNow, downloadTotal); } }.run(); } }
//cv是getfiledata中使用的條件變量 _downloader->onFileTaskSuccess = [this, &cv](const cocos2d::network::DownloadTask& task) { //做一些游戲自己的檢測邏輯,確認(rèn)文件下載完成之后這里設(shè)置條件變量并且通知主線程恢復(fù) isDownloadOK = true; cv.notify_all(); };
?文章來源地址http://www.zghlxwxcb.cn/news/detail-774757.html文章來源:http://www.zghlxwxcb.cn/news/detail-774757.html
?
到了這里,關(guān)于cocos2dx上做邊下邊玩小包熱更的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!