Ref T786, weather manager

* adjusted to new requestWeatherGrid
* use fetchNextWeatherDataDeferred to make sure follow up calls are decoupled
* for callbacks use weatherRequest.callback.singleShot so it is called in correct thread
This commit is contained in:
Klaus Basan
2020-04-19 02:25:25 +02:00
committed by Mat Sutcliffe
parent cc77183b05
commit 7304013eea
2 changed files with 53 additions and 23 deletions

View File

@@ -8,6 +8,7 @@
#include "blackcore/weatherdata.h" #include "blackcore/weatherdata.h"
#include "blackcore/weathermanager.h" #include "blackcore/weathermanager.h"
#include "blackcore/application.h"
#include "blackmisc/weather/gridpoint.h" #include "blackmisc/weather/gridpoint.h"
#include "blackmisc/weather/weatherdataplugininfo.h" #include "blackmisc/weather/weatherdataplugininfo.h"
@@ -40,16 +41,22 @@ namespace BlackCore
// todo: send weather grid to drivers from here // todo: send weather grid to drivers from here
} }
void CWeatherManager::requestWeatherGrid(const CWeatherGrid &weatherGrid, const CIdentifier &identifier) void CWeatherManager::requestWeatherGrid(const ICoordinateGeodetic &position, const CIdentifier &identifier)
{ {
WeatherRequest request { {}, identifier, weatherGrid, {} }; const CWeatherGrid weatherGrid = CWeatherGrid { { "GLOB", position } };
this->requestWeatherGrid(weatherGrid, identifier);
}
void CWeatherManager::requestWeatherGrid(const CWeatherGrid &initialWeatherGrid, const CIdentifier &identifier)
{
const WeatherRequest request { {}, identifier, initialWeatherGrid, {} };
m_pendingRequests.append(request); m_pendingRequests.append(request);
// Serialize the requests, since plugins can handle only one at a time // Serialize the requests, since plugins can handle only one at a time
if (m_pendingRequests.size() == 1) { fetchNextWeatherData(); } if (m_pendingRequests.size() == 1) { fetchNextWeatherDataDeferred(); }
} }
void CWeatherManager::requestWeatherGrid(const CWeatherGrid &weatherGrid, void CWeatherManager::requestWeatherGrid(const CWeatherGrid &initialWeatherGrid,
const CSlot<void(const CWeatherGrid &)> &callback) const CSlot<void(const CWeatherGrid &)> &callback)
{ {
BLACK_VERIFY_X(callback, Q_FUNC_INFO, "Missing callback"); BLACK_VERIFY_X(callback, Q_FUNC_INFO, "Missing callback");
@@ -61,14 +68,14 @@ namespace BlackCore
return; return;
} }
const WeatherRequest weatherRequest { {}, CIdentifier::null(), weatherGrid, callback }; const WeatherRequest weatherRequest { {}, CIdentifier::null(), initialWeatherGrid, callback };
m_pendingRequests.append(weatherRequest); m_pendingRequests.append(weatherRequest);
// Serialize the requests, since plugins can handle only one at a time // Serialize the requests, since plugins can handle only one at a time
if (m_pendingRequests.size() == 1) { fetchNextWeatherData(); } if (m_pendingRequests.size() == 1) { fetchNextWeatherDataDeferred(); }
} }
void CWeatherManager::requestWeatherGridFromFile(const QString &filePath, const CWeatherGrid &weatherGrid, void CWeatherManager::requestWeatherGridFromFile(const QString &filePath, const CWeatherGrid &initialWeatherGrid,
const CSlot<void(const CWeatherGrid &)> &callback) const CSlot<void(const CWeatherGrid &)> &callback)
{ {
if (m_isWeatherClear && callback) if (m_isWeatherClear && callback)
@@ -77,11 +84,11 @@ namespace BlackCore
return; return;
} }
WeatherRequest weatherRequest { filePath, CIdentifier::null(), weatherGrid, callback }; WeatherRequest weatherRequest { filePath, CIdentifier::null(), initialWeatherGrid, callback };
m_pendingRequests.append(weatherRequest); m_pendingRequests.append(weatherRequest);
// Serialize the requests, since plugins can handle only one at a time // Serialize the requests, since plugins can handle only one at a time
if (m_pendingRequests.size() == 1) { fetchNextWeatherData(); } if (m_pendingRequests.size() == 1) { fetchNextWeatherDataDeferred(); }
} }
bool CWeatherManager::loadWeatherDataPlugins() bool CWeatherManager::loadWeatherDataPlugins()
@@ -123,11 +130,28 @@ namespace BlackCore
for (IWeatherData *plugin : as_const(m_weatherDataPlugins)) for (IWeatherData *plugin : as_const(m_weatherDataPlugins))
{ {
if (weatherRequest.filePath.isEmpty()) { plugin->fetchWeatherData(weatherRequest.weatherGrid, maxDistance); } if (!plugin) { continue; }
else { plugin->fetchWeatherDataFromFile(weatherRequest.filePath, weatherRequest.weatherGrid, maxDistance); } if (weatherRequest.filePath.isEmpty())
{
plugin->fetchWeatherData(weatherRequest.weatherGrid, maxDistance);
}
else
{
plugin->fetchWeatherDataFromFile(weatherRequest.filePath, weatherRequest.weatherGrid, maxDistance);
}
} }
} }
void CWeatherManager::fetchNextWeatherDataDeferred()
{
QPointer<CWeatherManager> myself(this);
QTimer::singleShot(0, this, [ = ]
{
if (!myself || !sApp || sApp->isShuttingDown()) { return; }
myself->fetchNextWeatherData();
});
}
void CWeatherManager::handleNextRequest() void CWeatherManager::handleNextRequest()
{ {
Q_ASSERT(!m_pendingRequests.isEmpty()); Q_ASSERT(!m_pendingRequests.isEmpty());
@@ -136,7 +160,7 @@ namespace BlackCore
Q_ASSERT(weatherDataPlugin); Q_ASSERT(weatherDataPlugin);
const auto fetchedWeatherGrid = weatherDataPlugin->getWeatherData(); const auto fetchedWeatherGrid = weatherDataPlugin->getWeatherData();
const WeatherRequest weatherRequest = m_pendingRequests.constFirst(); const WeatherRequest weatherRequest = m_pendingRequests.front();
CWeatherGrid requestedWeatherGrid = weatherRequest.weatherGrid; CWeatherGrid requestedWeatherGrid = weatherRequest.weatherGrid;
// Interpolation. So far it just picks the closest point without interpolation. // Interpolation. So far it just picks the closest point without interpolation.
@@ -147,7 +171,11 @@ namespace BlackCore
gridPoint.setPosition(nearestGridPoint.getPosition()); gridPoint.setPosition(nearestGridPoint.getPosition());
} }
if (weatherRequest.callback) { weatherRequest.callback.singleShot(requestedWeatherGrid); } if (weatherRequest.callback)
{
weatherRequest.callback.singleShot(requestedWeatherGrid);
}
if (!weatherRequest.identifier.isAnonymous()) { emit weatherGridReceived(requestedWeatherGrid, weatherRequest.identifier); } if (!weatherRequest.identifier.isAnonymous()) { emit weatherGridReceived(requestedWeatherGrid, weatherRequest.identifier); }
m_pendingRequests.pop_front(); m_pendingRequests.pop_front();

