Hi, guys…
i modify code void AssetsManagerEx::startUpdate()
using std::thread with lambda,
and std::mutex, std::condition_variable, std::unique_lock<std::mutex> to control…
but UI freeze problem still not resolve…
any one can help?
FullCode:
void AssetsManagerEx::startUpdate()
{
CCLOG( "[Raz][AMEx] Into startUpdate()..." );
if (_updateState != State::NEED_UPDATE) { CCLOG( "[Raz][AMEx] update status don't need Update, return." ); return; }
_updateState = State::UPDATING;
// Clean up before update
_failedUnits.clear();
_downloadUnits.clear();
_compressedFiles.clear();
_totalWaitToDownload = _totalToDownload = 0;
_percent = _percentByFile = _sizeCollected = _totalSize = 0;
_downloadedSize.clear();
_totalEnabled = false;
// Temporary manifest exists, resuming previous download
if (_tempManifest->isLoaded() && _tempManifest->versionEquals(_remoteManifest))
{
CCLOG("[Raz][AMEx] Manifest Version Equal.");
_tempManifest->genResumeAssetsList(&_downloadUnits);
_totalWaitToDownload = _totalToDownload = (int)_downloadUnits.size();
this->batchDownload();
std::string msg = StringUtils::format("Resuming from previous unfinished update, %d files remains to be finished.", _totalToDownload);
dispatchUpdateEvent(EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "", msg);
}
// Check difference
else
{
// Temporary manifest not exists or out of date,
// it will be used to register the download states of each asset,
// in this case, it equals remote manifest.
_tempManifest->release();
_tempManifest = _remoteManifest;
CCLOG("[Raz][AMEx] Manifest Version Not Equal, GenDiff...");
dispatchUpdateEvent(EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "", "GenerateDiff.Start" );
CCLOG("[Raz][AMEx] Start Generate Diff files.");
std::mutex mutex;
std::condition_variable watcher;
std::unique_lock<std::mutex> uniqueLock( mutex );
std::unordered_map<std::string, Manifest::AssetDiff> diff_map;
//========================================================================================================================
std::thread _t_genDiff( [&]( std::unordered_map<std::string, Manifest::AssetDiff>& _map )
{
CCLOG( "[Raz][AMEx][Thread] genDiff Start..." );
//--------------------------------------------------------------------------------------------------------------------
_map = _localManifest->genDiff( _remoteManifest );
//--------------------------------------------------------------------------------------------------------------------
CCLOG( "[Raz][AMEx][Thread] genDiff Done." );
watcher.notify_one();
}, std::ref( diff_map ) );
//========================================================================================================================
watcher.wait( uniqueLock );
CCLOG("[Raz][AMEx] Done Generate Diff files, size[%d]", diff_map.size() );
dispatchUpdateEvent( EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "", "GenerateDiff.Done" );
_t_genDiff.detach();
if (diff_map.size() == 0)
{
updateSucceed();
}
else
{
// Generate download units for all assets that need to be updated or added
std::string packageUrl = _remoteManifest->getPackageUrl();
CCLOG("[Raz][AMEx] Start compare version between local and remote..");
dispatchUpdateEvent( EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "", "CompareDiff.Start" );
//========================================================================================================================
std::thread _t_compare( [&]()
{
CCLOG( "[Raz][AMEx][Thread] genDiff Start..." );
//--------------------------------------------------------------------------------------------------------------------
for (auto it = diff_map.begin(); it != diff_map.end(); ++it)
{
Manifest::AssetDiff diff = it->second;
if ( diff.type == Manifest::DiffType::DELETED )
{
_fileUtils->removeFile(_storagePath + diff.asset.path);
}
else
{
std::string path = diff.asset.path;
_fileUtils->createDirectory( basename(_storagePath + path) ); // Create path
DownloadUnit unit;
unit.customId = it->first;
unit.srcUrl = packageUrl + path;
unit.storagePath = _storagePath + path;
_downloadUnits.emplace( unit.customId, unit );
}
}
//--------------------------------------------------------------------------------------------------------------------
CCLOG( "[Raz][AMEx][Thread] genDiff Done." );
watcher.notify_one();
} );
//========================================================================================================================
watcher.wait( uniqueLock );
dispatchUpdateEvent( EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "", "CompareDiff.Done" );
_t_compare.detach();
CCLOG("[Raz][AMEx] Done of compare version between local and remote");
dispatchUpdateEvent( EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "", "CreateDownload.Start" );
//========================================================================================================================
std::thread _t_createDownload( [&,this]( std::condition_variable& watcher )
{
CCLOG( "[Raz][AMEx][Thread] Create Catch Download Start..." );
//--------------------------------------------------------------------------------------------------------------------
//CCLOG("[Raz][AMEx] Set Remote Manifest Assets download success.");
// Set other assets' downloadState to SUCCESSED
auto &assets = _remoteManifest->getAssets();
for (auto it = assets.cbegin(); it != assets.cend(); ++it)
{
const std::string &key = it->first;
auto diffIt = diff_map.find(key);
if (diffIt == diff_map.end())
{
_tempManifest->setAssetDownloadState( key, Manifest::DownloadState::SUCCESSED );
}
}
_totalWaitToDownload = _totalToDownload = (int)_downloadUnits.size();
this->batchDownload();
//--------------------------------------------------------------------------------------------------------------------
CCLOG( "[Raz][AMEx][Thread] Create Catch Download Done." );
watcher.notify_one();
}, std::ref( watcher ) );
//========================================================================================================================
watcher.wait( uniqueLock );
dispatchUpdateEvent( EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "", "CreateDownload.Done" );
_t_createDownload.detach();
std::string msg = StringUtils::format("Start to update %d files from remote package.", _totalToDownload);
CCLOG("[Raz][AMEx] Dispatch Update Progression FileCount[%d] Message[%s]", _totalToDownload, msg.c_str() );
dispatchUpdateEvent(EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "", msg);
}
}
_waitToUpdate = false;
}