void SuggestionsSidebarBlock::QueryProvider(SuggestionsBackend& backend, const CatalogItemPtr& item, uint64_t queryId) { m_pendingQueries++; // we need something to talk to GUI thread through that is guaranteed // to exist, and the app object is a good choice: auto backendPtr = &backend; std::weak_ptr<SuggestionsSidebarBlock> weakSelf = std::dynamic_pointer_cast<SuggestionsSidebarBlock>(shared_from_this()); m_provider->SuggestTranslation ( backend, m_parent->GetCurrentSourceLanguage(), m_parent->GetCurrentLanguage(), item->GetString().ToStdWstring(), // when receiving data [=](const SuggestionsList& hits){ call_on_main_thread([weakSelf,queryId,hits]{ auto self = weakSelf.lock(); // maybe this call is already out of date: if (!self || self->m_latestQueryId != queryId) return; self->UpdateSuggestions(hits); if (--self->m_pendingQueries == 0) self->OnQueriesFinished(); }); }, // on error: [=](std::exception_ptr e){ call_on_main_thread([weakSelf,queryId,backendPtr,e]{ auto self = weakSelf.lock(); // maybe this call is already out of date: if (!self || self->m_latestQueryId != queryId) return; self->ReportError(backendPtr, e); if (--self->m_pendingQueries == 0) self->OnQueriesFinished(); }); } ); }
bool DownloadQueue::enqueueDownload(const HTTPRequest & request, const std::string & saveToPath, const DownloadTask::completion_handle_t & completion, const DownloadTask::progress_handle_t & progress){ if (isDownloading(request)){ call_on_main_thread([=]{ if (completion) completion(NetworkTask::StatusUndef, {request});//response code and succeed? should we care? }); return false; } pDownloadTask task(DownloadTask::create(request, saveToPath, [=](NetworkTask::Status status, const HTTPResponse & response){ if (completion) completion(status, response); //remove from queue circulate(); }, progress)); _queue.emplace_back(task); circulate(); return true; }
void UnzipTask::start(){ _status=StatusUnzipping; FutureHolder * f(new FutureHolder); setProgress(0.f); f->future=std::async(std::launch::async, [=](){ auto callbackL([=](Status status){ call_on_main_thread([=]{ _status=status; releaseSelf(); if (_completionHandle) _completionHandle(_status); delete f; }); }); auto eachCallbackL([=](const std::string & path, bool success){ if (_completedEachHandle) call_on_main_thread([=]{ _completedEachHandle(path, success); }); }); unsigned long ulSize; unsigned char *pBuffer(nullptr); //background work unzFile pFile(unzOpen(_archivedFile.c_str())); if (pFile){ int iStatus(unzGoToFirstFile(pFile)); while (iStatus == UNZ_OK){ char szFilePath[260]; unz_file_info fileInfo; iStatus = unzGetCurrentFileInfo(pFile, &fileInfo, szFilePath, sizeof(szFilePath), NULL, 0, NULL, 0); if (iStatus != UNZ_OK){ break; } iStatus = unzOpenCurrentFile(pFile); if (iStatus != UNZ_OK){ break; } pBuffer=new unsigned char[fileInfo.uncompressed_size]; ulSize=unzReadCurrentFile(pFile, pBuffer, fileInfo.uncompressed_size); unzCloseCurrentFile(pFile); std::string filePath(szFilePath); bool isDirectory(false); if (!filePath.empty()) isDirectory=filePath.back()=='/'; std::string path(Functions::stringByAppendingPathComponent(_destinationPath, filePath)); if (isDirectory) { int result(mkdir(path.c_str(),0777)); eachCallbackL(path+"/", result==0); }else{ FILE *pFHandle(fopen(path.c_str(), "wb")); if (pFHandle){ fwrite(pBuffer, fileInfo.uncompressed_size, 1, pFHandle); fclose(pFHandle); eachCallbackL(path, true); }else eachCallbackL(path, false); } delete [] pBuffer; iStatus = unzGoToNextFile(pFile); } unzClose(pFile); callbackL(StatusCompleted); setProgress(1.f); }else callbackL(StatusFailed); }); }