mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 13:30:06 +00:00
Enable placefile auto-refresh (no more frequent than every 15 seconds)
This commit is contained in:
parent
170e30ca6c
commit
80c307c5fc
3 changed files with 125 additions and 11 deletions
|
|
@ -22,6 +22,7 @@
|
|||
#include <boost/json.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <cpr/cpr.h>
|
||||
#include <fmt/chrono.h>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -85,10 +86,16 @@ public:
|
|||
}
|
||||
~PlacefileRecord()
|
||||
{
|
||||
std::unique_lock lock(refreshMutex_);
|
||||
std::unique_lock refreshLock(refreshMutex_);
|
||||
std::unique_lock timerLock(timerMutex_);
|
||||
refreshTimer_.cancel();
|
||||
}
|
||||
|
||||
bool refresh_enabled() const;
|
||||
std::chrono::seconds refresh_time() const;
|
||||
|
||||
void CancelRefresh();
|
||||
void ScheduleRefresh();
|
||||
void Update();
|
||||
void UpdateAsync();
|
||||
void UpdatePlacefile(const std::shared_ptr<gr::Placefile>& placefile);
|
||||
|
|
@ -125,6 +132,10 @@ public:
|
|||
boost::asio::thread_pool threadPool_ {1u};
|
||||
boost::asio::steady_timer refreshTimer_ {threadPool_};
|
||||
std::mutex refreshMutex_ {};
|
||||
std::mutex timerMutex_ {};
|
||||
|
||||
std::string lastRadarSite_ {};
|
||||
std::chrono::system_clock::time_point lastUpdateTime_ {};
|
||||
};
|
||||
|
||||
PlacefileManager::PlacefileManager() : p(std::make_unique<Impl>(this))
|
||||
|
|
@ -210,11 +221,26 @@ void PlacefileManager::set_placefile_enabled(const std::string& name,
|
|||
|
||||
Q_EMIT PlacefileEnabled(name, enabled);
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
// Update the placefile
|
||||
// TODO: Only update if it's out of date, or if the radar site has changed
|
||||
if (enabled)
|
||||
{
|
||||
it->second->UpdateAsync();
|
||||
if (p->radarSite_ != nullptr &&
|
||||
record->lastRadarSite_ != p->radarSite_->id())
|
||||
{
|
||||
// If the radar site has changed, update now
|
||||
record->UpdateAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, schedule an update
|
||||
record->ScheduleRefresh();
|
||||
}
|
||||
}
|
||||
else if (!enabled)
|
||||
{
|
||||
record->CancelRefresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -262,6 +288,31 @@ void PlacefileManager::set_placefile_url(const std::string& name,
|
|||
}
|
||||
}
|
||||
|
||||
bool PlacefileManager::Impl::PlacefileRecord::refresh_enabled() const
|
||||
{
|
||||
if (placefile_ != nullptr)
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
return placefile_->refresh() > 0s;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::chrono::seconds
|
||||
PlacefileManager::Impl::PlacefileRecord::refresh_time() const
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
if (refresh_enabled())
|
||||
{
|
||||
// Don't refresh more often than every 15 seconds
|
||||
return std::max(placefile_->refresh(), 15s);
|
||||
}
|
||||
|
||||
return -1s;
|
||||
}
|
||||
|
||||
void PlacefileManager::Impl::InitializePlacefileSettings()
|
||||
{
|
||||
std::string appDataPath {
|
||||
|
|
@ -407,8 +458,11 @@ void PlacefileManager::AddUrl(const std::string& urlString,
|
|||
|
||||
Q_EMIT PlacefileUpdated(normalizedUrl);
|
||||
|
||||
// Queue a placefile update
|
||||
// Queue a placefile update, either if enabled, or if we don't know the title
|
||||
if (enabled || title.empty())
|
||||
{
|
||||
record->UpdateAsync();
|
||||
}
|
||||
}
|
||||
|
||||
void PlacefileManager::LoadFile(const std::string& filename)
|
||||
|
|
@ -491,6 +545,9 @@ void PlacefileManager::Impl::PlacefileRecord::Update()
|
|||
{
|
||||
logger_->debug("Update: {}", name_);
|
||||
|
||||
// Take unique lock before refreshing
|
||||
std::unique_lock lock {refreshMutex_};
|
||||
|
||||
// Make a copy of name in the event it changes.
|
||||
const std::string name {name_};
|
||||
|
||||
|
|
@ -581,15 +638,64 @@ void PlacefileManager::Impl::PlacefileRecord::Update()
|
|||
// Update the placefile
|
||||
placefile_ = updatedPlacefile;
|
||||
title_ = placefile_->title();
|
||||
lastUpdateTime_ = std::chrono::system_clock::now();
|
||||
|
||||
if (p->radarSite_ != nullptr)
|
||||
{
|
||||
lastRadarSite_ = p->radarSite_->id();
|
||||
}
|
||||
|
||||
// Notify slots of the placefile update
|
||||
Q_EMIT p->self_->PlacefileUpdated(name);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Update refresh timer
|
||||
// TODO: Can running this function out of sync with an existing refresh timer
|
||||
// cause issues?
|
||||
// Update refresh timer
|
||||
ScheduleRefresh();
|
||||
}
|
||||
|
||||
void PlacefileManager::Impl::PlacefileRecord::ScheduleRefresh()
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
if (!enabled_ || !refresh_enabled())
|
||||
{
|
||||
// Refresh is disabled
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_lock lock {timerMutex_};
|
||||
|
||||
auto nextUpdateTime = lastUpdateTime_ + refresh_time();
|
||||
auto timeUntilNextUpdate = nextUpdateTime - std::chrono::system_clock::now();
|
||||
|
||||
logger_->debug(
|
||||
"Scheduled refresh in {:%M:%S} ({})",
|
||||
std::chrono::duration_cast<std::chrono::seconds>(timeUntilNextUpdate),
|
||||
name_);
|
||||
|
||||
refreshTimer_.expires_after(timeUntilNextUpdate);
|
||||
refreshTimer_.async_wait(
|
||||
[this](const boost::system::error_code& e)
|
||||
{
|
||||
if (e == boost::asio::error::operation_aborted)
|
||||
{
|
||||
logger_->debug("Refresh timer cancelled");
|
||||
}
|
||||
else if (e != boost::system::errc::success)
|
||||
{
|
||||
logger_->warn("Refresh timer error: {}", e.message());
|
||||
}
|
||||
else
|
||||
{
|
||||
Update();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void PlacefileManager::Impl::PlacefileRecord::CancelRefresh()
|
||||
{
|
||||
refreshTimer_.cancel();
|
||||
}
|
||||
|
||||
void PlacefileManager::Impl::PlacefileRecord::UpdateAsync()
|
||||
|
|
@ -603,7 +709,8 @@ void PlacefileManager::Impl::PlacefileRecord::UpdatePlacefile(
|
|||
// Update placefile
|
||||
placefile_ = placefile;
|
||||
|
||||
// TODO: Update refresh timer
|
||||
// Update refresh timer
|
||||
ScheduleRefresh();
|
||||
}
|
||||
|
||||
std::shared_ptr<PlacefileManager> PlacefileManager::Instance()
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <scwx/common/geographic.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
|
@ -174,6 +175,7 @@ public:
|
|||
|
||||
std::string name() const;
|
||||
std::string title() const;
|
||||
std::chrono::seconds refresh() const;
|
||||
std::unordered_map<std::size_t, std::shared_ptr<Font>> fonts();
|
||||
std::shared_ptr<Font> font(std::size_t i);
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,11 @@ std::string Placefile::title() const
|
|||
return p->title_;
|
||||
}
|
||||
|
||||
std::chrono::seconds Placefile::refresh() const
|
||||
{
|
||||
return p->refresh_;
|
||||
}
|
||||
|
||||
std::unordered_map<std::size_t, std::shared_ptr<Placefile::Font>>
|
||||
Placefile::fonts()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue