mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 23:20:05 +00:00 
			
		
		
		
	Load placefiles from remote URLs
This commit is contained in:
		
							parent
							
								
									61bfeb88d0
								
							
						
					
					
						commit
						dcace24579
					
				
					 1 changed files with 98 additions and 6 deletions
				
			
		|  | @ -10,6 +10,7 @@ | ||||||
| #include <boost/asio/post.hpp> | #include <boost/asio/post.hpp> | ||||||
| #include <boost/asio/steady_timer.hpp> | #include <boost/asio/steady_timer.hpp> | ||||||
| #include <boost/asio/thread_pool.hpp> | #include <boost/asio/thread_pool.hpp> | ||||||
|  | #include <cpr/cpr.h> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
|  | @ -21,8 +22,10 @@ namespace manager | ||||||
| static const std::string logPrefix_ = "scwx::qt::manager::placefile_manager"; | static const std::string logPrefix_ = "scwx::qt::manager::placefile_manager"; | ||||||
| static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
| 
 | 
 | ||||||
| class PlacefileRecord | class PlacefileRecord : public QObject | ||||||
| { | { | ||||||
|  |    Q_OBJECT | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
|    explicit PlacefileRecord(const std::string&             name, |    explicit PlacefileRecord(const std::string&             name, | ||||||
|                             std::shared_ptr<gr::Placefile> placefile, |                             std::shared_ptr<gr::Placefile> placefile, | ||||||
|  | @ -36,7 +39,9 @@ public: | ||||||
|       refreshTimer_.cancel(); |       refreshTimer_.cancel(); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    void Update(std::shared_ptr<gr::Placefile> placefile); |    void Update(); | ||||||
|  |    void UpdateAsync(); | ||||||
|  |    void UpdatePlacefile(std::shared_ptr<gr::Placefile> placefile); | ||||||
| 
 | 
 | ||||||
|    std::string                    name_; |    std::string                    name_; | ||||||
|    std::shared_ptr<gr::Placefile> placefile_; |    std::shared_ptr<gr::Placefile> placefile_; | ||||||
|  | @ -45,6 +50,10 @@ public: | ||||||
|    boost::asio::thread_pool       threadPool_ {1u}; |    boost::asio::thread_pool       threadPool_ {1u}; | ||||||
|    boost::asio::steady_timer      refreshTimer_ {threadPool_}; |    boost::asio::steady_timer      refreshTimer_ {threadPool_}; | ||||||
|    std::mutex                     refreshMutex_ {}; |    std::mutex                     refreshMutex_ {}; | ||||||
|  | 
 | ||||||
|  | signals: | ||||||
|  |    void Updated(const std::string&             name, | ||||||
|  |                 std::shared_ptr<gr::Placefile> placefile); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class PlacefileManager::Impl | class PlacefileManager::Impl | ||||||
|  | @ -55,6 +64,8 @@ public: | ||||||
| 
 | 
 | ||||||
|    static std::string NormalizeUrl(const std::string& urlString); |    static std::string NormalizeUrl(const std::string& urlString); | ||||||
| 
 | 
 | ||||||
|  |    void ConnectRecordSignals(std::shared_ptr<PlacefileRecord> record); | ||||||
|  | 
 | ||||||
|    boost::asio::thread_pool threadPool_ {1u}; |    boost::asio::thread_pool threadPool_ {1u}; | ||||||
| 
 | 
 | ||||||
|    PlacefileManager* self_; |    PlacefileManager* self_; | ||||||
|  | @ -158,9 +169,36 @@ void PlacefileManager::set_placefile_url(const std::string& name, | ||||||
|       lock.unlock(); |       lock.unlock(); | ||||||
| 
 | 
 | ||||||
|       Q_EMIT PlacefileRenamed(name, normalizedUrl); |       Q_EMIT PlacefileRenamed(name, normalizedUrl); | ||||||
|  | 
 | ||||||
|  |       // Queue a placefile update
 | ||||||
|  |       placefileRecord->UpdateAsync(); | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void PlacefileManager::Impl::ConnectRecordSignals( | ||||||
|  |    std::shared_ptr<PlacefileRecord> record) | ||||||
|  | { | ||||||
|  |    QObject::connect( | ||||||
|  |       record.get(), | ||||||
|  |       &PlacefileRecord::Updated, | ||||||
|  |       self_, | ||||||
|  |       [this](const std::string& name, std::shared_ptr<gr::Placefile> placefile) | ||||||
|  |       { | ||||||
|  |          PlacefileRecord* sender = | ||||||
|  |             static_cast<PlacefileRecord*>(self_->sender()); | ||||||
|  | 
 | ||||||
|  |          // Check the name matches, in case the name updated
 | ||||||
|  |          if (sender->name_ == name) | ||||||
|  |          { | ||||||
|  |             // Update the placefile
 | ||||||
|  |             sender->placefile_ = placefile; | ||||||
|  | 
 | ||||||
|  |             // Notify slots of the placefile update
 | ||||||
|  |             Q_EMIT self_->PlacefileUpdated(name); | ||||||
|  |          } | ||||||
|  |       }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::vector<std::shared_ptr<gr::Placefile>> | std::vector<std::shared_ptr<gr::Placefile>> | ||||||
| PlacefileManager::GetActivePlacefiles() | PlacefileManager::GetActivePlacefiles() | ||||||
| { | { | ||||||
|  | @ -200,13 +238,17 @@ void PlacefileManager::AddUrl(const std::string& urlString) | ||||||
|    logger_->info("AddUrl: {}", normalizedUrl); |    logger_->info("AddUrl: {}", normalizedUrl); | ||||||
| 
 | 
 | ||||||
|    // Add an empty placefile record for the new URL
 |    // Add an empty placefile record for the new URL
 | ||||||
|    auto placefileRecord = p->placefileRecords_.emplace_back( |    auto& record = p->placefileRecords_.emplace_back( | ||||||
|       std::make_shared<PlacefileRecord>(normalizedUrl, nullptr, false)); |       std::make_shared<PlacefileRecord>(normalizedUrl, nullptr, false)); | ||||||
|    p->placefileRecordMap_.insert_or_assign(normalizedUrl, placefileRecord); |    p->placefileRecordMap_.insert_or_assign(normalizedUrl, record); | ||||||
|  |    p->ConnectRecordSignals(record); | ||||||
| 
 | 
 | ||||||
|    lock.unlock(); |    lock.unlock(); | ||||||
| 
 | 
 | ||||||
|    Q_EMIT PlacefileUpdated(normalizedUrl); |    Q_EMIT PlacefileUpdated(normalizedUrl); | ||||||
|  | 
 | ||||||
|  |    // Queue a placefile update
 | ||||||
|  |    record->UpdateAsync(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefileManager::LoadFile(const std::string& filename) | void PlacefileManager::LoadFile(const std::string& filename) | ||||||
|  | @ -236,7 +278,7 @@ void PlacefileManager::LoadFile(const std::string& filename) | ||||||
|          if (it != p->placefileRecordMap_.end()) |          if (it != p->placefileRecordMap_.end()) | ||||||
|          { |          { | ||||||
|             // If the placefile has been loaded previously, update it
 |             // If the placefile has been loaded previously, update it
 | ||||||
|             it->second->Update(placefile); |             it->second->UpdatePlacefile(placefile); | ||||||
| 
 | 
 | ||||||
|             lock.unlock(); |             lock.unlock(); | ||||||
| 
 | 
 | ||||||
|  | @ -248,6 +290,7 @@ void PlacefileManager::LoadFile(const std::string& filename) | ||||||
|             auto& record = p->placefileRecords_.emplace_back( |             auto& record = p->placefileRecords_.emplace_back( | ||||||
|                std::make_shared<PlacefileRecord>(placefileName, placefile)); |                std::make_shared<PlacefileRecord>(placefileName, placefile)); | ||||||
|             p->placefileRecordMap_.insert_or_assign(placefileName, record); |             p->placefileRecordMap_.insert_or_assign(placefileName, record); | ||||||
|  |             p->ConnectRecordSignals(record); | ||||||
| 
 | 
 | ||||||
|             lock.unlock(); |             lock.unlock(); | ||||||
| 
 | 
 | ||||||
|  | @ -257,7 +300,54 @@ void PlacefileManager::LoadFile(const std::string& filename) | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefileRecord::Update(std::shared_ptr<gr::Placefile> placefile) | void PlacefileRecord::Update() | ||||||
|  | { | ||||||
|  |    // Make a copy of name in the event it changes.
 | ||||||
|  |    const std::string name {name_}; | ||||||
|  | 
 | ||||||
|  |    std::shared_ptr<gr::Placefile> updatedPlacefile {}; | ||||||
|  | 
 | ||||||
|  |    QUrl url = QUrl::fromUserInput(QString::fromStdString(name)); | ||||||
|  |    if (url.isLocalFile()) | ||||||
|  |    { | ||||||
|  |       updatedPlacefile = gr::Placefile::Load(name); | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       // TODO: Update hard coded parameters
 | ||||||
|  |       auto response = cpr::Get( | ||||||
|  |          cpr::Url {name}, | ||||||
|  |          cpr::Header {{"User-Agent", "Supercell Wx/0.2.2"}}, | ||||||
|  |          cpr::Parameters { | ||||||
|  |             {"version", "1.2"}, {"lat", "38.699"}, {"lon", "-90.683"}}); | ||||||
|  | 
 | ||||||
|  |       if (response.status_code == cpr::status::HTTP_OK) | ||||||
|  |       { | ||||||
|  |          std::istringstream responseBody {response.text}; | ||||||
|  |          updatedPlacefile = gr::Placefile::Load(name, responseBody); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          logger_->warn("Error loading placefile: {}", response.error.message); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (updatedPlacefile != nullptr) | ||||||
|  |    { | ||||||
|  |       Q_EMIT Updated(name, updatedPlacefile); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // TODO: Update refresh timer
 | ||||||
|  |    // TODO: Can running this function out of sync with an existing refresh timer
 | ||||||
|  |    // cause issues?
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void PlacefileRecord::UpdateAsync() | ||||||
|  | { | ||||||
|  |    boost::asio::post(threadPool_, [this]() { Update(); }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void PlacefileRecord::UpdatePlacefile(std::shared_ptr<gr::Placefile> placefile) | ||||||
| { | { | ||||||
|    // Update placefile
 |    // Update placefile
 | ||||||
|    placefile_ = placefile; |    placefile_ = placefile; | ||||||
|  | @ -305,3 +395,5 @@ std::string PlacefileManager::Impl::NormalizeUrl(const std::string& urlString) | ||||||
| } // namespace manager
 | } // namespace manager
 | ||||||
| } // namespace qt
 | } // namespace qt
 | ||||||
| } // namespace scwx
 | } // namespace scwx
 | ||||||
|  | 
 | ||||||
|  | #include "placefile_manager.moc" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat