mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 13:10:04 +00:00 
			
		
		
		
	Catch exceptions in background threads
This commit is contained in:
		
							parent
							
								
									863cdd0384
								
							
						
					
					
						commit
						e1d61fccfa
					
				
					 13 changed files with 866 additions and 665 deletions
				
			
		|  | @ -611,6 +611,8 @@ void MainWindow::on_actionCheckForUpdates_triggered() | ||||||
|    boost::asio::post( |    boost::asio::post( | ||||||
|       p->threadPool_, |       p->threadPool_, | ||||||
|       [this]() |       [this]() | ||||||
|  |       { | ||||||
|  |          try | ||||||
|          { |          { | ||||||
|             if (!p->updateManager_->CheckForUpdates(main::kVersionString_)) |             if (!p->updateManager_->CheckForUpdates(main::kVersionString_)) | ||||||
|             { |             { | ||||||
|  | @ -627,6 +629,11 @@ void MainWindow::on_actionCheckForUpdates_triggered() | ||||||
|                      messageBox->show(); |                      messageBox->show(); | ||||||
|                   }); |                   }); | ||||||
|             } |             } | ||||||
|  |          } | ||||||
|  |          catch (const std::exception& ex) | ||||||
|  |          { | ||||||
|  |             logger_->error(ex.what()); | ||||||
|  |          } | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -662,10 +669,17 @@ void MainWindowImpl::AsyncSetup() | ||||||
|    { |    { | ||||||
|       boost::asio::post(threadPool_, |       boost::asio::post(threadPool_, | ||||||
|                         [this]() |                         [this]() | ||||||
|  |                         { | ||||||
|  |                            try | ||||||
|                            { |                            { | ||||||
|                               manager::UpdateManager::RemoveTemporaryReleases(); |                               manager::UpdateManager::RemoveTemporaryReleases(); | ||||||
|                               updateManager_->CheckForUpdates( |                               updateManager_->CheckForUpdates( | ||||||
|                                  main::kVersionString_); |                                  main::kVersionString_); | ||||||
|  |                            } | ||||||
|  |                            catch (const std::exception& ex) | ||||||
|  |                            { | ||||||
|  |                               logger_->error(ex.what()); | ||||||
|  |                            } | ||||||
|                         }); |                         }); | ||||||
|    } |    } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -42,7 +42,17 @@ public: | ||||||
|          [this](const types::TextEventKey& key, size_t messageIndex) |          [this](const types::TextEventKey& key, size_t messageIndex) | ||||||
|          { |          { | ||||||
|             boost::asio::post(threadPool_, |             boost::asio::post(threadPool_, | ||||||
|                               [=, this]() { HandleAlert(key, messageIndex); }); |                               [=, this]() | ||||||
|  |                               { | ||||||
|  |                                  try | ||||||
|  |                                  { | ||||||
|  |                                     HandleAlert(key, messageIndex); | ||||||
|  |                                  } | ||||||
|  |                                  catch (const std::exception& ex) | ||||||
|  |                                  { | ||||||
|  |                                     logger_->error(ex.what()); | ||||||
|  |                                  } | ||||||
|  |                               }); | ||||||
|          }); |          }); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -25,6 +25,8 @@ public: | ||||||
| 
 | 
 | ||||||
|    ~Impl() { threadPool_.join(); } |    ~Impl() { threadPool_.join(); } | ||||||
| 
 | 
 | ||||||
|  |    void DownloadSync(const std::shared_ptr<request::DownloadRequest>& request); | ||||||
|  | 
 | ||||||
|    boost::asio::thread_pool threadPool_ {1u}; |    boost::asio::thread_pool threadPool_ {1u}; | ||||||
| 
 | 
 | ||||||