View File

@@ -11,12 +11,13 @@
#ifndef BLACKCORE_WEATHERMANAGER_H #ifndef BLACKCORE_WEATHERMANAGER_H
#define BLACKCORE_WEATHERMANAGER_H #define BLACKCORE_WEATHERMANAGER_H
#include "blackcore/blackcoreexport.h"
#include "blackcore/pluginmanagerweatherdata.h" #include "blackcore/pluginmanagerweatherdata.h"
#include "blackmisc/identifier.h" #include "blackcore/blackcoreexport.h"
#include "blackmisc/slot.h"
#include "blackmisc/weather/weathergrid.h" #include "blackmisc/weather/weathergrid.h"
#include "blackmisc/weather/weathergridprovider.h" #include "blackmisc/weather/weathergridprovider.h"
#include "blackmisc/geo/coordinategeodetic.h"
#include "blackmisc/identifier.h"
#include "blackmisc/slot.h"
#include <QObject> #include <QObject>
#include <QVector> #include <QVector>
@@ -29,8 +30,8 @@ namespace BlackCore
* CWeatherManager * CWeatherManager
*/ */
class BLACKCORE_EXPORT CWeatherManager : class BLACKCORE_EXPORT CWeatherManager :
public QObject, public QObject,
public BlackMisc::Weather::IWeatherGridProvider public BlackMisc::Weather::IWeatherGridProvider
{ {
Q_OBJECT Q_OBJECT
Q_INTERFACES(BlackMisc::Weather::IWeatherGridProvider) Q_INTERFACES(BlackMisc::Weather::IWeatherGridProvider)
@@ -45,19 +46,18 @@ namespace BlackCore
//! Is weather overwritten to clear? //! Is weather overwritten to clear?
bool isWeatherClear() const { return m_isWeatherClear; } bool isWeatherClear() const { return m_isWeatherClear; }
//! Request weather grid //! \copydoc BlackMisc::Weather::IWeatherGridProvider::requestWeatherGrid
void requestWeatherGrid(const BlackMisc::Weather::CWeatherGrid &weatherGrid, const BlackMisc::CIdentifier &identifier); virtual void requestWeatherGrid(const BlackMisc::Geo::ICoordinateGeodetic &position, const BlackMisc::CIdentifier &identifier) override;
//! \copydoc BlackMisc::Weather::IWeatherGridProvider::requestWeatherGrid //! \copydoc BlackMisc::Weather::IWeatherGridProvider::requestWeatherGrid
virtual void requestWeatherGrid(const BlackMisc::Weather::CWeatherGrid &weatherGrid, virtual void requestWeatherGrid(const BlackMisc::Weather::CWeatherGrid &initialWeatherGrid,
const BlackMisc::CSlot<void(const BlackMisc::Weather::CWeatherGrid &)> &callback) override; const BlackMisc::CSlot<void(const BlackMisc::Weather::CWeatherGrid &)> &callback) override;
//! \copydoc BlackMisc::Weather::IWeatherGridProvider::requestWeatherGrid //! \copydoc BlackMisc::Weather::IWeatherGridProvider::requestWeatherGrid
virtual void requestWeatherGridFromFile(const QString &filePath, virtual void requestWeatherGridFromFile(const QString &filePath,
const BlackMisc::Weather::CWeatherGrid &weatherGrid, const BlackMisc::Weather::CWeatherGrid &initialWeatherGrid,
const BlackMisc::CSlot<void(const BlackMisc::Weather::CWeatherGrid &)> &callback) override; const BlackMisc::CSlot<void(const BlackMisc::Weather::CWeatherGrid &)> &callback) override;
signals: signals:
//! The weather grid, requested from identified, is available //! The weather grid, requested from identified, is available
void weatherGridReceived(const BlackMisc::Weather::CWeatherGrid &weatherGrid, const BlackMisc::CIdentifier &identifier); void weatherGridReceived(const BlackMisc::Weather::CWeatherGrid &weatherGrid, const BlackMisc::CIdentifier &identifier);
@@ -72,8 +72,10 @@ namespace BlackCore
BlackMisc::CSlot<void(const BlackMisc::Weather::CWeatherGrid &)> callback; BlackMisc::CSlot<void(const BlackMisc::Weather::CWeatherGrid &)> callback;
}; };
void requestWeatherGrid(const BlackMisc::Weather::CWeatherGrid &initialWeatherGrid, const BlackMisc::CIdentifier &identifier);
bool loadWeatherDataPlugins(); bool loadWeatherDataPlugins();
void fetchNextWeatherData(); void fetchNextWeatherData();
void fetchNextWeatherDataDeferred();
void handleNextRequest(); void handleNextRequest();
CPluginManagerWeatherData m_pluginManagerWeatherData { this }; CPluginManagerWeatherData m_pluginManagerWeatherData { this };