mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-28 03:35:38 +08:00
refactor: Clean up setup file reader
Previously we already switch to loading the bootstrap file only from the
local file (ec42553910).
This removes the remaining parts of loading the bootstrap file from a
remote location.
This also updates the UI in case of parsing errors of the bootstrap.json.
This commit is contained in:
@@ -67,6 +67,5 @@
|
|||||||
},
|
},
|
||||||
"ssrEquipmentHelpUrl": {
|
"ssrEquipmentHelpUrl": {
|
||||||
"url": "https://en.wikipedia.org/wiki/Equipment_codes#Surveillance_equipment_codes"
|
"url": "https://en.wikipedia.org/wiki/Equipment_codes#Surveillance_equipment_codes"
|
||||||
},
|
}
|
||||||
"wasLoadedFromFile": false
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,10 +149,6 @@ namespace BlackCore
|
|||||||
|
|
||||||
// global setup
|
// global setup
|
||||||
m_setupReader.reset(new CSetupReader(this));
|
m_setupReader.reset(new CSetupReader(this));
|
||||||
connect(m_setupReader.data(), &CSetupReader::setupHandlingCompleted, this, &CApplication::onSetupHandlingCompleted, Qt::QueuedConnection);
|
|
||||||
connect(m_setupReader.data(), &CSetupReader::setupHandlingCompleted, this, &CApplication::setupHandlingCompleted, Qt::QueuedConnection); // hand thru
|
|
||||||
|
|
||||||
this->addParserOptions(m_setupReader->getCmdLineOptions()); // add options from reader
|
|
||||||
|
|
||||||
// check for updates
|
// check for updates
|
||||||
m_gitHubPackagesReader.reset(new CGitHubPackagesReader(this));
|
m_gitHubPackagesReader.reset(new CGitHubPackagesReader(this));
|
||||||
@@ -380,13 +376,7 @@ namespace BlackCore
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \fixme KB 9/17 waiting for setup reader here is supposed to be replaced by explicitly waiting for reader
|
Q_ASSERT_X(m_setupReader && m_setupReader->isSetupAvailable(), Q_FUNC_INFO, "Setup not available");
|
||||||
if (!m_setupReader->isSetupAvailable())
|
|
||||||
{
|
|
||||||
msgs = this->requestReloadOfSetupAndVersion();
|
|
||||||
if (msgs.isFailure()) { break; }
|
|
||||||
if (msgs.isSuccess()) { msgs.push_back(this->waitForSetup()); }
|
|
||||||
}
|
|
||||||
|
|
||||||
// start hookin
|
// start hookin
|
||||||
msgs.push_back(this->startHookIn());
|
msgs.push_back(this->startHookIn());
|
||||||
@@ -413,62 +403,12 @@ namespace BlackCore
|
|||||||
return m_started;
|
return m_started;
|
||||||
}
|
}
|
||||||
|
|
||||||
CStatusMessageList CApplication::waitForSetup(int timeoutMs)
|
|
||||||
{
|
|
||||||
if (!m_setupReader) { return CStatusMessage(this).error(u"No setup reader"); }
|
|
||||||
CEventLoop eventLoop(this);
|
|
||||||
eventLoop.stopWhen(this, &CApplication::setupHandlingCompleted);
|
|
||||||
if (!m_setupReader->isSetupAvailable())
|
|
||||||
{
|
|
||||||
eventLoop.exec(timeoutMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup handling completed with success or failure, or we run into time out
|
|
||||||
CStatusMessageList msgs;
|
|
||||||
if (!eventLoop.isGuardAlive())
|
|
||||||
{
|
|
||||||
msgs.push_back(CStatusMessage(this).error(u"Setup not available, already shutting down."));
|
|
||||||
return msgs;
|
|
||||||
}
|
|
||||||
bool forced = false;
|
|
||||||
if (!m_setupReader->isSetupAvailable())
|
|
||||||
{
|
|
||||||
forced = true;
|
|
||||||
m_setupReader->forceAvailabilityUpdate(); // maybe web reading still hanging
|
|
||||||
}
|
|
||||||
if (m_setupReader->isSetupAvailable())
|
|
||||||
{
|
|
||||||
msgs.push_back(CStatusMessage(this).info(forced ? QStringLiteral("Setup available after forcing (so likely web read still pending)") : QStringLiteral("Setup available")));
|
|
||||||
return msgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// getting here means no "real" read success, and NO available cache
|
|
||||||
msgs.push_back(CStatusMessage(this).error(u"Setup not available, setup reading failed or timed out."));
|
|
||||||
if (m_setupReader->getLastSetupReadErrorMessages().hasErrorMessages())
|
|
||||||
{
|
|
||||||
msgs.push_back(m_setupReader->getLastSetupReadErrorMessages());
|
|
||||||
}
|
|
||||||
if (m_setupReader->hasCmdLineBootstrapUrl())
|
|
||||||
{
|
|
||||||
msgs.push_back(CStatusMessage(this).info(u"Bootstrap URL cmd line argument '%1'") << m_setupReader->getCmdLineBootstrapUrl());
|
|
||||||
}
|
|
||||||
return msgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CApplication::isSetupAvailable() const
|
bool CApplication::isSetupAvailable() const
|
||||||
{
|
{
|
||||||
if (m_shutdown || !m_setupReader) { return false; }
|
if (m_shutdown || !m_setupReader) { return false; }
|
||||||
return m_setupReader->isSetupAvailable();
|
return m_setupReader->isSetupAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
CStatusMessageList CApplication::requestReloadOfSetupAndVersion()
|
|
||||||
{
|
|
||||||
if (m_shutdown) { return CStatusMessage(this).warning(u"Shutting down, not reading"); }
|
|
||||||
if (!m_setupReader) { return CStatusMessage(this).error(u"No reader for setup/version"); }
|
|
||||||
Q_ASSERT_X(m_parsed, Q_FUNC_INFO, "Not yet parsed");
|
|
||||||
return m_setupReader->asyncLoad();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CApplication::hasMinimumMappingVersion() const
|
bool CApplication::hasMinimumMappingVersion() const
|
||||||
{
|
{
|
||||||
return (this->getGlobalSetup().isSwiftVersionMinimumMappingVersion());
|
return (this->getGlobalSetup().isSwiftVersionMinimumMappingVersion());
|
||||||
@@ -1103,7 +1043,6 @@ namespace BlackCore
|
|||||||
|
|
||||||
if (m_setupReader)
|
if (m_setupReader)
|
||||||
{
|
{
|
||||||
m_setupReader->gracefulShutdown();
|
|
||||||
m_setupReader.reset();
|
m_setupReader.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1448,15 +1387,26 @@ namespace BlackCore
|
|||||||
if (!this->parsingHookIn()) { return false; }
|
if (!this->parsingHookIn()) { return false; }
|
||||||
|
|
||||||
// setup reader
|
// setup reader
|
||||||
m_setupReader->parseCmdLineArguments();
|
|
||||||
m_parsed = true;
|
m_parsed = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CApplication::parseAndSynchronizeSetup(int timeoutMs)
|
bool CApplication::parseAndLoadSetup()
|
||||||
{
|
{
|
||||||
if (!this->parseAndStartupCheck()) return false;
|
if (!this->parseAndStartupCheck()) return false;
|
||||||
return !this->synchronizeSetup(timeoutMs).hasErrorMessages();
|
const CStatusMessageList msgs = loadSetup();
|
||||||
|
|
||||||
|
if (msgs.isFailure())
|
||||||
|
{
|
||||||
|
displaySetupLoadFailure(msgs);
|
||||||
|
}
|
||||||
|
return msgs.isSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CApplication::displaySetupLoadFailure(BlackMisc::CStatusMessageList)
|
||||||
|
{
|
||||||
|
// Ignore for CLI application
|
||||||
|
// Already logged to console
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CApplication::cmdLineWarningMessage(const QString &text, const QString &informativeText) const
|
bool CApplication::cmdLineWarningMessage(const QString &text, const QString &informativeText) const
|
||||||
@@ -1656,17 +1606,14 @@ namespace BlackCore
|
|||||||
return m_setupReader.data();
|
return m_setupReader.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CApplication::getLastSuccesfulSetupUrl() const
|
CStatusMessageList CApplication::loadSetup()
|
||||||
{
|
{
|
||||||
if (!this->hasSetupReader()) { return {}; }
|
if (m_shutdown) { return CStatusMessage(this).warning(u"Shutting down, not reading"); }
|
||||||
return m_setupReader->getLastSuccessfulSetupUrl();
|
if (!m_setupReader) { return CStatusMessage(this).error(u"No reader for setup/version"); }
|
||||||
}
|
Q_ASSERT_X(m_parsed, Q_FUNC_INFO, "Not yet parsed");
|
||||||
|
const CStatusMessageList requestMsgs = m_setupReader->loadSetup();
|
||||||
CStatusMessageList CApplication::synchronizeSetup(int timeoutMs)
|
onSetupHandlingCompleted(requestMsgs.isSuccess());
|
||||||
{
|
return requestMsgs;
|
||||||
const CStatusMessageList requestMsgs = this->requestReloadOfSetupAndVersion();
|
|
||||||
if (requestMsgs.isFailure()) { return requestMsgs; } // request already failed
|
|
||||||
return this->waitForSetup(timeoutMs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CUrlList CApplication::getVatsimMetarUrls() const
|
CUrlList CApplication::getVatsimMetarUrls() const
|
||||||
|
|||||||
@@ -298,8 +298,8 @@ namespace BlackCore
|
|||||||
|
|
||||||
//! Combined function
|
//! Combined function
|
||||||
//! \see parseAndStartupCheck
|
//! \see parseAndStartupCheck
|
||||||
//! \see synchronizeSetup
|
//! \see loadSetup
|
||||||
virtual bool parseAndSynchronizeSetup(int timeoutMs = BlackMisc::Network::CNetworkUtils::getLongTimeoutMs());
|
bool parseAndLoadSetup();
|
||||||
|
|
||||||
//! Display warning message
|
//! Display warning message
|
||||||
virtual bool cmdLineWarningMessage(const QString &text, const QString &informativeText = "") const;
|
virtual bool cmdLineWarningMessage(const QString &text, const QString &informativeText = "") const;
|
||||||
@@ -406,20 +406,9 @@ namespace BlackCore
|
|||||||
|
|
||||||
// ----------------------- setup data ---------------------------------
|
// ----------------------- setup data ---------------------------------
|
||||||
|
|
||||||
//! Last setup URL (successfully read)
|
|
||||||
//! \threadsafe
|
|
||||||
QString getLastSuccesfulSetupUrl() const;
|
|
||||||
|
|
||||||
//! Reload setup and version
|
|
||||||
BlackMisc::CStatusMessageList requestReloadOfSetupAndVersion();
|
|
||||||
|
|
||||||
//! Minimum mapping version check
|
//! Minimum mapping version check
|
||||||
virtual bool hasMinimumMappingVersion() const;
|
virtual bool hasMinimumMappingVersion() const;
|
||||||
|
|
||||||
//! Read and wait for setup
|
|
||||||
//! \sa waitForSetup
|
|
||||||
BlackMisc::CStatusMessageList synchronizeSetup(int timeoutMs = BlackMisc::Network::CNetworkUtils::getLongTimeoutMs());
|
|
||||||
|
|
||||||
//! Setup reader?
|
//! Setup reader?
|
||||||
bool hasSetupReader() const;
|
bool hasSetupReader() const;
|
||||||
|
|
||||||
@@ -570,9 +559,6 @@ namespace BlackCore
|
|||||||
//! @}
|
//! @}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
//! Setup available (cache, web load, ..) or failed to load setup
|
|
||||||
void setupHandlingCompleted(bool success);
|
|
||||||
|
|
||||||
//! Update info available (cache, web load)
|
//! Update info available (cache, web load)
|
||||||
void updateInfoAvailable(bool success);
|
void updateInfoAvailable(bool success);
|
||||||
|
|
||||||
@@ -597,13 +583,12 @@ namespace BlackCore
|
|||||||
void aboutToShutdown();
|
void aboutToShutdown();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
//! Display the failures caused by loading the setup file
|
||||||
|
virtual void displaySetupLoadFailure(BlackMisc::CStatusMessageList msgs);
|
||||||
|
|
||||||
//! Setup read/synchronized
|
//! Setup read/synchronized
|
||||||
void onSetupHandlingCompleted(bool available);
|
void onSetupHandlingCompleted(bool available);
|
||||||
|
|
||||||
//! Wait for setup data by calling the event loop and waiting until everything is ready
|
|
||||||
//! \remark requires parsing upfront
|
|
||||||
BlackMisc::CStatusMessageList waitForSetup(int timeoutMs = BlackMisc::Network::CNetworkUtils::getLongTimeoutMs());
|
|
||||||
|
|
||||||
//! Startup completed
|
//! Startup completed
|
||||||
virtual void onStartUpCompleted();
|
virtual void onStartUpCompleted();
|
||||||
|
|
||||||
@@ -672,6 +657,9 @@ namespace BlackCore
|
|||||||
std::atomic_bool m_shutdownInProgress { false }; //!< shutdown in progress?
|
std::atomic_bool m_shutdownInProgress { false }; //!< shutdown in progress?
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
//! Read the setup
|
||||||
|
BlackMisc::CStatusMessageList loadSetup();
|
||||||
|
|
||||||
//! Problem with network access manager
|
//! Problem with network access manager
|
||||||
void onChangedNetworkAccessibility(QNetworkAccessManager::NetworkAccessibility accessible);
|
void onChangedNetworkAccessibility(QNetworkAccessManager::NetworkAccessibility accessible);
|
||||||
|
|
||||||
|
|||||||
@@ -33,11 +33,6 @@ namespace BlackCore::Data
|
|||||||
this->initDefaultValues();
|
this->initDefaultValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGlobalSetup::wasLoaded() const
|
|
||||||
{
|
|
||||||
return this->wasLoadedFromFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGlobalSetup::initDefaultValues()
|
void CGlobalSetup::initDefaultValues()
|
||||||
{
|
{
|
||||||
m_mappingMinimumVersion = CBuildConfig::getVersionString();
|
m_mappingMinimumVersion = CBuildConfig::getVersionString();
|
||||||
@@ -87,17 +82,6 @@ namespace BlackCore::Data
|
|||||||
return m_sharedUrls;
|
return m_sharedUrls;
|
||||||
}
|
}
|
||||||
|
|
||||||
CUrl CGlobalSetup::getCorrespondingSharedUrl(const CUrl &candidate) const
|
|
||||||
{
|
|
||||||
CUrlList sameHosts = this->getSwiftSharedUrls().findByHost(candidate.getHost());
|
|
||||||
return sameHosts.frontOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
CUrlList CGlobalSetup::getSwiftBootstrapFileUrls() const
|
|
||||||
{
|
|
||||||
return getSwiftSharedUrls().withAppendedPath(CGlobalSetup::schemaVersionString() + "/bootstrap/" + CSwiftDirectories::bootstrapFileName());
|
|
||||||
}
|
|
||||||
|
|
||||||
CUrlList CGlobalSetup::getSwiftUpdateInfoFileUrls() const
|
CUrlList CGlobalSetup::getSwiftUpdateInfoFileUrls() const
|
||||||
{
|
{
|
||||||
return getSwiftSharedUrls().withAppendedPath(CGlobalSetup::schemaVersionString() + "/updateinfo/updateinfo.json");
|
return getSwiftSharedUrls().withAppendedPath(CGlobalSetup::schemaVersionString() + "/updateinfo/updateinfo.json");
|
||||||
@@ -179,31 +163,6 @@ namespace BlackCore::Data
|
|||||||
m_dbDebugFlag = debug;
|
m_dbDebugFlag = debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CGlobalSetup::buildBootstrapFileUrl(const QString &candidate)
|
|
||||||
{
|
|
||||||
if (candidate.isEmpty()) return {}; // not possible
|
|
||||||
static const QString version(QString(CGlobalSetup::schemaVersionString()).append("/"));
|
|
||||||
if (candidate.endsWith(CSwiftDirectories::bootstrapFileName())) { return candidate; }
|
|
||||||
CUrl url(candidate);
|
|
||||||
if (candidate.contains("/bootstrap"))
|
|
||||||
{
|
|
||||||
url.appendPath(CSwiftDirectories::bootstrapFileName());
|
|
||||||
}
|
|
||||||
else if (candidate.endsWith(CGlobalSetup::schemaVersionString()) || candidate.endsWith(version))
|
|
||||||
{
|
|
||||||
url.appendPath("/bootstrap/" + CSwiftDirectories::bootstrapFileName());
|
|
||||||
}
|
|
||||||
else if (candidate.endsWith("shared") || candidate.endsWith("shared/"))
|
|
||||||
{
|
|
||||||
url.appendPath(CGlobalSetup::schemaVersionString() + "/bootstrap/" + CSwiftDirectories::bootstrapFileName());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
url.appendPath("shared/" + CGlobalSetup::schemaVersionString() + "/bootstrap/" + CSwiftDirectories::bootstrapFileName());
|
|
||||||
}
|
|
||||||
return url.getFullUrl();
|
|
||||||
}
|
|
||||||
|
|
||||||
CUrl CGlobalSetup::buildDbDataDirectoryUrl(const CUrl &candidate)
|
CUrl CGlobalSetup::buildDbDataDirectoryUrl(const CUrl &candidate)
|
||||||
{
|
{
|
||||||
if (candidate.isEmpty()) return CUrl(); // not possible
|
if (candidate.isEmpty()) return CUrl(); // not possible
|
||||||
@@ -257,11 +216,11 @@ namespace BlackCore::Data
|
|||||||
QString CGlobalSetup::convertToQString(const QString &separator, bool i18n) const
|
QString CGlobalSetup::convertToQString(const QString &separator, bool i18n) const
|
||||||
{
|
{
|
||||||
QString s =
|
QString s =
|
||||||
u"timestamp: " % this->getFormattedUtcTimestampYmdhms() % separator % u"Global setup loaded: " % boolToYesNo(this->wasLoadedFromFile()) % separator
|
u"timestamp: " % this->getFormattedUtcTimestampYmdhms() % separator % u"Global setup loaded: "
|
||||||
|
|
||||||
% u"Mapping min.version: " % this->getMappingMinimumVersionString() % separator
|
% u"Mapping min.version: " % this->getMappingMinimumVersionString() % separator
|
||||||
|
|
||||||
% u"Distribution URLs: " % getSwiftUpdateInfoFileUrls().toQString(i18n) % separator % u"Bootstrap URLs: " % getSwiftBootstrapFileUrls().toQString(i18n) % separator % u"Help URLs: " % m_onlineHelpUrls.toQString(i18n) % separator;
|
% u"Distribution URLs: " % getSwiftUpdateInfoFileUrls().toQString(i18n) % separator % u"Help URLs: " % m_onlineHelpUrls.toQString(i18n) % separator;
|
||||||
s +=
|
s +=
|
||||||
u"DB root directory: " % getDbRootDirectoryUrl().toQString(i18n) % separator % u"ICAO DB reader: " % getDbIcaoReaderUrl().toQString(i18n) % separator % u"Model DB reader: " % getDbModelReaderUrl().toQString(i18n) % separator % u"Airport DB reader: " % getDbAirportReaderUrl().toQString(i18n) % separator % u"DB home page: " % getDbHomePageUrl().toQString(i18n) % separator % u"DB login service: " % getDbLoginServiceUrl().toQString(i18n) % separator % u"DB client ping service: " % getDbClientPingServiceUrl().toQString(i18n);
|
u"DB root directory: " % getDbRootDirectoryUrl().toQString(i18n) % separator % u"ICAO DB reader: " % getDbIcaoReaderUrl().toQString(i18n) % separator % u"Model DB reader: " % getDbModelReaderUrl().toQString(i18n) % separator % u"Airport DB reader: " % getDbAirportReaderUrl().toQString(i18n) % separator % u"DB home page: " % getDbHomePageUrl().toQString(i18n) % separator % u"DB login service: " % getDbLoginServiceUrl().toQString(i18n) % separator % u"DB client ping service: " % getDbClientPingServiceUrl().toQString(i18n);
|
||||||
s +=
|
s +=
|
||||||
@@ -292,12 +251,10 @@ namespace BlackCore::Data
|
|||||||
case IndexVatsimServer: return QVariant::fromValue(m_vatsimServerFileUrl);
|
case IndexVatsimServer: return QVariant::fromValue(m_vatsimServerFileUrl);
|
||||||
case IndexVatsimHttpFsd: return QVariant::fromValue(m_vatsimFsdHttpUrl);
|
case IndexVatsimHttpFsd: return QVariant::fromValue(m_vatsimFsdHttpUrl);
|
||||||
case IndexVatsimMetars: return QVariant::fromValue(m_vatsimMetarsUrls);
|
case IndexVatsimMetars: return QVariant::fromValue(m_vatsimMetarsUrls);
|
||||||
case IndexBootstrapFileUrls: return QVariant::fromValue(this->getSwiftBootstrapFileUrls());
|
|
||||||
case IndexUpdateInfoFileUrls: return QVariant::fromValue(this->getSwiftUpdateInfoFileUrls());
|
case IndexUpdateInfoFileUrls: return QVariant::fromValue(this->getSwiftUpdateInfoFileUrls());
|
||||||
case IndexSharedUrls: return QVariant::fromValue(m_sharedUrls);
|
case IndexSharedUrls: return QVariant::fromValue(m_sharedUrls);
|
||||||
case IndexOnlineHelpUrls: return QVariant::fromValue(m_onlineHelpUrls);
|
case IndexOnlineHelpUrls: return QVariant::fromValue(m_onlineHelpUrls);
|
||||||
case IndexCrashReportServerUrl: return QVariant::fromValue(m_crashReportServerUrl);
|
case IndexCrashReportServerUrl: return QVariant::fromValue(m_crashReportServerUrl);
|
||||||
case IndexWasLoadedFromFile: return QVariant::fromValue(m_wasLoadedFromFile);
|
|
||||||
case IndexMappingMinimumVersion: return QVariant::fromValue(m_mappingMinimumVersion);
|
case IndexMappingMinimumVersion: return QVariant::fromValue(m_mappingMinimumVersion);
|
||||||
case IndexPredefinedServers: return QVariant::fromValue(m_predefinedServers);
|
case IndexPredefinedServers: return QVariant::fromValue(m_predefinedServers);
|
||||||
default: return CValueObject::propertyByIndex(index);
|
default: return CValueObject::propertyByIndex(index);
|
||||||
@@ -332,7 +289,6 @@ namespace BlackCore::Data
|
|||||||
case IndexSharedUrls: m_sharedUrls = variant.value<CUrlList>(); break;
|
case IndexSharedUrls: m_sharedUrls = variant.value<CUrlList>(); break;
|
||||||
case IndexOnlineHelpUrls: m_onlineHelpUrls = variant.value<CUrlList>(); break;
|
case IndexOnlineHelpUrls: m_onlineHelpUrls = variant.value<CUrlList>(); break;
|
||||||
case IndexCrashReportServerUrl: m_crashReportServerUrl = variant.value<CUrl>(); break;
|
case IndexCrashReportServerUrl: m_crashReportServerUrl = variant.value<CUrl>(); break;
|
||||||
case IndexWasLoadedFromFile: m_wasLoadedFromFile = variant.toBool(); break;
|
|
||||||
case IndexMappingMinimumVersion: m_mappingMinimumVersion = variant.toString(); break;
|
case IndexMappingMinimumVersion: m_mappingMinimumVersion = variant.toString(); break;
|
||||||
case IndexPredefinedServers: m_predefinedServers = variant.value<CServerList>(); break;
|
case IndexPredefinedServers: m_predefinedServers = variant.value<CServerList>(); break;
|
||||||
default: CValueObject::setPropertyByIndex(index, variant); break;
|
default: CValueObject::setPropertyByIndex(index, variant); break;
|
||||||
|
|||||||
@@ -47,12 +47,9 @@ namespace BlackCore::Data
|
|||||||
IndexVatsimServer,
|
IndexVatsimServer,
|
||||||
IndexVatsimHttpFsd,
|
IndexVatsimHttpFsd,
|
||||||
IndexSwiftDbFiles,
|
IndexSwiftDbFiles,
|
||||||
IndexBootstrapFileUrls,
|
|
||||||
IndexUpdateInfoFileUrls,
|
IndexUpdateInfoFileUrls,
|
||||||
IndexOnlineHelpUrls,
|
IndexOnlineHelpUrls,
|
||||||
IndexCrashReportServerUrl,
|
IndexCrashReportServerUrl,
|
||||||
IndexWasLoadedFromWeb,
|
|
||||||
IndexWasLoadedFromFile,
|
|
||||||
IndexSharedUrls,
|
IndexSharedUrls,
|
||||||
IndexMappingMinimumVersion,
|
IndexMappingMinimumVersion,
|
||||||
IndexPredefinedServers
|
IndexPredefinedServers
|
||||||
@@ -72,15 +69,6 @@ namespace BlackCore::Data
|
|||||||
//! Default constructor
|
//! Default constructor
|
||||||
CGlobalSetup();
|
CGlobalSetup();
|
||||||
|
|
||||||
//! Has data loaded from file
|
|
||||||
bool wasLoadedFromFile() const { return m_wasLoadedFromFile; }
|
|
||||||
|
|
||||||
//! Loaded (web/file)
|
|
||||||
bool wasLoaded() const;
|
|
||||||
|
|
||||||
//! Mark as loaded from file
|
|
||||||
void markAsLoadedFromFile(bool loaded) { m_wasLoadedFromFile = loaded; }
|
|
||||||
|
|
||||||
//! Http port
|
//! Http port
|
||||||
int getDbHttpPort() const { return m_dbHttpPort; }
|
int getDbHttpPort() const { return m_dbHttpPort; }
|
||||||
|
|
||||||
@@ -144,14 +132,6 @@ namespace BlackCore::Data
|
|||||||
//! Shared URLs
|
//! Shared URLs
|
||||||
const BlackMisc::Network::CUrlList &getSwiftSharedUrls() const;
|
const BlackMisc::Network::CUrlList &getSwiftSharedUrls() const;
|
||||||
|
|
||||||
//! Get pure shared URL as in getSwiftSharedUrls from bootstrap, distribution or other shared URL
|
|
||||||
//! \remark normally based on one of the getSwiftSharedUrls
|
|
||||||
BlackMisc::Network::CUrl getCorrespondingSharedUrl(const BlackMisc::Network::CUrl &candidate) const;
|
|
||||||
|
|
||||||
//! Bootstrap URLs
|
|
||||||
//! \remark based on getSwiftSharedUrls
|
|
||||||
BlackMisc::Network::CUrlList getSwiftBootstrapFileUrls() const;
|
|
||||||
|
|
||||||
//! Distribution URLs
|
//! Distribution URLs
|
||||||
//! \remark based on getSwiftSharedUrls
|
//! \remark based on getSwiftSharedUrls
|
||||||
BlackMisc::Network::CUrlList getSwiftUpdateInfoFileUrls() const;
|
BlackMisc::Network::CUrlList getSwiftUpdateInfoFileUrls() const;
|
||||||
@@ -216,9 +196,6 @@ namespace BlackCore::Data
|
|||||||
//! Schema version (shared files, bootstrap file)
|
//! Schema version (shared files, bootstrap file)
|
||||||
static const QString &schemaVersionString();
|
static const QString &schemaVersionString();
|
||||||
|
|
||||||
//! Build bootstrap file URL from shared URL
|
|
||||||
static QString buildBootstrapFileUrl(const QString &candidate);
|
|
||||||
|
|
||||||
//! Build the full dbdata directory URL from shared URL
|
//! Build the full dbdata directory URL from shared URL
|
||||||
static BlackMisc::Network::CUrl buildDbDataDirectoryUrl(const BlackMisc::Network::CUrl &candidate);
|
static BlackMisc::Network::CUrl buildDbDataDirectoryUrl(const BlackMisc::Network::CUrl &candidate);
|
||||||
|
|
||||||
@@ -226,7 +203,6 @@ namespace BlackCore::Data
|
|||||||
static CGlobalSetup fromJsonFile(const QString &fileNameAndPath, bool acceptCacheFormat);
|
static CGlobalSetup fromJsonFile(const QString &fileNameAndPath, bool acceptCacheFormat);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_wasLoadedFromFile = false; //!< Loaded from local file
|
|
||||||
int m_dbHttpPort = 80; //!< port
|
int m_dbHttpPort = 80; //!< port
|
||||||
int m_dbHttpsPort = 443; //!< SSL port
|
int m_dbHttpsPort = 443; //!< SSL port
|
||||||
qint64 m_pingIntervalSecs = 180; //!< seconds between datastore pings
|
qint64 m_pingIntervalSecs = 180; //!< seconds between datastore pings
|
||||||
@@ -252,7 +228,6 @@ namespace BlackCore::Data
|
|||||||
|
|
||||||
BLACK_METACLASS(
|
BLACK_METACLASS(
|
||||||
CGlobalSetup,
|
CGlobalSetup,
|
||||||
BLACK_METAMEMBER(wasLoadedFromFile),
|
|
||||||
BLACK_METAMEMBER(timestampMSecsSinceEpoch),
|
BLACK_METAMEMBER(timestampMSecsSinceEpoch),
|
||||||
BLACK_METAMEMBER(crashReportServerUrl),
|
BLACK_METAMEMBER(crashReportServerUrl),
|
||||||
BLACK_METAMEMBER(dbRootDirectoryUrl),
|
BLACK_METAMEMBER(dbRootDirectoryUrl),
|
||||||
@@ -275,16 +250,6 @@ namespace BlackCore::Data
|
|||||||
BLACK_METAMEMBER(dbDebugFlag)
|
BLACK_METAMEMBER(dbDebugFlag)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Trait for global setup data
|
|
||||||
struct TGlobalSetup : public BlackMisc::TDataTrait<CGlobalSetup>
|
|
||||||
{
|
|
||||||
//! Key in data cache
|
|
||||||
static const char *key() { return "bootstrap"; }
|
|
||||||
|
|
||||||
//! First load is synchronous
|
|
||||||
static constexpr bool isPinned() { return true; }
|
|
||||||
};
|
|
||||||
} // ns
|
} // ns
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(BlackCore::Data::CGlobalSetup)
|
Q_DECLARE_METATYPE(BlackCore::Data::CGlobalSetup)
|
||||||
|
|||||||
@@ -34,162 +34,41 @@ using namespace BlackCore::Data;
|
|||||||
|
|
||||||
namespace BlackCore
|
namespace BlackCore
|
||||||
{
|
{
|
||||||
CSetupReader::CSetupReader(QObject *parent) : QObject(parent),
|
CSetupReader::CSetupReader(QObject *parent) : QObject(parent)
|
||||||
m_cmdBootstrapUrl {
|
|
||||||
{ "url", "bootstrapurl" },
|
|
||||||
QCoreApplication::translate("application", "Bootstrap URL, e.g. https://datastore.swift-project.org/shared"),
|
|
||||||
"bootstrapurl",
|
|
||||||
(sApp->getApplicationInfo().isUnitTest()) ? unitTestBootstrapUrl() : ""
|
|
||||||
},
|
|
||||||
m_cmdBootstrapMode {
|
|
||||||
{ "bmode", "bootstrapmode" },
|
|
||||||
QCoreApplication::translate("application", "Bootstrap mode: explicit, implicit, cache(-only)"),
|
|
||||||
"bootstrapmode",
|
|
||||||
"explicit"
|
|
||||||
}
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QList<QCommandLineOption> CSetupReader::getCmdLineOptions() const
|
CStatusMessageList CSetupReader::loadSetup()
|
||||||
{
|
|
||||||
return QList<QCommandLineOption> { { m_cmdBootstrapUrl, m_cmdBootstrapMode } };
|
|
||||||
}
|
|
||||||
|
|
||||||
CStatusMessageList CSetupReader::asyncLoad()
|
|
||||||
{
|
{
|
||||||
CStatusMessageList msgs;
|
CStatusMessageList msgs;
|
||||||
if (m_localSetupFileValue.isEmpty())
|
msgs = this->readLocalBootstrapFile();
|
||||||
{
|
m_setupAvailable = msgs.isSuccess();
|
||||||
// TODO Check if file exists or is broken
|
|
||||||
msgs = this->readLocalBootstrapFile(CSwiftDirectories::shareDirectory() + "/shared/bootstrap/bootstrap.json");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msgs = this->readLocalBootstrapFile(m_localSetupFileValue);
|
|
||||||
}
|
|
||||||
msgs.push_back(this->manageSetupAvailability(false, msgs.isSuccess()));
|
|
||||||
return msgs;
|
return msgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSetupReader::parseCmdLineArguments()
|
CStatusMessageList CSetupReader::readLocalBootstrapFile()
|
||||||
{
|
{
|
||||||
// copy vars at beginning to simplify a threadsafe version in the future
|
const QString fileName = CSwiftDirectories::bootstrapResourceFilePath();
|
||||||
const QString cmdLineBootstrapUrl = this->getCmdLineBootstrapUrl();
|
// TODO Check if file exists or is broken
|
||||||
BootstrapMode bootstrapMode = stringToEnum(sApp->getParserValue(m_cmdBootstrapMode));
|
|
||||||
const bool ignoreCmdBootstrapUrl = m_ignoreCmdBootstrapUrl;
|
|
||||||
const bool checkCmdBootstrapUrl = m_checkCmdBootstrapUrl;
|
|
||||||
const QString bootstrapUrlFileValue = CGlobalSetup::buildBootstrapFileUrl(cmdLineBootstrapUrl);
|
|
||||||
QString localSetupFileValue;
|
|
||||||
const QUrl url(bootstrapUrlFileValue);
|
|
||||||
const QString urlString(url.toString());
|
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
if (urlString.isEmpty() && bootstrapMode == Explicit)
|
|
||||||
{
|
|
||||||
bootstrapMode = Implicit; // no URL, we use implicit mode
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// check on local file
|
|
||||||
if (url.isLocalFile())
|
|
||||||
{
|
|
||||||
localSetupFileValue = url.toLocalFile();
|
|
||||||
const QFile f(localSetupFileValue);
|
|
||||||
if (!f.exists())
|
|
||||||
{
|
|
||||||
sApp->cmdLineErrorMessage(QStringLiteral("File '%1' does not exist)").arg(localSetupFileValue));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check on explicit URL
|
|
||||||
if (bootstrapMode == Explicit)
|
|
||||||
{
|
|
||||||
if (!url.isLocalFile())
|
|
||||||
{
|
|
||||||
bool retry = false;
|
|
||||||
|
|
||||||
// "retry" possible in some cases
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (ignoreCmdBootstrapUrl || !checkCmdBootstrapUrl || CNetworkUtils::canConnect(url, CNetworkUtils::getLongTimeoutMs())) // cppcheck-suppress knownConditionTrueFalse
|
|
||||||
{
|
|
||||||
ok = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
retry = sApp->cmdLineErrorMessage(QStringLiteral("URL '%1' not reachable").arg(urlString), "", true);
|
|
||||||
}
|
|
||||||
while (retry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (false);
|
|
||||||
|
|
||||||
m_localSetupFileValue = localSetupFileValue;
|
|
||||||
m_bootstrapUrlFileValue = bootstrapUrlFileValue;
|
|
||||||
m_bootstrapMode = bootstrapMode;
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupReader::gracefulShutdown()
|
|
||||||
{
|
|
||||||
m_shutdown = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupReader::forceAvailabilityUpdate()
|
|
||||||
{
|
|
||||||
this->manageSetupAvailability(false, false); // fake a failed web read
|
|
||||||
}
|
|
||||||
|
|
||||||
CSetupReader::BootstrapMode CSetupReader::stringToEnum(const QString &s)
|
|
||||||
{
|
|
||||||
const QString bsm(s.toLower().trimmed());
|
|
||||||
if (bsm.startsWith("expl")) { return Explicit; }
|
|
||||||
if (bsm.startsWith("cache")) { return CacheOnly; }
|
|
||||||
return Implicit;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString &CSetupReader::unitTestBootstrapUrl()
|
|
||||||
{
|
|
||||||
static const QString url("https://datastore.swift-project.org/shared");
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
CStatusMessageList CSetupReader::readLocalBootstrapFile(const QString &fileName)
|
|
||||||
{
|
|
||||||
if (fileName.isEmpty()) { return CStatusMessage(this).error(u"No file name for local bootstrap file"); }
|
if (fileName.isEmpty()) { return CStatusMessage(this).error(u"No file name for local bootstrap file"); }
|
||||||
if (!sApp || sApp->isShuttingDown()) { return CStatusMessage(this).error(u"No sApp, shutting down?"); }
|
if (!sApp || sApp->isShuttingDown()) { return CStatusMessage(this).error(u"No sApp, shutting down?"); }
|
||||||
QString fn;
|
|
||||||
const QFile file(fileName);
|
const QFile file(fileName);
|
||||||
if (!file.exists())
|
if (!file.exists())
|
||||||
{
|
{
|
||||||
// relative name?
|
return CStatusMessage(this).error(u"File '%1' not existing") << fileName;
|
||||||
const QString dir(sApp->getCmdSwiftPrivateSharedDir());
|
|
||||||
if (dir.isEmpty()) { return CStatusMessage(this).error(u"Empty shared directory '%1' for bootstrap file") << dir; }
|
|
||||||
|
|
||||||
// no version for local files, as those come with the current code
|
|
||||||
fn = CFileUtils::appendFilePaths(dir, "bootstrap/" + CSwiftDirectories::bootstrapFileName());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fn = fileName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString content(CFileUtils::readFileToString(fn));
|
const QString content(CFileUtils::readFileToString(fileName));
|
||||||
if (content.isEmpty()) { return CStatusMessage(this).error(u"File '%1' not existing or empty") << fn; }
|
if (content.isEmpty()) { return CStatusMessage(this).error(u"File '%1' empty") << fileName; }
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CGlobalSetup s;
|
m_setup.convertFromJson(content);
|
||||||
s.convertFromJson(content);
|
return CStatusMessage(this).info(u"Setup loaded from local file '%1'") << fileName;
|
||||||
s.markAsLoadedFromFile(true);
|
|
||||||
const CStatusMessage setMsg = m_setup.set(s);
|
|
||||||
const CStatusMessage setInfo = CStatusMessage(this).info(u"Setup cache updated from local file '%1'") << fn;
|
|
||||||
return setMsg.isSuccess() ? setInfo : setMsg;
|
|
||||||
}
|
}
|
||||||
catch (const CJsonException &ex)
|
catch (const CJsonException &ex)
|
||||||
{
|
{
|
||||||
return CStatusMessage::fromJsonException(ex, this, QStringLiteral("Parsing local setup file '%1'").arg(fn));
|
return CStatusMessage::fromJsonException(ex, this, QStringLiteral("Parsing local setup file '%1'").arg(fileName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,136 +78,8 @@ namespace BlackCore
|
|||||||
return cats;
|
return cats;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSetupReader::hasCmdLineBootstrapUrl() const
|
|
||||||
{
|
|
||||||
return !this->getCmdLineBootstrapUrl().isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSetupReader::getCmdLineBootstrapUrl() const
|
|
||||||
{
|
|
||||||
if (m_ignoreCmdBootstrapUrl) return {};
|
|
||||||
return sApp->getParserValue(m_cmdBootstrapUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupReader::setIgnoreCmdLineBootstrapUrl(bool ignore)
|
|
||||||
{
|
|
||||||
m_ignoreCmdBootstrapUrl = ignore;
|
|
||||||
this->parseCmdLineArguments(); // T156 this part not threadsafe, currently not a real problem as setup reader runs in main thread
|
|
||||||
}
|
|
||||||
|
|
||||||
CGlobalSetup CSetupReader::getSetup() const
|
CGlobalSetup CSetupReader::getSetup() const
|
||||||
{
|
{
|
||||||
return m_setup.get();
|
return m_setup;
|
||||||
}
|
|
||||||
|
|
||||||
bool CSetupReader::hasCachedSetup() const
|
|
||||||
{
|
|
||||||
const CGlobalSetup cachedSetup = m_setup.get();
|
|
||||||
const bool cacheAvailable = cachedSetup.wasLoaded();
|
|
||||||
return cacheAvailable;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDateTime CSetupReader::getSetupCacheTimestamp() const
|
|
||||||
{
|
|
||||||
return m_setup.getTimestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSetupReader::prefillCacheWithLocalResourceBootstrapFile()
|
|
||||||
{
|
|
||||||
if (m_shutdown) { return false; }
|
|
||||||
m_setup.synchronize(); // make sure it is loaded
|
|
||||||
const CGlobalSetup cachedSetup = m_setup.get();
|
|
||||||
const bool cacheAvailable = cachedSetup.wasLoaded();
|
|
||||||
if (cacheAvailable)
|
|
||||||
{
|
|
||||||
CLogMessage(this).info(u"Setup cache prefill (bootstrap already cached, no prefill needed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const QString fn = CSwiftDirectories::bootstrapResourceFilePath();
|
|
||||||
const CStatusMessageList msgs = this->readLocalBootstrapFile(fn);
|
|
||||||
CLogMessage::preformatted(msgs);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSetupReader::getLastSuccessfulSetupUrl() const
|
|
||||||
{
|
|
||||||
QReadLocker l(&m_lockSetup);
|
|
||||||
return m_lastSuccessfulSetupUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupReader::synchronize()
|
|
||||||
{
|
|
||||||
m_setup.synchronize();
|
|
||||||
}
|
|
||||||
|
|
||||||
CStatusMessageList CSetupReader::getLastSetupReadErrorMessages() const
|
|
||||||
{
|
|
||||||
QReadLocker l(&m_lockSetup);
|
|
||||||
return m_setupReadErrorMsgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString &CSetupReader::getBootstrapUrlFile() const
|
|
||||||
{
|
|
||||||
if (!m_localSetupFileValue.isEmpty()) { return m_localSetupFileValue; }
|
|
||||||
return m_bootstrapUrlFileValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSetupReader::getBootstrapModeAsString() const
|
|
||||||
{
|
|
||||||
switch (m_bootstrapMode)
|
|
||||||
{
|
|
||||||
case CacheOnly: return QStringLiteral("cache only");
|
|
||||||
case Explicit: return QStringLiteral("explicit");
|
|
||||||
case Implicit: return QStringLiteral("implicit");
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupReader::setLastSetupReadErrorMessages(const CStatusMessageList &messages)
|
|
||||||
{
|
|
||||||
QWriteLocker l(&m_lockSetup);
|
|
||||||
m_setupReadErrorMsgs = messages.getErrorMessages();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupReader::networkReplyProgress(int logId, qint64 current, qint64 max, const QUrl &url)
|
|
||||||
{
|
|
||||||
Q_UNUSED(url)
|
|
||||||
Q_UNUSED(logId)
|
|
||||||
Q_UNUSED(current)
|
|
||||||
Q_UNUSED(max)
|
|
||||||
}
|
|
||||||
|
|
||||||
CStatusMessageList CSetupReader::manageSetupAvailability(bool webRead, bool localRead)
|
|
||||||
{
|
|
||||||
Q_ASSERT_X(!(webRead && localRead), Q_FUNC_INFO, "Local and web read together seems to be wrong");
|
|
||||||
CStatusMessageList msgs;
|
|
||||||
|
|
||||||
bool available = false;
|
|
||||||
if (webRead || localRead)
|
|
||||||
{
|
|
||||||
available = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const bool cacheAvailable = m_setup.get().wasLoaded(); // loaded from web or file
|
|
||||||
available = cacheAvailable && m_bootstrapMode != Explicit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (available && !webRead && !localRead)
|
|
||||||
{
|
|
||||||
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, u"Setup available, but not updated this time"));
|
|
||||||
}
|
|
||||||
else if (!available)
|
|
||||||
{
|
|
||||||
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityError, u"Setup not available"));
|
|
||||||
if (m_bootstrapMode == Explicit)
|
|
||||||
{
|
|
||||||
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityError, u"Mode is 'explicit', likely URL '" % m_bootstrapUrlFileValue % u"' is not reachable"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_setupAvailable = available;
|
|
||||||
emit this->setupHandlingCompleted(available);
|
|
||||||
return msgs;
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -22,10 +22,6 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
namespace BlackMisc
|
|
||||||
{
|
|
||||||
class CLogCategoryList;
|
|
||||||
}
|
|
||||||
namespace BlackCoreTest
|
namespace BlackCoreTest
|
||||||
{
|
{
|
||||||
class CTestConnectivity;
|
class CTestConnectivity;
|
||||||
@@ -39,144 +35,38 @@ namespace BlackCore
|
|||||||
//! \note This class is no(!) BlackCore::CThreadedReader as it will be loaded once during startup
|
//! \note This class is no(!) BlackCore::CThreadedReader as it will be loaded once during startup
|
||||||
//! and reading setup data is fast. The read file is also called "bootstrap" file as it tells
|
//! and reading setup data is fast. The read file is also called "bootstrap" file as it tells
|
||||||
//! swift which data and versions are located where. Without that file we cannot start.
|
//! swift which data and versions are located where. Without that file we cannot start.
|
||||||
//! Once the file is in place (i.e. in the cache) it can be automatically updated.
|
|
||||||
//!
|
//!
|
||||||
//! \sa BlackCore::Data::TGlobalSetup
|
|
||||||
//! \sa BlackMisc::Db::TUpdateInfo
|
//! \sa BlackMisc::Db::TUpdateInfo
|
||||||
class BLACKCORE_EXPORT CSetupReader : public QObject
|
class BLACKCORE_EXPORT CSetupReader : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
friend class CApplication; //!< only using class
|
|
||||||
friend class BlackCoreTest::CTestConnectivity;
|
friend class BlackCoreTest::CTestConnectivity;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Categories
|
//! Categories
|
||||||
static const QStringList &getLogCategories();
|
static const QStringList &getLogCategories();
|
||||||
|
|
||||||
//! Has a given cmd line argument for bootstrap URL?
|
//! Constructor
|
||||||
bool hasCmdLineBootstrapUrl() const;
|
explicit CSetupReader(QObject *parent);
|
||||||
|
|
||||||
//! CMD line argument for bootstrap URL
|
//! Load the setup. If the setup is already loaded, the setup is reloaded
|
||||||
QString getCmdLineBootstrapUrl() const;
|
BlackMisc::CStatusMessageList loadSetup();
|
||||||
|
|
||||||
//! Ignore the bootstrap URL
|
//! Setup available?
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
void setIgnoreCmdLineBootstrapUrl(bool ignore);
|
bool isSetupAvailable() const { return m_setupAvailable; }
|
||||||
|
|
||||||
//! Check connection of the bootstrap URL
|
|
||||||
//! \threadsafe
|
|
||||||
void setCheckCmdLineBootstrapUrl(bool check) { m_checkCmdBootstrapUrl = check; }
|
|
||||||
|
|
||||||
//! Current setup (reader URLs, DB location, crash server)
|
//! Current setup (reader URLs, DB location, crash server)
|
||||||
//! \remarks aka "bootstrap file"
|
//! \remarks aka "bootstrap file"
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
Data::CGlobalSetup getSetup() const;
|
Data::CGlobalSetup getSetup() const;
|
||||||
|
|
||||||
//! Has cached setup ("bootstrap") data?
|
|
||||||
//! \threadsafe
|
|
||||||
bool hasCachedSetup() const;
|
|
||||||
|
|
||||||
//! Get setup cache timestamp
|
|
||||||
//! \threadsafe
|
|
||||||
QDateTime getSetupCacheTimestamp() const;
|
|
||||||
|
|
||||||
//! Load the cache file local bootstrap file
|
|
||||||
//! \remark can be used during installation as failover
|
|
||||||
//! \threadsafe
|
|
||||||
bool prefillCacheWithLocalResourceBootstrapFile();
|
|
||||||
|
|
||||||
//! Last distribution URL successfully read
|
|
||||||
//! \threadsafe
|
|
||||||
QString getLastSuccessfulSetupUrl() const;
|
|
||||||
|
|
||||||
//! Synchronize the caches
|
|
||||||
void synchronize();
|
|
||||||
|
|
||||||
//! Last setup parsing error messages (if any)
|
|
||||||
BlackMisc::CStatusMessageList getLastSetupReadErrorMessages() const;
|
|
||||||
|
|
||||||
//! Get bootstrap URL, either m_bootstrapUrlFileValue or m_localSetupFileValue
|
|
||||||
const QString &getBootstrapUrlFile() const;
|
|
||||||
|
|
||||||
//! Mode as string
|
|
||||||
QString getBootstrapModeAsString() const;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
//! Setup fetched or failed (from web, cache, or local file)?
|
|
||||||
void setupHandlingCompleted(bool available);
|
|
||||||
|
|
||||||
//! Message about the loading status
|
|
||||||
void setupLoadingMessages(const BlackMisc::CStatusMessageList &messages);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//! Constructor
|
|
||||||
explicit CSetupReader(QObject *parent);
|
|
||||||
|
|
||||||
//! Load the data
|
|
||||||
BlackMisc::CStatusMessageList asyncLoad();
|
|
||||||
|
|
||||||
//! Parse cmd line arguments
|
|
||||||
bool parseCmdLineArguments();
|
|
||||||
|
|
||||||
//! Add cmd line arguments to BlackCore::CApplication
|
|
||||||
QList<QCommandLineOption> getCmdLineOptions() const;
|
|
||||||
|
|
||||||
//! Terminate
|
|
||||||
void gracefulShutdown();
|
|
||||||
|
|
||||||
//! Setup available?
|
|
||||||
//! \threadsafe
|
|
||||||
bool isSetupAvailable() const { return m_setupAvailable; }
|
|
||||||
|
|
||||||
//! Force an availability update
|
|
||||||
//! \remark check for cached setup if the read check never got triggered
|
|
||||||
void forceAvailabilityUpdate();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Bootstrap mode
|
|
||||||
enum BootstrapMode
|
|
||||||
{
|
|
||||||
Implicit,
|
|
||||||
Explicit,
|
|
||||||
CacheOnly
|
|
||||||
};
|
|
||||||
|
|
||||||
std::atomic<bool> m_shutdown { false }; //!< shutdown in progress
|
|
||||||
std::atomic<bool> m_setupAvailable { false }; //!< setup available?
|
std::atomic<bool> m_setupAvailable { false }; //!< setup available?
|
||||||
std::atomic<bool> m_ignoreCmdBootstrapUrl { false }; //!< ignore the explicitly set bootstrap URL
|
Data::CGlobalSetup m_setup {}; //!< data setup
|
||||||
std::atomic<bool> m_checkCmdBootstrapUrl { true }; //!< check connection on CMD bootstrap URL
|
|
||||||
std::atomic_int m_bootstrapReadErrors { 0 }; //!< failed bootstrap reads
|
|
||||||
std::atomic_int m_updateInfoReadErrors { 0 }; //!< failed version info reads
|
|
||||||
QString m_localSetupFileValue; //!< Local file for setup, passed by cmd line arguments
|
|
||||||
QString m_bootstrapUrlFileValue; //!< Bootstrap URL if not local
|
|
||||||
BootstrapMode m_bootstrapMode = Explicit; //!< How to bootstrap
|
|
||||||
BlackMisc::Network::CUrlList m_bootstrapUrls; //!< location of setup files
|
|
||||||
QCommandLineOption m_cmdBootstrapUrl; //!< bootstrap URL
|
|
||||||
QCommandLineOption m_cmdBootstrapMode; //!< bootstrap mode
|
|
||||||
mutable QReadWriteLock m_lockSetup; //!< lock for setup
|
|
||||||
mutable QReadWriteLock m_lockUpdateInfo; //!< lock for update info
|
|
||||||
QString m_lastSuccessfulSetupUrl; //!< last successful read setup URL
|
|
||||||
BlackMisc::CStatusMessageList m_setupReadErrorMsgs; //!< last parsing error messages
|
|
||||||
BlackMisc::CData<Data::TGlobalSetup> m_setup { this }; //!< data cache setup
|
|
||||||
|
|
||||||
//! Read by local individual file and update cache from that
|
//! Read by local file
|
||||||
BlackMisc::CStatusMessageList readLocalBootstrapFile(const QString &fileName);
|
BlackMisc::CStatusMessageList readLocalBootstrapFile();
|
||||||
|
|
||||||
//! Emit the availability signal and state and trigger follow up actions
|
|
||||||
//! \threadsafe
|
|
||||||
BlackMisc::CStatusMessageList manageSetupAvailability(bool webRead, bool localRead = false);
|
|
||||||
|
|
||||||
//! Set last setup parsing messages
|
|
||||||
void setLastSetupReadErrorMessages(const BlackMisc::CStatusMessageList &messages);
|
|
||||||
|
|
||||||
//! Progress
|
|
||||||
void networkReplyProgress(int logId, qint64 current, qint64 max, const QUrl &url);
|
|
||||||
|
|
||||||
//! Convert string to bootstrap mode
|
|
||||||
static BootstrapMode stringToEnum(const QString &s);
|
|
||||||
|
|
||||||
//! Bootsrap URL used for unit tests
|
|
||||||
static const QString &unitTestBootstrapUrl();
|
|
||||||
};
|
};
|
||||||
} // ns
|
} // ns
|
||||||
|
|
||||||
|
|||||||
@@ -377,12 +377,6 @@ namespace BlackGui::Components
|
|||||||
{
|
{
|
||||||
this->initMultiSimulatorCache(&m_modelCaches, file);
|
this->initMultiSimulatorCache(&m_modelCaches, file);
|
||||||
}
|
}
|
||||||
else if (file.contains(CSwiftDirectories::bootstrapFileName()))
|
|
||||||
{
|
|
||||||
CData<TGlobalSetup> setup { this }; //!< data cache setup
|
|
||||||
const CGlobalSetup s = CGlobalSetup::fromJsonFile(file, true);
|
|
||||||
setup.set(s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow the cache files to be generated before we will override them
|
// allow the cache files to be generated before we will override them
|
||||||
|
|||||||
@@ -37,11 +37,6 @@ namespace BlackGui::Components
|
|||||||
ui->comp_CopyConfiguration->setNameFilterDisables(disable);
|
ui->comp_CopyConfiguration->setNameFilterDisables(disable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCopyConfigurationDialog::setWithBootstrapFile(bool withBootstrapFile)
|
|
||||||
{
|
|
||||||
ui->comp_CopyConfiguration->setWithBootstrapFile(withBootstrapFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCopyConfigurationDialog::event(QEvent *event)
|
bool CCopyConfigurationDialog::event(QEvent *event)
|
||||||
{
|
{
|
||||||
if (CGuiApplication::triggerShowHelp(this, event)) { return true; }
|
if (CGuiApplication::triggerShowHelp(this, event)) { return true; }
|
||||||
|
|||||||
@@ -41,9 +41,6 @@ namespace BlackGui::Components
|
|||||||
//! \copydoc QFileSystemModel::setNameFilterDisables
|
//! \copydoc QFileSystemModel::setNameFilterDisables
|
||||||
void setNameFilterDisables(bool disable);
|
void setNameFilterDisables(bool disable);
|
||||||
|
|
||||||
//! \copydoc CCopyConfigurationComponent::setWithBootstrapFile
|
|
||||||
void setWithBootstrapFile(bool withBootstrapFile);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \copydoc QObject::event
|
//! \copydoc QObject::event
|
||||||
virtual bool event(QEvent *event) override;
|
virtual bool event(QEvent *event) override;
|
||||||
|
|||||||
@@ -5,16 +5,11 @@
|
|||||||
#include "blackgui/components/copymodelsfromotherswiftversionsdialog.h"
|
#include "blackgui/components/copymodelsfromotherswiftversionsdialog.h"
|
||||||
#include "ui_setuploadingdialog.h"
|
#include "ui_setuploadingdialog.h"
|
||||||
#include "blackgui/guiapplication.h"
|
#include "blackgui/guiapplication.h"
|
||||||
#include "blackcore/data/globalsetup.h"
|
|
||||||
#include "blackcore/setupreader.h"
|
#include "blackcore/setupreader.h"
|
||||||
#include "blackmisc/swiftdirectories.h"
|
#include "blackmisc/swiftdirectories.h"
|
||||||
#include "blackmisc/directoryutils.h"
|
|
||||||
#include "blackmisc/network/urllist.h"
|
|
||||||
|
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QTimer>
|
|
||||||
#include <QPointer>
|
|
||||||
|
|
||||||
using namespace BlackMisc;
|
using namespace BlackMisc;
|
||||||
using namespace BlackMisc::Network;
|
using namespace BlackMisc::Network;
|
||||||
@@ -27,30 +22,15 @@ namespace BlackGui::Components
|
|||||||
ui(new Ui::CSetupLoadingDialog)
|
ui(new Ui::CSetupLoadingDialog)
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Need sApp");
|
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Need sApp");
|
||||||
if (this->hasSetupReader())
|
|
||||||
{
|
|
||||||
// reset if it was temporarily ignored
|
|
||||||
sApp->getSetupReader()->setIgnoreCmdLineBootstrapUrl(false);
|
|
||||||
connect(sApp, &CGuiApplication::setupHandlingCompleted, this, &CSetupLoadingDialog::onSetupHandlingCompleted);
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
connect(ui->pb_IgnoreExplicitBootstrapUrl, &QPushButton::clicked, this, &CSetupLoadingDialog::tryAgainWithoutBootstrapUrl);
|
|
||||||
connect(ui->pb_LoadFromDisk, &QPushButton::clicked, this, &CSetupLoadingDialog::prefillSetupCache);
|
|
||||||
connect(ui->pb_Help, &QPushButton::clicked, this, &CSetupLoadingDialog::openHelpPage);
|
|
||||||
connect(ui->pb_CopyFromSwift, &QPushButton::clicked, this, &CSetupLoadingDialog::copyFromOtherSwiftVersions);
|
|
||||||
connect(ui->pb_OpemDirectory, &QPushButton::clicked, this, &CSetupLoadingDialog::openDirectory);
|
|
||||||
connect(ui->pb_TryToFix, &QPushButton::clicked, this, &CSetupLoadingDialog::tryToFix);
|
|
||||||
|
|
||||||
QPushButton *retry = ui->bb_Dialog->button(QDialogButtonBox::Retry);
|
const QString bootstrapPath = CSwiftDirectories::bootstrapResourceFilePath();
|
||||||
retry->setDefault(true);
|
ui->lbl_ownBootstrap->setText("Your boostrap.json file is available at <a href=" + bootstrapPath + ">" + bootstrapPath + "</>");
|
||||||
|
|
||||||
this->displaySetupCacheInfo();
|
// hide unnecessary details
|
||||||
this->displayCmdBoostrapUrl();
|
ui->comp_Messages->hideFilterBar();
|
||||||
this->displayGlobalSetup();
|
ui->comp_Messages->showDetails(false);
|
||||||
this->displayOtherVersionsInfo();
|
|
||||||
|
|
||||||
ui->comp_Messages->hideFilterBar(); // saves space, we only expect aview messages
|
|
||||||
}
|
}
|
||||||
CSetupLoadingDialog::CSetupLoadingDialog(const CStatusMessageList &msgs, QWidget *parent) : CSetupLoadingDialog(parent)
|
CSetupLoadingDialog::CSetupLoadingDialog(const CStatusMessageList &msgs, QWidget *parent) : CSetupLoadingDialog(parent)
|
||||||
{
|
{
|
||||||
@@ -59,124 +39,4 @@ namespace BlackGui::Components
|
|||||||
|
|
||||||
CSetupLoadingDialog::~CSetupLoadingDialog()
|
CSetupLoadingDialog::~CSetupLoadingDialog()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool CSetupLoadingDialog::hasCachedSetup() const
|
|
||||||
{
|
|
||||||
return this->hasSetupReader() && sApp->getSetupReader()->hasCachedSetup();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSetupLoadingDialog::hasSetupReader() const
|
|
||||||
{
|
|
||||||
return sApp && sApp->hasSetupReader();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupLoadingDialog::displayCmdBoostrapUrl()
|
|
||||||
{
|
|
||||||
if (!sApp->hasSetupReader()) { return; }
|
|
||||||
ui->le_CmdLine->setText(sApp->cmdLineArgumentsAsString());
|
|
||||||
ui->le_BootstrapMode->setText(sApp->getSetupReader()->getBootstrapModeAsString());
|
|
||||||
|
|
||||||
const QString bsUrl = sApp->getSetupReader()->getCmdLineBootstrapUrl();
|
|
||||||
ui->pb_IgnoreExplicitBootstrapUrl->setVisible(!bsUrl.isEmpty());
|
|
||||||
ui->le_BootstrapUrl->setText(bsUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupLoadingDialog::displayGlobalSetup()
|
|
||||||
{
|
|
||||||
const QString gs = sApp->getGlobalSetup().convertToQString("\n", true);
|
|
||||||
Q_UNUSED(gs)
|
|
||||||
// ui->comp_Messages->appendPlainTextToConsole(gs);
|
|
||||||
//! \fixme create plain text console for this (used to be part of the log component, changed by issue T36)
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupLoadingDialog::openHelpPage()
|
|
||||||
{
|
|
||||||
const CUrl url = sApp->getGlobalSetup().getHelpPageUrl("bootstrap");
|
|
||||||
if (url.isEmpty()) { return; }
|
|
||||||
QDesktopServices::openUrl(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupLoadingDialog::tryAgainWithoutBootstrapUrl()
|
|
||||||
{
|
|
||||||
if (!sApp->hasSetupReader()) { return; }
|
|
||||||
sApp->getSetupReader()->setIgnoreCmdLineBootstrapUrl(true);
|
|
||||||
this->accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupLoadingDialog::tryToFix()
|
|
||||||
{
|
|
||||||
this->prefillSetupCache();
|
|
||||||
QPushButton *retry = ui->bb_Dialog->button(QDialogButtonBox::Retry);
|
|
||||||
if (!retry) { return; }
|
|
||||||
|
|
||||||
QPointer<CSetupLoadingDialog> myself(this);
|
|
||||||
QTimer::singleShot(2000, this, [=] {
|
|
||||||
if (!sApp || !myself) { return; }
|
|
||||||
retry->click();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupLoadingDialog::prefillSetupCache()
|
|
||||||
{
|
|
||||||
if (!sApp || sApp->isShuttingDown()) { return; }
|
|
||||||
if (!this->hasSetupReader()) { return; }
|
|
||||||
sApp->getSetupReader()->prefillCacheWithLocalResourceBootstrapFile();
|
|
||||||
this->displaySetupCacheInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupLoadingDialog::displaySetupCacheInfo()
|
|
||||||
{
|
|
||||||
if (this->hasSetupReader())
|
|
||||||
{
|
|
||||||
// reset if it was temporarily ignored
|
|
||||||
const CSetupReader *sr = sApp->getSetupReader();
|
|
||||||
const QDateTime setupTs = sr->getSetupCacheTimestamp();
|
|
||||||
static const QDateTime zeroTime = QDateTime::fromMSecsSinceEpoch(0);
|
|
||||||
ui->le_SetupCache->setText(setupTs.isValid() && setupTs > zeroTime ?
|
|
||||||
setupTs.toString(Qt::ISODateWithMs) :
|
|
||||||
"No cache timestamp");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui->le_SetupCache->setText("No setup reader");
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool hasCachedSetup = this->hasCachedSetup();
|
|
||||||
ui->pb_LoadFromDisk->setEnabled(!hasCachedSetup);
|
|
||||||
ui->pb_LoadFromDisk->setToolTip(hasCachedSetup ? "Cached setup already available" : "No cached setup");
|
|
||||||
ui->pb_TryToFix->setEnabled(!hasCachedSetup);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupLoadingDialog::displayOtherVersionsInfo()
|
|
||||||
{
|
|
||||||
const int other = CSwiftDirectories::applicationDataDirectoriesCount() - 1;
|
|
||||||
ui->le_OtherSwiftVersions->setText(QStringLiteral("There is/are %1 other swift version(s) installed").arg(other));
|
|
||||||
ui->pb_CopyFromSwift->setEnabled(other > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupLoadingDialog::openDirectory()
|
|
||||||
{
|
|
||||||
const QUrl url = QUrl::fromLocalFile(CSwiftDirectories::normalizedApplicationDataDirectory());
|
|
||||||
QDesktopServices::openUrl(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupLoadingDialog::copyFromOtherSwiftVersions()
|
|
||||||
{
|
|
||||||
if (!m_copyFromOtherSwiftVersion)
|
|
||||||
{
|
|
||||||
CCopyModelsFromOtherSwiftVersionsDialog *d = new CCopyModelsFromOtherSwiftVersionsDialog(this);
|
|
||||||
d->setModal(true);
|
|
||||||
m_copyFromOtherSwiftVersion.reset(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int r = m_copyFromOtherSwiftVersion->exec();
|
|
||||||
Q_UNUSED(r);
|
|
||||||
this->displaySetupCacheInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSetupLoadingDialog::onSetupHandlingCompleted(bool success)
|
|
||||||
{
|
|
||||||
Q_UNUSED(success);
|
|
||||||
this->displaySetupCacheInfo();
|
|
||||||
}
|
|
||||||
} // ns
|
} // ns
|
||||||
|
|||||||
@@ -15,19 +15,14 @@ namespace Ui
|
|||||||
}
|
}
|
||||||
namespace BlackGui::Components
|
namespace BlackGui::Components
|
||||||
{
|
{
|
||||||
class CCopyModelsFromOtherSwiftVersionsDialog;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Setup dialog, if something goes wrong allows to copy bootstrap file
|
* Setup dialog, if loading the boostrap file fails
|
||||||
*/
|
*/
|
||||||
class CSetupLoadingDialog : public QDialog
|
class CSetupLoadingDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Ctor
|
|
||||||
explicit CSetupLoadingDialog(QWidget *parent = nullptr);
|
|
||||||
|
|
||||||
//! Ctor with messages
|
//! Ctor with messages
|
||||||
CSetupLoadingDialog(const BlackMisc::CStatusMessageList &msgs, QWidget *parent = nullptr);
|
CSetupLoadingDialog(const BlackMisc::CStatusMessageList &msgs, QWidget *parent = nullptr);
|
||||||
|
|
||||||
@@ -36,46 +31,9 @@ namespace BlackGui::Components
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<Ui::CSetupLoadingDialog> ui;
|
QScopedPointer<Ui::CSetupLoadingDialog> ui;
|
||||||
QScopedPointer<CCopyModelsFromOtherSwiftVersionsDialog> m_copyFromOtherSwiftVersion;
|
|
||||||
|
|
||||||
//! Cached setup available?
|
//! Ctor
|
||||||
bool hasCachedSetup() const;
|
explicit CSetupLoadingDialog(QWidget *parent = nullptr);
|
||||||
|
|
||||||
//! Setup reader?
|
|
||||||
bool hasSetupReader() const;
|
|
||||||
|
|
||||||
//! Display bootstrap URL
|
|
||||||
void displayCmdBoostrapUrl();
|
|
||||||
|
|
||||||
//! Display global setup
|
|
||||||
void displayGlobalSetup();
|
|
||||||
|
|
||||||
//! Open the help page
|
|
||||||
void openHelpPage();
|
|
||||||
|
|
||||||
//! Try again without explicit bootstrap URL
|
|
||||||
void tryAgainWithoutBootstrapUrl();
|
|
||||||
|
|
||||||
//! Try to fix
|
|
||||||
void tryToFix();
|
|
||||||
|
|
||||||
//! Prefill setup cache
|
|
||||||
void prefillSetupCache();
|
|
||||||
|
|
||||||
//! Display the setup cache info
|
|
||||||
void displaySetupCacheInfo();
|
|
||||||
|
|
||||||
//! Display other versions info
|
|
||||||
void displayOtherVersionsInfo();
|
|
||||||
|
|
||||||
//! Open directory
|
|
||||||
void openDirectory();
|
|
||||||
|
|
||||||
//! Copy from other swift versions
|
|
||||||
void copyFromOtherSwiftVersions();
|
|
||||||
|
|
||||||
//! Setup loading has been completed
|
|
||||||
void onSetupHandlingCompleted(bool success);
|
|
||||||
};
|
};
|
||||||
} // ns
|
} // ns
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Loading the setup ("bootstrap file")</string>
|
<string>Loading the setup file failed</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -36,173 +36,29 @@
|
|||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="gb_Details">
|
<widget class="QLabel" name="lbl_Info">
|
||||||
<property name="title">
|
<property name="text">
|
||||||
<string>Setup and caches</string>
|
<string><html><head/><body><p><span style=" font-weight:600;">Loading the setup file (bootstrap.json) has failed!</span> This file is required for <span style=" font-style:italic;">swift</span> to work properly. Fix the errors mentioned below and restart swift. You can also replace your bootstrap.json with the latest version available <a href="https://raw.githubusercontent.com/swift-project/pilotclient/main/resources/share/shared/bootstrap/bootstrap.json"><span style=" text-decoration: underline; color:#0000ff;">from GitHub.</span></a></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::RichText</enum>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lbl_ownBootstrap">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gl_Details" columnstretch="0,0,0,0">
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLineEdit" name="le_BootstrapMode">
|
|
||||||
<property name="whatsThis">
|
|
||||||
<string><html><head/><body><p>The mode: 'implicit' means no URL is provided and the value is obtained from an existing setup. 'explicit' means an URL is provided via command line arguments.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="lbl_BootstrapMode">
|
|
||||||
<property name="text">
|
|
||||||
<string>Mode:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QLineEdit" name="le_SetupCache">
|
|
||||||
<property name="whatsThis">
|
|
||||||
<string>Timestamp of the setup cache.</string>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="lbl_CmdLine">
|
|
||||||
<property name="text">
|
|
||||||
<string>Command:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="lbl_BootstrapUrl">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Where the bootstrap file is located</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Bootstrap URL:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QLineEdit" name="le_BootstrapUrl">
|
|
||||||
<property name="whatsThis">
|
|
||||||
<string><html><head/><body><p>The bootstrap URL provided by command line options. This is where the setup data are loaded from.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1" colspan="3">
|
|
||||||
<widget class="QLineEdit" name="le_CmdLine">
|
|
||||||
<property name="whatsThis">
|
|
||||||
<string>The command line.</string>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="lbl_SetupCache">
|
|
||||||
<property name="text">
|
|
||||||
<string>Setup cache:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="lbl_CopyOver">
|
|
||||||
<property name="text">
|
|
||||||
<string>Copy over:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="2">
|
|
||||||
<widget class="QPushButton" name="pb_LoadFromDisk">
|
|
||||||
<property name="whatsThis">
|
|
||||||
<string>load the cache data from disk, i.e. from the file which came with the installer</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>from disk</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0" colspan="4">
|
|
||||||
<widget class="QLabel" name="lbl_Info">
|
|
||||||
<property name="text">
|
|
||||||
<string><html><head/><body><p><span style=" font-size:9pt; font-weight:600;">Loading the setup (aka &quot;bootstrap file&quot;) has failed!</span><span style=" font-size:9pt;"> This file is required for </span><span style=" font-size:9pt; font-style:italic;">swift</span><span style=" font-size:9pt;"> to work properly. You can try to load the file again (&quot;Retry&quot;) or give up (&quot;Cancel&quot;). If you have set an explicit bootstrap URL, you can also ignore this URL and use cached setup data (if there are any). If all goes wrong, you can try to load the setup cache from disk.</span></p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="textFormat">
|
|
||||||
<enum>Qt::RichText</enum>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="2">
|
|
||||||
<widget class="QPushButton" name="pb_IgnoreExplicitBootstrapUrl">
|
|
||||||
<property name="whatsThis">
|
|
||||||
<string>ignore the bootstrap URL and try to read from cache</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>ignore</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="3">
|
|
||||||
<widget class="QPushButton" name="pb_OpemDirectory">
|
|
||||||
<property name="text">
|
|
||||||
<string>open dir.</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="3">
|
|
||||||
<widget class="QPushButton" name="pb_Help">
|
|
||||||
<property name="text">
|
|
||||||
<string>help page</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QLineEdit" name="le_OtherSwiftVersions">
|
|
||||||
<property name="whatsThis">
|
|
||||||
<string>Info about other swift versions installed</string>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="2">
|
|
||||||
<widget class="QPushButton" name="pb_CopyFromSwift">
|
|
||||||
<property name="whatsThis">
|
|
||||||
<string>copy cache data from another swift version</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>copy over</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="2" colspan="2">
|
|
||||||
<widget class="QPushButton" name="pb_TryToFix">
|
|
||||||
<property name="text">
|
|
||||||
<string>try to fix</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -236,7 +92,7 @@
|
|||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Retry</set>
|
<set>QDialogButtonBox::Close</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -250,18 +106,6 @@
|
|||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<tabstops>
|
|
||||||
<tabstop>le_CmdLine</tabstop>
|
|
||||||
<tabstop>le_BootstrapMode</tabstop>
|
|
||||||
<tabstop>le_BootstrapUrl</tabstop>
|
|
||||||
<tabstop>pb_IgnoreExplicitBootstrapUrl</tabstop>
|
|
||||||
<tabstop>le_SetupCache</tabstop>
|
|
||||||
<tabstop>pb_LoadFromDisk</tabstop>
|
|
||||||
<tabstop>pb_Help</tabstop>
|
|
||||||
<tabstop>le_OtherSwiftVersions</tabstop>
|
|
||||||
<tabstop>pb_CopyFromSwift</tabstop>
|
|
||||||
<tabstop>pb_OpemDirectory</tabstop>
|
|
||||||
</tabstops>
|
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
|
|||||||
@@ -129,7 +129,6 @@ namespace BlackGui
|
|||||||
{
|
{
|
||||||
CGuiApplication::registerMetadata();
|
CGuiApplication::registerMetadata();
|
||||||
CApplication::init(false); // base class without metadata
|
CApplication::init(false); // base class without metadata
|
||||||
if (this->hasSetupReader()) { this->getSetupReader()->setCheckCmdLineBootstrapUrl(false); } // no connect checks on setup reader (handled with interactive setup loading)
|
|
||||||
CGuiApplication::adjustPalette();
|
CGuiApplication::adjustPalette();
|
||||||
this->setWindowIcon(icon);
|
this->setWindowIcon(icon);
|
||||||
this->settingsChanged();
|
this->settingsChanged();
|
||||||
@@ -138,9 +137,6 @@ namespace BlackGui
|
|||||||
|
|
||||||
connect(&m_styleSheetUtility, &CStyleSheetUtility::styleSheetsChanged, this, &CGuiApplication::onStyleSheetsChanged, Qt::QueuedConnection);
|
connect(&m_styleSheetUtility, &CStyleSheetUtility::styleSheetsChanged, this, &CGuiApplication::onStyleSheetsChanged, Qt::QueuedConnection);
|
||||||
connect(this, &CGuiApplication::startUpCompleted, this, &CGuiApplication::superviseWindowMinSizes, Qt::QueuedConnection);
|
connect(this, &CGuiApplication::startUpCompleted, this, &CGuiApplication::superviseWindowMinSizes, Qt::QueuedConnection);
|
||||||
|
|
||||||
// splash screen
|
|
||||||
connect(this->getSetupReader(), &CSetupReader::setupLoadingMessages, this, &CGuiApplication::displaySplashMessages, Qt::QueuedConnection);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1094,48 +1090,21 @@ namespace BlackGui
|
|||||||
m_minHeightChars = heightChars;
|
m_minHeightChars = heightChars;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGuiApplication::interactivelySynchronizeSetup(int timeoutMs)
|
void CGuiApplication::displaySetupLoadFailure(BlackMisc::CStatusMessageList msgs)
|
||||||
{
|
{
|
||||||
bool ok = false;
|
if (msgs.hasErrorMessages())
|
||||||
do
|
|
||||||
{
|
{
|
||||||
const CStatusMessageList msgs = this->synchronizeSetup(timeoutMs);
|
CSetupLoadingDialog dialog(msgs, BlackGui::CGuiApplication::mainApplicationWidget());
|
||||||
if (msgs.hasErrorMessages())
|
if (sGui)
|
||||||
{
|
{
|
||||||
CSetupLoadingDialog dialog(msgs, this->mainApplicationWidget());
|
static const QString style = sGui->getStyleSheetUtility().styles(
|
||||||
if (sGui)
|
{ CStyleSheetUtility::fileNameFonts(),
|
||||||
{
|
CStyleSheetUtility::fileNameStandardWidget() });
|
||||||
static const QString style = sGui->getStyleSheetUtility().styles(
|
dialog.setStyleSheet(style);
|
||||||
{ CStyleSheetUtility::fileNameFonts(),
|
}
|
||||||
CStyleSheetUtility::fileNameStandardWidget() });
|
|
||||||
dialog.setStyleSheet(style);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int r = dialog.exec();
|
dialog.exec();
|
||||||
if (r == QDialog::Rejected)
|
|
||||||
{
|
|
||||||
break; // exit with false state, as file was not loaded
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// run loop again and sync again
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// setup loaded
|
|
||||||
ok = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (!ok);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CGuiApplication::parseAndSynchronizeSetup(int timeoutMs)
|
|
||||||
{
|
|
||||||
if (!this->parseAndStartupCheck()) { return false; }
|
|
||||||
return this->interactivelySynchronizeSetup(timeoutMs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QDialog::DialogCode CGuiApplication::showCloseDialog(QMainWindow *mainWindow, QCloseEvent *closeEvent)
|
QDialog::DialogCode CGuiApplication::showCloseDialog(QMainWindow *mainWindow, QCloseEvent *closeEvent)
|
||||||
|
|||||||
@@ -217,13 +217,8 @@ namespace BlackGui
|
|||||||
//! \deprecated kept for experimental tests
|
//! \deprecated kept for experimental tests
|
||||||
void setMinimumSizeInCharacters(int widthChars, int heightChars);
|
void setMinimumSizeInCharacters(int widthChars, int heightChars);
|
||||||
|
|
||||||
//! Wait for setup, in case it fails display a dialog how to continue
|
//! \copydoc BlackCore::CApplication::displaySetupLoadFailure
|
||||||
bool interactivelySynchronizeSetup(int timeoutMs = BlackMisc::Network::CNetworkUtils::getLongTimeoutMs());
|
void displaySetupLoadFailure(BlackMisc::CStatusMessageList msgs) override;
|
||||||
|
|
||||||
//! Combined function
|
|
||||||
//! \see parseAndStartupCheck
|
|
||||||
//! \see interactivelySynchronizeSetup
|
|
||||||
virtual bool parseAndSynchronizeSetup(int timeoutMs = BlackMisc::Network::CNetworkUtils::getLongTimeoutMs()) override;
|
|
||||||
|
|
||||||
//! Show close dialog
|
//! Show close dialog
|
||||||
//! \remark will modify CApplication::saveSettingsOnShutdown
|
//! \remark will modify CApplication::saveSettingsOnShutdown
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ int main(int argc, char *argv[])
|
|||||||
a.addDBusAddressOption();
|
a.addDBusAddressOption();
|
||||||
a.addVatlibOptions();
|
a.addVatlibOptions();
|
||||||
a.addAudioOptions();
|
a.addAudioOptions();
|
||||||
if (!a.parseAndSynchronizeSetup()) { return EXIT_FAILURE; }
|
if (!a.parseAndLoadSetup()) { return EXIT_FAILURE; }
|
||||||
|
|
||||||
const QString dBusAdress(a.getCmdDBusAddressValue());
|
const QString dBusAdress(a.getCmdDBusAddressValue());
|
||||||
a.useContexts(CCoreFacadeConfig::forCoreAllLocalInDBus(dBusAdress));
|
a.useContexts(CCoreFacadeConfig::forCoreAllLocalInDBus(dBusAdress));
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ int main(int argc, char *argv[])
|
|||||||
CGuiApplication a(CApplicationInfo::swiftMappingTool(), CApplicationInfo::MappingTool, CIcons::swiftDatabase48());
|
CGuiApplication a(CApplicationInfo::swiftMappingTool(), CApplicationInfo::MappingTool, CIcons::swiftDatabase48());
|
||||||
a.setSignalStartupAutomatically(false); // application will signal startup on its own
|
a.setSignalStartupAutomatically(false); // application will signal startup on its own
|
||||||
a.splashScreen(CIcons::swiftDatabase256());
|
a.splashScreen(CIcons::swiftDatabase256());
|
||||||
if (!a.parseAndSynchronizeSetup()) { return EXIT_FAILURE; }
|
if (!a.parseAndLoadSetup()) { return EXIT_FAILURE; }
|
||||||
a.useWebDataServices(BlackCore::CWebReaderFlags::AllSwiftDbReaders, CDatabaseReaderConfigList::forMappingTool());
|
a.useWebDataServices(BlackCore::CWebReaderFlags::AllSwiftDbReaders, CDatabaseReaderConfigList::forMappingTool());
|
||||||
a.useFacadeNoContexts();
|
a.useFacadeNoContexts();
|
||||||
if (!a.start())
|
if (!a.start())
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ int main(int argc, char *argv[])
|
|||||||
a.setSignalStartupAutomatically(false); // application will signal startup on its own
|
a.setSignalStartupAutomatically(false); // application will signal startup on its own
|
||||||
a.splashScreen(CIcons::swift256());
|
a.splashScreen(CIcons::swift256());
|
||||||
a.setMinimumSizeInCharacters(60, 42); // experimental
|
a.setMinimumSizeInCharacters(60, 42); // experimental
|
||||||
if (!a.parseAndSynchronizeSetup()) { return EXIT_FAILURE; }
|
if (!a.parseAndLoadSetup()) { return EXIT_FAILURE; }
|
||||||
if (!a.hasSetupReader() || !a.start())
|
if (!a.hasSetupReader() || !a.start())
|
||||||
{
|
{
|
||||||
a.gracefulShutdown();
|
a.gracefulShutdown();
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ int main(int argc, char *argv[])
|
|||||||
CGuiApplication a(CApplicationInfo::swiftLauncher(), CApplicationInfo::Laucher, CIcons::swiftLauncher1024());
|
CGuiApplication a(CApplicationInfo::swiftLauncher(), CApplicationInfo::Laucher, CIcons::swiftLauncher1024());
|
||||||
a.addVatlibOptions(); // so it can be passed (hand over) to started applications
|
a.addVatlibOptions(); // so it can be passed (hand over) to started applications
|
||||||
a.addParserOption({ { "i", "installer" }, QCoreApplication::translate("main", "Installer setup.") });
|
a.addParserOption({ { "i", "installer" }, QCoreApplication::translate("main", "Installer setup.") });
|
||||||
if (!a.parseAndSynchronizeSetup()) { return EXIT_FAILURE; }
|
if (!a.parseAndLoadSetup()) { return EXIT_FAILURE; }
|
||||||
a.useWebDataServices(BlackCore::CWebReaderFlags::AllSwiftDbReaders, CDatabaseReaderConfigList::forLauncher());
|
a.useWebDataServices(BlackCore::CWebReaderFlags::AllSwiftDbReaders, CDatabaseReaderConfigList::forLauncher());
|
||||||
a.useFacadeNoContexts();
|
a.useFacadeNoContexts();
|
||||||
if (!a.start())
|
if (!a.start())
|
||||||
|
|||||||
@@ -129,11 +129,6 @@ void CSwiftLauncher::installerMode()
|
|||||||
const QDir dir = CSwiftDirectories::logDirectory();
|
const QDir dir = CSwiftDirectories::logDirectory();
|
||||||
if (!dir.exists()) { break; }
|
if (!dir.exists()) { break; }
|
||||||
|
|
||||||
if (sGui && sGui->getSetupReader())
|
|
||||||
{
|
|
||||||
sGui->getSetupReader()->prefillCacheWithLocalResourceBootstrapFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const CSimulatorInfo &sim : CSimulatorInfo::allSimulatorsSet())
|
for (const CSimulatorInfo &sim : CSimulatorInfo::allSimulatorsSet())
|
||||||
{
|
{
|
||||||
this->synchronizeCache(sim);
|
this->synchronizeCache(sim);
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ int main(int argc, char *argv[])
|
|||||||
BLACKTEST_INIT(BlackCoreTest::CTestContext)
|
BLACKTEST_INIT(BlackCoreTest::CTestContext)
|
||||||
CApplication a(CApplicationInfo::UnitTest);
|
CApplication a(CApplicationInfo::UnitTest);
|
||||||
a.addVatlibOptions();
|
a.addVatlibOptions();
|
||||||
const bool setup = a.parseAndSynchronizeSetup();
|
const bool setup = a.parseAndLoadSetup();
|
||||||
if (!setup) { qWarning() << "No setup loaded"; }
|
if (!setup) { qWarning() << "No setup loaded"; }
|
||||||
int r = EXIT_FAILURE;
|
int r = EXIT_FAILURE;
|
||||||
if (a.start())
|
if (a.start())
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ int main(int argc, char *argv[])
|
|||||||
BLACKTEST_INIT(BlackCoreTest::CTestConnectivity)
|
BLACKTEST_INIT(BlackCoreTest::CTestConnectivity)
|
||||||
CApplication a(CApplicationInfo::UnitTest);
|
CApplication a(CApplicationInfo::UnitTest);
|
||||||
a.addVatlibOptions();
|
a.addVatlibOptions();
|
||||||
const bool setup = a.parseAndSynchronizeSetup();
|
const bool setup = a.parseAndLoadSetup();
|
||||||
if (!setup) { qWarning() << "No setup loaded"; }
|
if (!setup) { qWarning() << "No setup loaded"; }
|
||||||
int r = EXIT_FAILURE;
|
int r = EXIT_FAILURE;
|
||||||
if (a.start())
|
if (a.start())
|
||||||
|
|||||||
Reference in New Issue
Block a user