|    DownloadManager* self_; |    DownloadManager* self_; | ||||||
|  | @ -36,13 +38,25 @@ DownloadManager::~DownloadManager() = default; | ||||||
| void DownloadManager::Download( | void DownloadManager::Download( | ||||||
|    const std::shared_ptr<request::DownloadRequest>& request) |    const std::shared_ptr<request::DownloadRequest>& request) | ||||||
| { | { | ||||||
|    boost::asio::post( |    boost::asio::post(p->threadPool_, | ||||||
|       p->threadPool_, |  | ||||||
|                      [=]() |                      [=]() | ||||||
|  |                      { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                            p->DownloadSync(request); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DownloadManager::Impl::DownloadSync( | ||||||
|  |    const std::shared_ptr<request::DownloadRequest>& request) | ||||||
| { | { | ||||||
|    // Prepare destination file
 |    // Prepare destination file
 | ||||||
|          const std::filesystem::path& destinationPath = |    const std::filesystem::path& destinationPath = request->destination_path(); | ||||||
|             request->destination_path(); |  | ||||||
| 
 | 
 | ||||||
|    if (!destinationPath.has_parent_path()) |    if (!destinationPath.has_parent_path()) | ||||||
|    { |    { | ||||||
|  | @ -95,8 +109,7 @@ void DownloadManager::Download( | ||||||
|                          std::ios_base::trunc}; |                          std::ios_base::trunc}; | ||||||
|    if (!ofs.is_open() || !ofs.good()) |    if (!ofs.is_open() || !ofs.good()) | ||||||
|    { |    { | ||||||
|             logger_->error( |       logger_->error("Unable to open destination file for writing: \"{}\"", | ||||||
|                "Unable to open destination file for writing: \"{}\"", |  | ||||||
|                      destinationPath.string()); |                      destinationPath.string()); | ||||||
| 
 | 
 | ||||||
|       Q_EMIT request->RequestComplete( |       Q_EMIT request->RequestComplete( | ||||||
|  | @ -110,8 +123,8 @@ void DownloadManager::Download( | ||||||
|    cpr::cpr_off_t                        lastDownloadTotal {}; |    cpr::cpr_off_t                        lastDownloadTotal {}; | ||||||
| 
 | 
 | ||||||
|    // Download file
 |    // Download file
 | ||||||
|          cpr::Response response = |    cpr::Response response = cpr::Get( | ||||||
|             cpr::Get(cpr::Url {request->url()}, |       cpr::Url {request->url()}, | ||||||
|       cpr::ProgressCallback( |       cpr::ProgressCallback( | ||||||
|          [&](cpr::cpr_off_t downloadTotal, |          [&](cpr::cpr_off_t downloadTotal, | ||||||
|              cpr::cpr_off_t downloadNow, |              cpr::cpr_off_t downloadNow, | ||||||
|  | @ -125,17 +138,14 @@ void DownloadManager::Download( | ||||||
|                std::chrono::system_clock::now(); |                std::chrono::system_clock::now(); | ||||||
| 
 | 
 | ||||||
|             // Only emit an update every 100ms
 |             // Only emit an update every 100ms
 | ||||||
|                            if ((now > lastUpdated + 100ms || |             if ((now > lastUpdated + 100ms || downloadNow == downloadTotal) && | ||||||
|                                 downloadNow == downloadTotal) && |  | ||||||
|                 (downloadNow != lastDownloadNow || |                 (downloadNow != lastDownloadNow || | ||||||
|                  downloadTotal != lastDownloadTotal)) |                  downloadTotal != lastDownloadTotal)) | ||||||
|             { |             { | ||||||
|                               logger_->trace("Downloaded: {} / {}", |                logger_->trace( | ||||||
|                                              downloadNow, |                   "Downloaded: {} / {}", downloadNow, downloadTotal); | ||||||
|                                              downloadTotal); |  | ||||||
| 
 | 
 | ||||||
|                               Q_EMIT request->ProgressUpdated(downloadNow, |                Q_EMIT request->ProgressUpdated(downloadNow, downloadTotal); | ||||||
|                                                               downloadTotal); |  | ||||||
| 
 | 
 | ||||||
|                lastUpdated       = now; |                lastUpdated       = now; | ||||||
|                lastDownloadNow   = downloadNow; |                lastDownloadNow   = downloadNow; | ||||||
|  | @ -156,8 +166,8 @@ void DownloadManager::Download( | ||||||
|    ofs.close(); |    ofs.close(); | ||||||
| 
 | 
 | ||||||
|    // Handle error response
 |    // Handle error response
 | ||||||
|          if (response.error.code != cpr::ErrorCode::OK || |    if (response.error.code != cpr::ErrorCode::OK || request->IsCanceled() || | ||||||
|              request->IsCanceled() || !ofsGood) |        !ofsGood) | ||||||
|    { |    { | ||||||
|       request::DownloadRequest::CompleteReason reason = |       request::DownloadRequest::CompleteReason reason = | ||||||
|          request::DownloadRequest::CompleteReason::IOError; |          request::DownloadRequest::CompleteReason::IOError; | ||||||
|  | @ -198,8 +208,7 @@ void DownloadManager::Download( | ||||||
| 
 | 
 | ||||||
|    // Handle response
 |    // Handle response
 | ||||||
|    const auto contentMd5 = response.header.find("content-md5"); |    const auto contentMd5 = response.header.find("content-md5"); | ||||||
|          if (contentMd5 != response.header.cend() && |    if (contentMd5 != response.header.cend() && !contentMd5->second.empty()) | ||||||
|              !contentMd5->second.empty()) |  | ||||||
|    { |    { | ||||||
|       // Open file for reading
 |       // Open file for reading
 | ||||||
|       std::ifstream is {destinationPath, |       std::ifstream is {destinationPath, | ||||||
|  | @ -219,8 +228,7 @@ void DownloadManager::Download( | ||||||
|       std::vector<std::uint8_t> digest {}; |       std::vector<std::uint8_t> digest {}; | ||||||
|       if (!util::ComputeDigest(EVP_md5(), is, digest)) |       if (!util::ComputeDigest(EVP_md5(), is, digest)) | ||||||
|       { |       { | ||||||
|                logger_->error("Failed to compute MD5: {}", |          logger_->error("Failed to compute MD5: {}", destinationPath.string()); | ||||||
|                               destinationPath.string()); |  | ||||||
| 
 | 
 | ||||||
|          Q_EMIT request->RequestComplete( |          Q_EMIT request->RequestComplete( | ||||||
|             request::DownloadRequest::CompleteReason::IOError); |             request::DownloadRequest::CompleteReason::IOError); | ||||||
|  | @ -231,13 +239,13 @@ void DownloadManager::Download( | ||||||
|       // Compare calculated MD5 with digest in response header
 |       // Compare calculated MD5 with digest in response header
 | ||||||
|       QByteArray expectedDigestArray = |       QByteArray expectedDigestArray = | ||||||
|          QByteArray::fromBase64(contentMd5->second.c_str()); |          QByteArray::fromBase64(contentMd5->second.c_str()); | ||||||
|             std::vector<std::uint8_t> expectedDigest( |       std::vector<std::uint8_t> expectedDigest(expectedDigestArray.cbegin(), | ||||||
|                expectedDigestArray.cbegin(), expectedDigestArray.cend()); |                                                expectedDigestArray.cend()); | ||||||
| 
 | 
 | ||||||
|       if (digest != expectedDigest) |       if (digest != expectedDigest) | ||||||
|       { |       { | ||||||
|                QByteArray calculatedDigest( |          QByteArray calculatedDigest(reinterpret_cast<char*>(digest.data()), | ||||||
|                   reinterpret_cast<char*>(digest.data()), digest.size()); |                                      digest.size()); | ||||||
| 
 | 
 | ||||||
|          logger_->error("Digest mismatch: {} != {}", |          logger_->error("Digest mismatch: {} != {}", | ||||||
|                         calculatedDigest.toBase64().toStdString(), |                         calculatedDigest.toBase64().toStdString(), | ||||||
|  | @ -253,7 +261,6 @@ void DownloadManager::Download( | ||||||
|    logger_->info("Download complete: {}", request->url()); |    logger_->info("Download complete: {}", request->url()); | ||||||
|    Q_EMIT request->RequestComplete( |    Q_EMIT request->RequestComplete( | ||||||
|       request::DownloadRequest::CompleteReason::OK); |       request::DownloadRequest::CompleteReason::OK); | ||||||
|       }); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<DownloadManager> DownloadManager::Instance() | std::shared_ptr<DownloadManager> DownloadManager::Instance() | ||||||
|  |  | ||||||
|  | @ -156,6 +156,8 @@ PlacefileManager::PlacefileManager() : p(std::make_unique<Impl>(this)) | ||||||
| { | { | ||||||
|    boost::asio::post(p->threadPool_, |    boost::asio::post(p->threadPool_, | ||||||
|                      [this]() |                      [this]() | ||||||
|  |                      { | ||||||
|  |                         try | ||||||
|                         { |                         { | ||||||
|                            p->InitializePlacefileSettings(); |                            p->InitializePlacefileSettings(); | ||||||
| 
 | 
 | ||||||
|  | @ -163,6 +165,11 @@ PlacefileManager::PlacefileManager() : p(std::make_unique<Impl>(this)) | ||||||
|                            main::Application::WaitForInitialization(); |                            main::Application::WaitForInitialization(); | ||||||
|                            p->ReadPlacefileSettings(); |                            p->ReadPlacefileSettings(); | ||||||
|                            Q_EMIT PlacefilesInitialized(); |                            Q_EMIT PlacefilesInitialized(); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|                      }); |                      }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -678,7 +685,7 @@ void PlacefileManager::Impl::PlacefileRecord::ScheduleRefresh() | ||||||
|          } |          } | ||||||
|          else |          else | ||||||
|          { |          { | ||||||
|             Update(); |             UpdateAsync(); | ||||||
|          } |          } | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  | @ -691,7 +698,18 @@ void PlacefileManager::Impl::PlacefileRecord::CancelRefresh() | ||||||
| 
 | 
 | ||||||
| void PlacefileManager::Impl::PlacefileRecord::UpdateAsync() | void PlacefileManager::Impl::PlacefileRecord::UpdateAsync() | ||||||
| { | { | ||||||
|    boost::asio::post(threadPool_, [this]() { Update(); }); |    boost::asio::post(threadPool_, | ||||||
|  |                      [this]() | ||||||
|  |                      { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                            Update(); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<PlacefileManager> PlacefileManager::Instance() | std::shared_ptr<PlacefileManager> PlacefileManager::Instance() | ||||||
|  |  | ||||||
|  | @ -196,6 +196,7 @@ public: | ||||||
|                       std::shared_ptr<ProviderManager> providerManager, |                       std::shared_ptr<ProviderManager> providerManager, | ||||||
|                       bool                             enabled); |                       bool                             enabled); | ||||||
|    void RefreshData(std::shared_ptr<ProviderManager> providerManager); |    void RefreshData(std::shared_ptr<ProviderManager> providerManager); | ||||||
|  |    void RefreshDataSync(std::shared_ptr<ProviderManager> providerManager); | ||||||
| 
 | 
 | ||||||
|    std::tuple<std::shared_ptr<types::RadarProductRecord>, |    std::tuple<std::shared_ptr<types::RadarProductRecord>, | ||||||
|               std::chrono::system_clock::time_point> |               std::chrono::system_clock::time_point> | ||||||
|  | @ -225,6 +226,8 @@ public: | ||||||
|    void PopulateLevel3ProductTimes(const std::string& product, |    void PopulateLevel3ProductTimes(const std::string& product, | ||||||
|                                    std::chrono::system_clock::time_point time); |                                    std::chrono::system_clock::time_point time); | ||||||
| 
 | 
 | ||||||
|  |    void UpdateAvailableProductsSync(); | ||||||
|  | 
 | ||||||
|    static void |    static void | ||||||
|    PopulateProductTimes(std::shared_ptr<ProviderManager> providerManager, |    PopulateProductTimes(std::shared_ptr<ProviderManager> providerManager, | ||||||
|                         RadarProductRecordMap&           productRecordMap, |                         RadarProductRecordMap&           productRecordMap, | ||||||
|  | @ -575,6 +578,8 @@ void RadarProductManager::EnableRefresh(common::RadarProductGroup group, | ||||||
|       boost::asio::post( |       boost::asio::post( | ||||||
|          p->threadPool_, |          p->threadPool_, | ||||||
|          [=, this]() |          [=, this]() | ||||||
|  |          { | ||||||
|  |             try | ||||||
|             { |             { | ||||||
|                providerManager->provider_->RequestAvailableProducts(); |                providerManager->provider_->RequestAvailableProducts(); | ||||||
|                auto availableProducts = |                auto availableProducts = | ||||||
|  | @ -587,6 +592,11 @@ void RadarProductManager::EnableRefresh(common::RadarProductGroup group, | ||||||
|                { |                { | ||||||
|                   p->EnableRefresh(uuid, providerManager, enabled); |                   p->EnableRefresh(uuid, providerManager, enabled); | ||||||
|                } |                } | ||||||
|  |             } | ||||||
|  |             catch (const std::exception& ex) | ||||||
|  |             { | ||||||
|  |                logger_->error(ex.what()); | ||||||
|  |             } | ||||||
|          }); |          }); | ||||||
|    } |    } | ||||||
| } | } | ||||||
|  | @ -664,27 +674,37 @@ void RadarProductManagerImpl::RefreshData( | ||||||
|       providerManager->refreshTimer_.cancel(); |       providerManager->refreshTimer_.cancel(); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    boost::asio::post( |    boost::asio::post(threadPool_, | ||||||
|       threadPool_, |  | ||||||
|                      [=, this]() |                      [=, this]() | ||||||
|  |                      { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                            RefreshDataSync(providerManager); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RadarProductManagerImpl::RefreshDataSync( | ||||||
|  |    std::shared_ptr<ProviderManager> providerManager) | ||||||
| { | { | ||||||
|    using namespace std::chrono_literals; |    using namespace std::chrono_literals; | ||||||
| 
 | 
 | ||||||
|          auto [newObjects, totalObjects] = |    auto [newObjects, totalObjects] = providerManager->provider_->Refresh(); | ||||||
|             providerManager->provider_->Refresh(); |  | ||||||
| 
 | 
 | ||||||
|    std::chrono::milliseconds interval = kFastRetryInterval_; |    std::chrono::milliseconds interval = kFastRetryInterval_; | ||||||
| 
 | 
 | ||||||
|    if (totalObjects > 0) |    if (totalObjects > 0) | ||||||
|    { |    { | ||||||
|       std::string key = providerManager->provider_->FindLatestKey(); |       std::string key = providerManager->provider_->FindLatestKey(); | ||||||
|             auto        latestTime = |       auto latestTime = providerManager->provider_->GetTimePointByKey(key); | ||||||
|                providerManager->provider_->GetTimePointByKey(key); |  | ||||||
| 
 | 
 | ||||||
|       auto updatePeriod      = providerManager->provider_->update_period(); |       auto updatePeriod      = providerManager->provider_->update_period(); | ||||||
|       auto lastModified      = providerManager->provider_->last_modified(); |       auto lastModified      = providerManager->provider_->last_modified(); | ||||||
|             auto sinceLastModified = |       auto sinceLastModified = std::chrono::system_clock::now() - lastModified; | ||||||
|                std::chrono::system_clock::now() - lastModified; |  | ||||||
| 
 | 
 | ||||||
|       // For the default interval, assume products are updated at a
 |       // For the default interval, assume products are updated at a
 | ||||||
|       // constant rate. Expect the next product at a time based on the
 |       // constant rate. Expect the next product at a time based on the
 | ||||||
|  | @ -707,9 +727,7 @@ void RadarProductManagerImpl::RefreshData( | ||||||
|       if (newObjects > 0) |       if (newObjects > 0) | ||||||
|       { |       { | ||||||
|          Q_EMIT providerManager->NewDataAvailable( |          Q_EMIT providerManager->NewDataAvailable( | ||||||
|                   providerManager->group_, |             providerManager->group_, providerManager->product_, latestTime); | ||||||
|                   providerManager->product_, |  | ||||||
|                   latestTime); |  | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|    else if (providerManager->refreshEnabled_) |    else if (providerManager->refreshEnabled_) | ||||||
|  | @ -752,7 +770,6 @@ void RadarProductManagerImpl::RefreshData( | ||||||
|             }); |             }); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|       }); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::set<std::chrono::system_clock::time_point> | std::set<std::chrono::system_clock::time_point> | ||||||
|  | @ -1009,7 +1026,16 @@ void RadarProductManagerImpl::LoadNexradFileAsync( | ||||||
| { | { | ||||||
|    boost::asio::post(threadPool_, |    boost::asio::post(threadPool_, | ||||||
|                      [=, &mutex]() |                      [=, &mutex]() | ||||||
|                      { LoadNexradFile(load, request, mutex, time); }); |                      { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                            LoadNexradFile(load, request, mutex, time); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RadarProductManagerImpl::LoadNexradFile( | void RadarProductManagerImpl::LoadNexradFile( | ||||||
|  | @ -1441,31 +1467,41 @@ void RadarProductManager::UpdateAvailableProducts() | ||||||
| 
 | 
 | ||||||
|    logger_->debug("UpdateAvailableProducts()"); |    logger_->debug("UpdateAvailableProducts()"); | ||||||
| 
 | 
 | ||||||
|    boost::asio::post( |    boost::asio::post(p->threadPool_, | ||||||
|       p->threadPool_, |  | ||||||
|                      [this]() |                      [this]() | ||||||
|  |                      { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                            p->UpdateAvailableProductsSync(); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RadarProductManagerImpl::UpdateAvailableProductsSync() | ||||||
| { | { | ||||||
|    auto level3ProviderManager = |    auto level3ProviderManager = | ||||||
|             p->GetLevel3ProviderManager(kDefaultLevel3Product_); |       GetLevel3ProviderManager(kDefaultLevel3Product_); | ||||||
|    level3ProviderManager->provider_->RequestAvailableProducts(); |    level3ProviderManager->provider_->RequestAvailableProducts(); | ||||||
|    auto updatedAwipsIdList = |    auto updatedAwipsIdList = | ||||||
|       level3ProviderManager->provider_->GetAvailableProducts(); |       level3ProviderManager->provider_->GetAvailableProducts(); | ||||||
| 
 | 
 | ||||||
|          std::unique_lock lock {p->availableCategoryMutex_}; |    std::unique_lock lock {availableCategoryMutex_}; | ||||||
| 
 | 
 | ||||||
|    for (common::Level3ProductCategory category : |    for (common::Level3ProductCategory category : | ||||||
|         common::Level3ProductCategoryIterator()) |         common::Level3ProductCategoryIterator()) | ||||||
|    { |    { | ||||||
|             const auto& products = |       const auto& products = common::GetLevel3ProductsByCategory(category); | ||||||
|                common::GetLevel3ProductsByCategory(category); |  | ||||||
| 
 | 
 | ||||||
|       std::unordered_map<std::string, std::vector<std::string>> |       std::unordered_map<std::string, std::vector<std::string>> | ||||||
|          availableProducts; |          availableProducts; | ||||||
| 
 | 
 | ||||||
|       for (const auto& product : products) |       for (const auto& product : products) | ||||||
|       { |       { | ||||||
|                const auto& awipsIds = |          const auto& awipsIds = common::GetLevel3AwipsIdsByProduct(product); | ||||||
|                   common::GetLevel3AwipsIdsByProduct(product); |  | ||||||
| 
 | 
 | ||||||
|          std::vector<std::string> availableAwipsIds; |          std::vector<std::string> availableAwipsIds; | ||||||
| 
 | 
 | ||||||
|  | @ -1481,24 +1517,23 @@ void RadarProductManager::UpdateAvailableProducts() | ||||||
| 
 | 
 | ||||||
|          if (!availableAwipsIds.empty()) |          if (!availableAwipsIds.empty()) | ||||||
|          { |          { | ||||||
|                   availableProducts.insert_or_assign( |             availableProducts.insert_or_assign(product, | ||||||
|                      product, std::move(availableAwipsIds)); |                                                std::move(availableAwipsIds)); | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (!availableProducts.empty()) |       if (!availableProducts.empty()) | ||||||
|       { |       { | ||||||
|                p->availableCategoryMap_.insert_or_assign( |          availableCategoryMap_.insert_or_assign(category, | ||||||
|                   category, std::move(availableProducts)); |                                                 std::move(availableProducts)); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|                p->availableCategoryMap_.erase(category); |          availableCategoryMap_.erase(category); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|          Q_EMIT Level3ProductsChanged(); |    Q_EMIT self_->Level3ProductsChanged(); | ||||||
|       }); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<RadarProductManager> | std::shared_ptr<RadarProductManager> | ||||||
|  |  | ||||||
|  | @ -49,10 +49,17 @@ public: | ||||||
| 
 | 
 | ||||||
|       boost::asio::post(threadPool_, |       boost::asio::post(threadPool_, | ||||||
|                         [this]() |                         [this]() | ||||||
|  |                         { | ||||||
|  |                            try | ||||||
|                            { |                            { | ||||||
|                               main::Application::WaitForInitialization(); |                               main::Application::WaitForInitialization(); | ||||||
|                               logger_->debug("Start Refresh"); |                               logger_->debug("Start Refresh"); | ||||||
|                               Refresh(); |                               Refresh(); | ||||||
|  |                            } | ||||||
|  |                            catch (const std::exception& ex) | ||||||
|  |                            { | ||||||
|  |                               logger_->error(ex.what()); | ||||||
|  |                            } | ||||||
|                         }); |                         }); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  | @ -70,6 +77,7 @@ public: | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    void HandleMessage(std::shared_ptr<awips::TextProductMessage> message); |    void HandleMessage(std::shared_ptr<awips::TextProductMessage> message); | ||||||
|  |    void RefreshAsync(); | ||||||
|    void Refresh(); |    void Refresh(); | ||||||
| 
 | 
 | ||||||
|    boost::asio::thread_pool threadPool_ {1u}; |    boost::asio::thread_pool threadPool_ {1u}; | ||||||
|  | @ -130,6 +138,8 @@ void TextEventManager::LoadFile(const std::string& filename) | ||||||
| 
 | 
 | ||||||
|    boost::asio::post(p->threadPool_, |    boost::asio::post(p->threadPool_, | ||||||
|                      [=, this]() |                      [=, this]() | ||||||
|  |                      { | ||||||
|  |                         try | ||||||
|                         { |                         { | ||||||
|                            awips::TextProductFile file; |                            awips::TextProductFile file; | ||||||
| 
 | 
 | ||||||
|  | @ -146,6 +156,11 @@ void TextEventManager::LoadFile(const std::string& filename) | ||||||
|                            { |                            { | ||||||
|                               p->HandleMessage(message); |                               p->HandleMessage(message); | ||||||
|                            } |                            } | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|                      }); |                      }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -212,6 +227,22 @@ void TextEventManager::Impl::HandleMessage( | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void TextEventManager::Impl::RefreshAsync() | ||||||
|  | { | ||||||
|  |    boost::asio::post(threadPool_, | ||||||
|  |                      [this]() | ||||||
|  |                      { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                            Refresh(); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void TextEventManager::Impl::Refresh() | void TextEventManager::Impl::Refresh() | ||||||
| { | { | ||||||
|    logger_->trace("Refresh"); |    logger_->trace("Refresh"); | ||||||
|  | @ -257,7 +288,7 @@ void TextEventManager::Impl::Refresh() | ||||||
|          } |          } | ||||||
|          else |          else | ||||||
|          { |          { | ||||||
|             Refresh(); |             RefreshAsync(); | ||||||
|          } |          } | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -69,11 +69,13 @@ public: | ||||||
| 
 | 
 | ||||||
|    void Pause(); |    void Pause(); | ||||||
|    void Play(); |    void Play(); | ||||||
|  |    void PlaySync(); | ||||||
|    void |    void | ||||||
|    SelectTimeAsync(std::chrono::system_clock::time_point selectedTime = {}); |    SelectTimeAsync(std::chrono::system_clock::time_point selectedTime = {}); | ||||||
|    std::pair<bool, bool> |    std::pair<bool, bool> | ||||||
|         SelectTime(std::chrono::system_clock::time_point selectedTime = {}); |         SelectTime(std::chrono::system_clock::time_point selectedTime = {}); | ||||||
|    void StepAsync(Direction direction); |    void StepAsync(Direction direction); | ||||||
|  |    void Step(Direction direction); | ||||||
| 
 | 
 | ||||||
|    boost::asio::thread_pool playThreadPool_ {1}; |    boost::asio::thread_pool playThreadPool_ {1}; | ||||||
|    boost::asio::thread_pool selectThreadPool_ {1}; |    boost::asio::thread_pool selectThreadPool_ {1}; | ||||||
|  | @ -405,8 +407,6 @@ void TimelineManager::Impl::UpdateCacheLimit( | ||||||
| 
 | 
 | ||||||
| void TimelineManager::Impl::Play() | void TimelineManager::Impl::Play() | ||||||
| { | { | ||||||
|    using namespace std::chrono_literals; |  | ||||||
| 
 |  | ||||||
|    if (animationState_ != types::AnimationState::Play) |    if (animationState_ != types::AnimationState::Play) | ||||||
|    { |    { | ||||||
|       animationState_ = types::AnimationState::Play; |       animationState_ = types::AnimationState::Play; | ||||||
|  | @ -418,10 +418,24 @@ void TimelineManager::Impl::Play() | ||||||
|       animationTimer_.cancel(); |       animationTimer_.cancel(); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    boost::asio::post( |    boost::asio::post(playThreadPool_, | ||||||
|       playThreadPool_, |  | ||||||
|                      [this]() |                      [this]() | ||||||
|                      { |                      { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                            PlaySync(); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TimelineManager::Impl::PlaySync() | ||||||
|  | { | ||||||
|  |    using namespace std::chrono_literals; | ||||||
|  | 
 | ||||||
|    // Take a lock for time selection
 |    // Take a lock for time selection
 | ||||||
|    std::unique_lock lock {selectTimeMutex_}; |    std::unique_lock lock {selectTimeMutex_}; | ||||||
| 
 | 
 | ||||||
|  | @ -504,14 +518,23 @@ void TimelineManager::Impl::Play() | ||||||
|             logger_->warn("Play timer error: {}", e.message()); |             logger_->warn("Play timer error: {}", e.message()); | ||||||
|          } |          } | ||||||
|       }); |       }); | ||||||
|       }); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void TimelineManager::Impl::SelectTimeAsync( | void TimelineManager::Impl::SelectTimeAsync( | ||||||
|    std::chrono::system_clock::time_point selectedTime) |    std::chrono::system_clock::time_point selectedTime) | ||||||
| { | { | ||||||
|    boost::asio::post(selectThreadPool_, |    boost::asio::post(selectThreadPool_, | ||||||
|                      [=, this]() { SelectTime(selectedTime); }); |                      [=, this]() | ||||||
|  |                      { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                            SelectTime(selectedTime); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::pair<bool, bool> TimelineManager::Impl::SelectTime( | std::pair<bool, bool> TimelineManager::Impl::SelectTime( | ||||||
|  | @ -597,9 +620,21 @@ std::pair<bool, bool> TimelineManager::Impl::SelectTime( | ||||||
| 
 | 
 | ||||||
| void TimelineManager::Impl::StepAsync(Direction direction) | void TimelineManager::Impl::StepAsync(Direction direction) | ||||||
| { | { | ||||||
|    boost::asio::post( |    boost::asio::post(selectThreadPool_, | ||||||
|       selectThreadPool_, |  | ||||||
|                      [=, this]() |                      [=, this]() | ||||||
|  |                      { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                            Step(direction); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TimelineManager::Impl::Step(Direction direction) | ||||||
| { | { | ||||||
|    // Take a lock for time selection
 |    // Take a lock for time selection
 | ||||||
|    std::unique_lock lock {selectTimeMutex_}; |    std::unique_lock lock {selectTimeMutex_}; | ||||||
|  | @ -614,8 +649,7 @@ void TimelineManager::Impl::StepAsync(Direction direction) | ||||||
|    // Request active volume times
 |    // Request active volume times
 | ||||||
|    auto radarProductManager = |    auto radarProductManager = | ||||||
|       manager::RadarProductManager::Instance(radarSite_); |       manager::RadarProductManager::Instance(radarSite_); | ||||||
|          auto volumeTimes = |    auto volumeTimes = radarProductManager->GetActiveVolumeTimes(queryTime); | ||||||
|             radarProductManager->GetActiveVolumeTimes(queryTime); |  | ||||||
| 
 | 
 | ||||||
|    if (volumeTimes.empty()) |    if (volumeTimes.empty()) | ||||||
|    { |    { | ||||||
|  | @ -636,8 +670,7 @@ void TimelineManager::Impl::StepAsync(Direction direction) | ||||||
|    else |    else | ||||||
|    { |    { | ||||||
|       // Get the current element in the set
 |       // Get the current element in the set
 | ||||||
|             it = scwx::util::GetBoundedElementIterator(volumeTimes, |       it = scwx::util::GetBoundedElementIterator(volumeTimes, adjustedTime_); | ||||||
|                                                        adjustedTime_); |  | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    if (it == volumeTimes.cend()) |    if (it == volumeTimes.cend()) | ||||||
|  | @ -681,7 +714,6 @@ void TimelineManager::Impl::StepAsync(Direction direction) | ||||||
|          Q_EMIT self_->SelectedTimeUpdated(adjustedTime_); |          Q_EMIT self_->SelectedTimeUpdated(adjustedTime_); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|       }); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<TimelineManager> TimelineManager::Instance() | std::shared_ptr<TimelineManager> TimelineManager::Instance() | ||||||
|  |  | ||||||
|  | @ -325,9 +325,16 @@ void AlertLayerHandler::UpdateAlerts() | ||||||
|             logger_->warn("Alert update timer error: {}", e.message()); |             logger_->warn("Alert update timer error: {}", e.message()); | ||||||
|          } |          } | ||||||
|          else |          else | ||||||
|  |          { | ||||||
|  |             try | ||||||
|             { |             { | ||||||
|                UpdateAlerts(); |                UpdateAlerts(); | ||||||
|             } |             } | ||||||
|  |             catch (const std::exception& ex) | ||||||
|  |             { | ||||||
|  |                logger_->error(ex.what()); | ||||||
|  |             } | ||||||
|  |          } | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1637,6 +1637,8 @@ void MapWidgetImpl::RadarProductManagerConnect() | ||||||
|                boost::asio::post( |                boost::asio::post( | ||||||
|                   threadPool_, |                   threadPool_, | ||||||
|                   [=, this]() |                   [=, this]() | ||||||
|  |                   { | ||||||
|  |                      try | ||||||
|                      { |                      { | ||||||
|                         if (group == common::RadarProductGroup::Level2) |                         if (group == common::RadarProductGroup::Level2) | ||||||
|                         { |                         { | ||||||
|  | @ -1648,6 +1650,11 @@ void MapWidgetImpl::RadarProductManagerConnect() | ||||||
|                            radarProductManager_->LoadLevel3Data( |                            radarProductManager_->LoadLevel3Data( | ||||||
|                               product, latestTime, request); |                               product, latestTime, request); | ||||||
|                         } |                         } | ||||||
|  |                      } | ||||||
|  |                      catch (const std::exception& ex) | ||||||
|  |                      { | ||||||
|  |                         logger_->error(ex.what()); | ||||||
|  |                      } | ||||||
|                   }); |                   }); | ||||||
|             } |             } | ||||||
|          }, |          }, | ||||||
|  | @ -1672,7 +1679,10 @@ void MapWidgetImpl::InitializeNewRadarProductView( | ||||||
|    boost::asio::post(threadPool_, |    boost::asio::post(threadPool_, | ||||||
|                      [=, this]() |                      [=, this]() | ||||||
|                      { |                      { | ||||||
|                         auto radarProductView = context_->radar_product_view(); |                         try | ||||||
|  |                         { | ||||||
|  |                            auto radarProductView = | ||||||
|  |                               context_->radar_product_view(); | ||||||
| 
 | 
 | ||||||
|                            std::string colorTableFile = |                            std::string colorTableFile = | ||||||
|                               settings::PaletteSettings::Instance() |                               settings::PaletteSettings::Instance() | ||||||
|  | @ -1688,6 +1698,11 @@ void MapWidgetImpl::InitializeNewRadarProductView( | ||||||
|                            } |                            } | ||||||
| 
 | 
 | ||||||
|                            radarProductView->Initialize(); |                            radarProductView->Initialize(); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|                      }); |                      }); | ||||||
| 
 | 
 | ||||||
|    if (map_ != nullptr) |    if (map_ != nullptr) | ||||||
|  |  | ||||||
|  | @ -45,6 +45,7 @@ public: | ||||||
|    ~Impl() { threadPool_.join(); } |    ~Impl() { threadPool_.join(); } | ||||||
| 
 | 
 | ||||||
|    void ConnectSignals(); |    void ConnectSignals(); | ||||||
|  |    void ReloadDataSync(); | ||||||
| 
 | 
 | ||||||
|    boost::asio::thread_pool threadPool_ {1}; |    boost::asio::thread_pool threadPool_ {1}; | ||||||
| 
 | 
 | ||||||
|  | @ -170,72 +171,77 @@ void PlacefileLayer::Deinitialize() | ||||||
| 
 | 
 | ||||||
| void PlacefileLayer::ReloadData() | void PlacefileLayer::ReloadData() | ||||||
| { | { | ||||||
|    boost::asio::post( |    boost::asio::post(p->threadPool_, | ||||||
|       p->threadPool_, |  | ||||||
|                      [this]() |                      [this]() | ||||||
|                      { |                      { | ||||||
|          logger_->debug("ReloadData: {}", p->placefileName_); |                         try | ||||||
|  |                         { | ||||||
|  |                            p->ReloadDataSync(); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|          std::unique_lock lock {p->dataMutex_}; | void PlacefileLayer::Impl::ReloadDataSync() | ||||||
|  | { | ||||||
|  |    logger_->debug("ReloadData: {}", placefileName_); | ||||||
|  | 
 | ||||||
|  |    std::unique_lock lock {dataMutex_}; | ||||||
| 
 | 
 | ||||||
|    std::shared_ptr<manager::PlacefileManager> placefileManager = |    std::shared_ptr<manager::PlacefileManager> placefileManager = | ||||||
|       manager::PlacefileManager::Instance(); |       manager::PlacefileManager::Instance(); | ||||||
| 
 | 
 | ||||||
|          auto placefile = placefileManager->placefile(p->placefileName_); |    auto placefile = placefileManager->placefile(placefileName_); | ||||||
|    if (placefile == nullptr) |    if (placefile == nullptr) | ||||||
|    { |    { | ||||||
|       return; |       return; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    // Start draw items
 |    // Start draw items
 | ||||||
|          p->placefileIcons_->StartIcons(); |    placefileIcons_->StartIcons(); | ||||||
|          p->placefileImages_->StartImages(placefile->name()); |    placefileImages_->StartImages(placefile->name()); | ||||||
|          p->placefileLines_->StartLines(); |    placefileLines_->StartLines(); | ||||||
|          p->placefilePolygons_->StartPolygons(); |    placefilePolygons_->StartPolygons(); | ||||||
|          p->placefileTriangles_->StartTriangles(); |    placefileTriangles_->StartTriangles(); | ||||||
|          p->placefileText_->StartText(); |    placefileText_->StartText(); | ||||||
| 
 | 
 | ||||||
|          p->placefileIcons_->SetIconFiles(placefile->icon_files(), |    placefileIcons_->SetIconFiles(placefile->icon_files(), placefile->name()); | ||||||
|                                           placefile->name()); |    placefileText_->SetFonts(placefileManager->placefile_fonts(placefileName_)); | ||||||
|          p->placefileText_->SetFonts( |  | ||||||
|             placefileManager->placefile_fonts(p->placefileName_)); |  | ||||||
| 
 | 
 | ||||||
|    for (auto& drawItem : placefile->GetDrawItems()) |    for (auto& drawItem : placefile->GetDrawItems()) | ||||||
|    { |    { | ||||||
|       switch (drawItem->itemType_) |       switch (drawItem->itemType_) | ||||||
|       { |       { | ||||||
|       case gr::Placefile::ItemType::Text: |       case gr::Placefile::ItemType::Text: | ||||||
|                p->placefileText_->AddText( |          placefileText_->AddText( | ||||||
|                   std::static_pointer_cast<gr::Placefile::TextDrawItem>( |             std::static_pointer_cast<gr::Placefile::TextDrawItem>(drawItem)); | ||||||
|                      drawItem)); |  | ||||||
|          break; |          break; | ||||||
| 
 | 
 | ||||||
|       case gr::Placefile::ItemType::Icon: |       case gr::Placefile::ItemType::Icon: | ||||||
|                p->placefileIcons_->AddIcon( |          placefileIcons_->AddIcon( | ||||||
|                   std::static_pointer_cast<gr::Placefile::IconDrawItem>( |             std::static_pointer_cast<gr::Placefile::IconDrawItem>(drawItem)); | ||||||
|                      drawItem)); |  | ||||||
|          break; |          break; | ||||||
| 
 | 
 | ||||||
|       case gr::Placefile::ItemType::Line: |       case gr::Placefile::ItemType::Line: | ||||||
|                p->placefileLines_->AddLine( |          placefileLines_->AddLine( | ||||||
|                   std::static_pointer_cast<gr::Placefile::LineDrawItem>( |             std::static_pointer_cast<gr::Placefile::LineDrawItem>(drawItem)); | ||||||
|                      drawItem)); |  | ||||||
|          break; |          break; | ||||||
| 
 | 
 | ||||||
|       case gr::Placefile::ItemType::Polygon: |       case gr::Placefile::ItemType::Polygon: | ||||||
|                p->placefilePolygons_->AddPolygon( |          placefilePolygons_->AddPolygon( | ||||||
|                   std::static_pointer_cast<gr::Placefile::PolygonDrawItem>( |             std::static_pointer_cast<gr::Placefile::PolygonDrawItem>(drawItem)); | ||||||
|                      drawItem)); |  | ||||||
|          break; |          break; | ||||||
| 
 | 
 | ||||||
|       case gr::Placefile::ItemType::Image: |       case gr::Placefile::ItemType::Image: | ||||||
|                p->placefileImages_->AddImage( |          placefileImages_->AddImage( | ||||||
|                   std::static_pointer_cast<gr::Placefile::ImageDrawItem>( |             std::static_pointer_cast<gr::Placefile::ImageDrawItem>(drawItem)); | ||||||
|                      drawItem)); |  | ||||||
|          break; |          break; | ||||||
| 
 | 
 | ||||||
|       case gr::Placefile::ItemType::Triangles: |       case gr::Placefile::ItemType::Triangles: | ||||||
|                p->placefileTriangles_->AddTriangles( |          placefileTriangles_->AddTriangles( | ||||||
|             std::static_pointer_cast<gr::Placefile::TrianglesDrawItem>( |             std::static_pointer_cast<gr::Placefile::TrianglesDrawItem>( | ||||||
|                drawItem)); |                drawItem)); | ||||||
|          break; |          break; | ||||||
|  | @ -246,15 +252,14 @@ void PlacefileLayer::ReloadData() | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    // Finish draw items
 |    // Finish draw items
 | ||||||
|          p->placefileIcons_->FinishIcons(); |    placefileIcons_->FinishIcons(); | ||||||
|          p->placefileImages_->FinishImages(); |    placefileImages_->FinishImages(); | ||||||
|          p->placefileLines_->FinishLines(); |    placefileLines_->FinishLines(); | ||||||
|          p->placefilePolygons_->FinishPolygons(); |    placefilePolygons_->FinishPolygons(); | ||||||
|          p->placefileTriangles_->FinishTriangles(); |    placefileTriangles_->FinishTriangles(); | ||||||
|          p->placefileText_->FinishText(); |    placefileText_->FinishText(); | ||||||
| 
 | 
 | ||||||
|          Q_EMIT DataReloaded(); |    Q_EMIT self_->DataReloaded(); | ||||||
|       }); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace map
 | } // namespace map
 | ||||||
|  |  | ||||||
|  | @ -119,9 +119,16 @@ void AlertProxyModelImpl::UpdateAlerts() | ||||||
|             logger_->warn("Alert update timer error: {}", e.message()); |             logger_->warn("Alert update timer error: {}", e.message()); | ||||||
|          } |          } | ||||||
|          else |          else | ||||||
|  |          { | ||||||
|  |             try | ||||||
|             { |             { | ||||||
|                UpdateAlerts(); |                UpdateAlerts(); | ||||||
|             } |             } | ||||||
|  |             catch (const std::exception& ex) | ||||||
|  |             { | ||||||
|  |                logger_->error(ex.what()); | ||||||
|  |             } | ||||||
|  |          } | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -237,10 +237,19 @@ void OverlayProductView::Impl::LoadProduct( | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    // Load file
 |    // Load file
 | ||||||
|    boost::asio::post( |    boost::asio::post(threadPool_, | ||||||
|       threadPool_, |  | ||||||
|                      [=, this]() |                      [=, this]() | ||||||
|       { radarProductManager_->LoadLevel3Data(product, time, request); }); |                      { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                            radarProductManager_->LoadLevel3Data( | ||||||
|  |                               product, time, request); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void OverlayProductView::Impl::ResetProducts() | void OverlayProductView::Impl::ResetProducts() | ||||||
|  |  | ||||||
|  | @ -121,7 +121,18 @@ void RadarProductView::SelectTime(std::chrono::system_clock::time_point time) | ||||||
| 
 | 
 | ||||||
| void RadarProductView::Update() | void RadarProductView::Update() | ||||||
| { | { | ||||||
|    boost::asio::post(thread_pool(), [this]() { ComputeSweep(); }); |    boost::asio::post(thread_pool(), | ||||||
|  |                      [this]() | ||||||
|  |                      { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                            ComputeSweep(); | ||||||
|  |                         } | ||||||
|  |                         catch (const std::exception& ex) | ||||||
|  |                         { | ||||||
|  |                            logger_->error(ex.what()); | ||||||
|  |                         } | ||||||
|  |                      }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool RadarProductView::IsInitialized() const | bool RadarProductView::IsInitialized() const | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat