@@ -94,10 +94,8 @@ bool ProjectDownloader::downloadAssets(const std::vector<std::string> &assetIds)
9494 m_cancelMutex.unlock ();
9595
9696 auto count = assetIds.size ();
97- unsigned int threadCount = std::thread::hardware_concurrency ();
98-
99- // Thread count: number of assets / 5, limited to maximum number of threads
100- threadCount = std::max (1u , std::min (threadCount, static_cast <unsigned int >(std::ceil (count / 5.0 ))));
97+ // unsigned int threadCount = std::thread::hardware_concurrency();
98+ unsigned int threadCount = 20 ;
10199
102100 m_assets.clear ();
103101 m_assets.reserve (count);
@@ -120,48 +118,92 @@ bool ProjectDownloader::downloadAssets(const std::vector<std::string> &assetIds)
120118 downloaders.push_back (m_downloaderFactory->create ());
121119
122120 // Download assets
123- auto f = [this , &downloaders, &assetIds, count, threadCount](unsigned int thread) {
124- auto downloader = downloaders[thread];
125- unsigned int n = std::ceil (count / static_cast <double >(threadCount));
121+ auto f = [this , count](std::shared_ptr<IDownloader> downloader, int index, const std::string &id) {
122+ m_cancelMutex.lock ();
126123
127- for ( unsigned int i = 0 ; i < n; i++) {
128- unsigned int index = thread * n + i ;
124+ if (m_cancel)
125+ return ;
129126
130- if (index < count) {
131- m_cancelMutex.lock ();
127+ m_cancelMutex.unlock ();
132128
133- if (m_cancel)
134- return ;
129+ bool ret = downloader->download (ASSET_PREFIX + id + ASSET_SUFFIX);
135130
136- m_cancelMutex.unlock ();
131+ if (!ret) {
132+ std::cerr << " Failed to download asset: " << id << std::endl;
133+ m_cancelMutex.lock ();
134+ m_cancel = true ;
135+ m_cancelMutex.unlock ();
136+ return ;
137+ }
137138
138- bool ret = downloader->download (ASSET_PREFIX + assetIds[index] + ASSET_SUFFIX);
139+ m_assetsMutex.lock ();
140+ m_assets[index] = downloader->text ();
141+ m_downloadedAssetCount++;
142+ m_downloadProgressChanged (m_downloadedAssetCount, count);
143+ m_assetsMutex.unlock ();
144+ };
139145
140- if (!ret) {
141- std::cerr << " Failed to download asset: " << assetIds[index] << std::endl;
142- m_cancelMutex.lock ();
143- m_cancel = true ;
144- m_cancelMutex.unlock ();
145- return ;
146- }
146+ std::unordered_map<int , std::pair<std::thread, std::shared_ptr<IDownloader>>> threads;
147+ bool done = false ;
148+ unsigned int lastCount = 0 , i = 0 ;
147149
148- m_assetsMutex.lock ();
149- m_assets[index] = downloader->text ();
150- m_downloadedAssetCount++;
151- std::cout << " Downloaded assets: " << m_downloadedAssetCount << " of " << count << std::endl;
152- m_downloadProgressChanged (m_downloadedAssetCount, count);
153- m_assetsMutex.unlock ();
150+ while (true ) {
151+ int addCount = threadCount - threads.size ();
152+
153+ for (int j = 0 ; j < addCount; j++) {
154+ if (i >= count) {
155+ done = true ;
156+ break ;
154157 }
158+
159+ std::shared_ptr<IDownloader> freeDownloader = nullptr ;
160+
161+ for (auto downloader : downloaders) {
162+ auto it = std::find_if (threads.begin (), threads.end (), [&downloader](std::pair<const int , std::pair<std::thread, std::shared_ptr<IDownloader>>> &pair) {
163+ return pair.second .second == downloader;
164+ });
165+
166+ if (it == threads.cend ()) {
167+ freeDownloader = downloader;
168+ break ;
169+ }
170+ }
171+
172+ assert (freeDownloader);
173+ threads[i] = { std::thread (f, freeDownloader, i, assetIds[i]), freeDownloader };
174+ i++;
155175 }
156- };
157176
158- std::vector< std::thread> threads ;
177+ std::this_thread::sleep_for ( std::chrono::milliseconds ( 25 )) ;
159178
160- for (unsigned int i = 0 ; i < threadCount; i++)
161- threads.emplace_back (std::thread (f, i));
179+ m_assetsMutex.lock ();
162180
163- for (unsigned int i = 0 ; i < threadCount; i++)
164- threads[i].join ();
181+ if (m_downloadedAssetCount != lastCount) {
182+ std::cout << " Downloaded assets: " << m_downloadedAssetCount << " of " << count << std::endl;
183+ lastCount = m_downloadedAssetCount;
184+ }
185+
186+ std::vector<int > toRemove;
187+
188+ for (auto &[index, info] : threads) {
189+ if (!m_assets[index].empty ())
190+ toRemove.push_back (index);
191+ }
192+
193+ m_assetsMutex.unlock ();
194+
195+ for (int index : toRemove) {
196+ threads[index].first .join ();
197+ threads.erase (index);
198+ }
199+
200+ if (done) {
201+ for (auto &[index, info] : threads)
202+ info.first .join ();
203+
204+ break ;
205+ }
206+ }
165207
166208 CHECK_CANCEL ();
167209
0 commit comments