diff --git a/src/blackconfig/buildconfig.cpp b/src/blackconfig/buildconfig.cpp index 28373f199..a13180e5d 100644 --- a/src/blackconfig/buildconfig.cpp +++ b/src/blackconfig/buildconfig.cpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace BlackConfig { @@ -236,6 +237,44 @@ namespace BlackConfig } return 0; // intentionally 0 => 0.7.3.0 <- } + + const QStringList &CBuildConfig::getBuildAbiParts() + { + static const QStringList parts = QSysInfo::buildAbi().split('-'); + return parts; + } + + int buildWordSizeImpl() + { + if (CBuildConfig::getBuildAbiParts().length() < 3) { return -1; } + const QString abiWs = CBuildConfig::getBuildAbiParts()[2]; + if (abiWs.contains("32")) { return 32; } + if (abiWs.contains("64")) { return 64; } + return -1; + } + + int CBuildConfig::buildWordSize() + { + static const int bws = buildWordSizeImpl(); + return bws; + } + + QString CBuildConfig::guessMyPlatformString() + { + // 32/64 only matters on Windows + // 64 is default + QString p; + QString ws = (buildWordSize() == 32) ? "32" : "64"; + if (BlackConfig::CBuildConfig::isRunningOnWindowsNtPlatform()) + { + p = "win-" + ws; + } + else if (BlackConfig::CBuildConfig::isRunningOnMacOSXPlatform()) { p = "macos-64"; } + else if (BlackConfig::CBuildConfig::isRunningOnLinuxPlatform()) { p = "linux-64"; } + + if (!p.isEmpty() && BlackConfig::CBuildConfig::isVatsimVersion()) { p += "-vatsim"; } + return p; + } } // ns //! \endcond diff --git a/src/blackconfig/buildconfig.h b/src/blackconfig/buildconfig.h index 6acb2a1d1..d1c37efb7 100644 --- a/src/blackconfig/buildconfig.h +++ b/src/blackconfig/buildconfig.h @@ -137,6 +137,17 @@ namespace BlackConfig //! Turns build timestamp into a version number static int buildTimestampAsVersionSegment(const QDateTime &buildTimestamp); + //! Build ABI parts as in http://doc.qt.io/qt-5/qsysinfo.html#buildAbi + static const QStringList &getBuildAbiParts(); + + //! Whether this swift application is build as 32 or 64bit application + //! \returns 32, 64 or -1 (in case no info is possible) + static int buildWordSize(); + + //! The platform string used for updates etc. + //! \remark ideally no such guess would be needed, but it is used as default value + static QString guessMyPlatformString(); + private: //! Major version static int versionMajor(); // defined in buildconfig_gen.cpp.in diff --git a/src/blackcore/setupreader.h b/src/blackcore/setupreader.h index 9a51b61cd..e6ec3a3af 100644 --- a/src/blackcore/setupreader.h +++ b/src/blackcore/setupreader.h @@ -176,8 +176,8 @@ namespace BlackCore QString m_lastSuccessfulSetupUrl; //!< last successful read setup URL QString m_lastSuccessfulDistributionUrl; //!< last successful read distribution URL BlackMisc::CStatusMessageList m_setupReadErrorMsgs; //!< last parsing error messages - BlackMisc::CData m_setup {this, &CSetupReader::ps_setupChanged}; //!< data cache setup - BlackMisc::CData m_distributions {this}; //!< data cache distributions + BlackMisc::CData m_setup {this, &CSetupReader::ps_setupChanged}; //!< data cache setup + BlackMisc::CData m_distributions {this}; //!< data cache distributions //! Read by local individual file and update cache from that BlackMisc::CStatusMessageList readLocalBootstrapFile(const QString &fileName); diff --git a/src/blackmisc/db/distribution.cpp b/src/blackmisc/db/distribution.cpp index 0565973f4..f89d3b944 100644 --- a/src/blackmisc/db/distribution.cpp +++ b/src/blackmisc/db/distribution.cpp @@ -38,7 +38,13 @@ namespace BlackMisc return platforms; } - QString CDistribution::guessPlatform() const + bool CDistribution::supportsPlatform(const QString &platform) const + { + QStringList platforms = m_platformFiles.keys(); + return !platform.isEmpty() && platforms.contains(platform); + } + + QString CDistribution::guessMyPlatform() const { const QStringList platforms(getPlatforms()); if (platforms.isEmpty()) { return ""; } @@ -55,7 +61,7 @@ namespace BlackMisc } else if (CBuildConfig::isRunningOnMacOSXPlatform()) { - if (!p.contains("mac", Qt::CaseInsensitive) || !p.contains("osx", Qt::CaseInsensitive)) continue; + if (!(p.contains("mac", Qt::CaseInsensitive) || p.contains("osx", Qt::CaseInsensitive))) continue; } reduced << p; } @@ -78,6 +84,20 @@ namespace BlackMisc if (!furtherReduced.isEmpty()) { reduced = furtherReduced; } } + int wordSize = CBuildConfig::buildWordSize(); + if (wordSize >= 32 && reduced.size() > 1) + { + // further reduce by word size 32/64 + QStringList furtherReduced; + const QString wsString = QString::number(wordSize); + for (const QString &p : as_const(reduced)) + { + if (!p.contains(wsString)) { continue; } + furtherReduced << p; + } + if (!furtherReduced.isEmpty()) { reduced = furtherReduced; } + } + if (reduced.isEmpty()) { return ""; } return reduced.front(); } @@ -102,12 +122,12 @@ namespace BlackMisc void CDistribution::addDownloadUrl(const CUrl &url) { if (url.isEmpty()) { return; } - this->m_downloadUrls.push_back(url); + m_downloadUrls.push_back(url); } bool CDistribution::hasDownloadUrls() const { - return !this->m_downloadUrls.isEmpty(); + return !m_downloadUrls.isEmpty(); } QString CDistribution::convertToQString(bool i18n) const @@ -138,18 +158,12 @@ namespace BlackMisc const ColumnIndex i = index.frontCasted(); switch (i) { - case IndexChannel: - return CVariant::fromValue(this->m_channel); - case IndexDownloadUrls: - return CVariant::fromValue(this->m_downloadUrls); - case IndexRestricted: - return CVariant::fromValue(this->m_restricted); - case IndexPlatforms: - return CVariant::fromValue(this->getPlatforms()); - case IndexPlatformFiles: - return CVariant::fromValue(this->m_platformFiles); - default: - return CValueObject::propertyByIndex(index); + case IndexChannel: return CVariant::fromValue(m_channel); + case IndexDownloadUrls: return CVariant::fromValue(m_downloadUrls); + case IndexRestricted: return CVariant::fromValue(m_restricted); + case IndexPlatforms: return CVariant::fromValue(this->getPlatforms()); + case IndexPlatformFiles: return CVariant::fromValue(m_platformFiles); + default: return CValueObject::propertyByIndex(index); } } @@ -165,21 +179,11 @@ namespace BlackMisc const ColumnIndex i = index.frontCasted(); switch (i) { - case IndexChannel: - this->setChannel(variant.value()); - break; - case IndexDownloadUrls: - this->m_downloadUrls = variant.value(); - break; - case IndexRestricted: - this->m_restricted = variant.toBool(); - break; - case IndexPlatformFiles: - this->m_platformFiles = variant.value(); - break; - default: - CValueObject::setPropertyByIndex(index, variant); - break; + case IndexChannel: this->setChannel(variant.value()); break; + case IndexDownloadUrls: m_downloadUrls = variant.value(); break; + case IndexRestricted: m_restricted = variant.toBool(); break; + case IndexPlatformFiles: m_platformFiles = variant.value(); break; + default: CValueObject::setPropertyByIndex(index, variant); break; } } diff --git a/src/blackmisc/db/distribution.h b/src/blackmisc/db/distribution.h index cc65a1cbe..e8f4d0a9f 100644 --- a/src/blackmisc/db/distribution.h +++ b/src/blackmisc/db/distribution.h @@ -32,7 +32,7 @@ namespace BlackMisc //! Dictionary for files per platform using CPlatformDictionary = BlackMisc::CDictionary; - //! CDistribution for channel + //! Distributions for channel class BLACKMISC_EXPORT CDistribution : public BlackMisc::CValueObject, public BlackMisc::Db::IDatastoreObjectWithIntegerKey @@ -66,8 +66,11 @@ namespace BlackMisc //! Get platforms QStringList getPlatforms() const; - //! Guess platform - QString guessPlatform() const; + //! Supports platform? + bool supportsPlatform(const QString &platform) const; + + //! Guess platform for this distribution channel and this version of swift + QString guessMyPlatform() const; //! Version for platform QString getVersionString(const QString &platform) const; @@ -106,7 +109,7 @@ namespace BlackMisc static CDistribution fromDatabaseJson(const QJsonObject &json, const QString &prefix = {}); private: - QString m_channel; //!< for development + QString m_channel; //!< channel the files belong to bool m_restricted = false; //!< restricted access (i.e. password for download needed) BlackMisc::Network::CUrlList m_downloadUrls; //!< download URLs, here I get the installer CPlatformDictionary m_platformFiles; //!< the latest file version per platform @@ -128,7 +131,6 @@ namespace BlackMisc BLACK_METAMEMBER(platformVersions, 0, DisabledForComparison | DisabledForHashing) ); }; - //! Distribution settings: channel/platform struct TDistributionSetting : public BlackMisc::TSettingTrait { diff --git a/src/blackmisc/db/distributionlist.cpp b/src/blackmisc/db/distributionlist.cpp index 56cd5ef31..f36f174fc 100644 --- a/src/blackmisc/db/distributionlist.cpp +++ b/src/blackmisc/db/distributionlist.cpp @@ -20,9 +20,9 @@ namespace BlackMisc CSequence(other) { } - QStringList CDistributionList::getChannels() const + QSet CDistributionList::getChannels() const { - QStringList channels; + QSet channels; for (const CDistribution &distribution : *this) { if (distribution.getChannel().isEmpty()) { continue; } @@ -31,6 +31,32 @@ namespace BlackMisc return channels; } + QSet CDistributionList::findChannelsForPlatform(const QString &platform) const + { + QSet channels; + if (platform.isEmpty()) { return channels; } + for (const CDistribution &distribution : *this) + { + if (distribution.getChannel().isEmpty()) { continue; } + if (distribution.supportsPlatform(platform)) + { + channels.insert(distribution.getChannel()); + } + } + return channels; + } + + QSet CDistributionList::getPlatforms() const + { + QSet platforms; + for (const CDistribution &distribution : *this) + { + if (distribution.getChannel().isEmpty()) { continue; } + platforms << distribution.getChannel(); + } + return platforms; + } + CDistribution CDistributionList::findByChannelOrDefault(const QString &channel) const { return this->findFirstByOrDefault(&CDistribution::getChannel, channel); @@ -60,6 +86,12 @@ namespace BlackMisc return this->getQVersionForChannelAndPlatform(channelPlatform.first(), channelPlatform.last()); } + QStringList CDistributionList::guessMyDefaultChannelAndPlatform() const + { + //! \fixme will be further improved when we have added a public server and have more channels + return QStringList({"ALPHA", BlackConfig::CBuildConfig::guessMyPlatformString()}); // guessing + } + CDistributionList CDistributionList::fromDatabaseJson(const QJsonArray &array) { CDistributionList distributions; diff --git a/src/blackmisc/db/distributionlist.h b/src/blackmisc/db/distributionlist.h index e9392e000..d6ce4f5c6 100644 --- a/src/blackmisc/db/distributionlist.h +++ b/src/blackmisc/db/distributionlist.h @@ -19,12 +19,16 @@ #include "blackmisc/collection.h" #include "blackmisc/sequence.h" #include "blackmisc/variant.h" +#include +#include namespace BlackMisc { namespace Db { - //! Value object encapsulating a list of aircraft models + //! Multiple distributions for different channels: + //! - one CDistribution objects contains all versions for a channel + //! - a distribution list normally contains all distributions for all channels class BLACKMISC_EXPORT CDistributionList : public BlackMisc::CSequence, public BlackMisc::Db::IDatastoreObjectList, @@ -40,7 +44,13 @@ namespace BlackMisc CDistributionList(const CSequence &other); //! All channels - QStringList getChannels() const; + QSet getChannels() const; + + //! Find channels for platform + QSet findChannelsForPlatform(const QString &platform) const; + + //! All platforms for all channels + QSet getPlatforms() const; //! Find distribution by channels CDistribution findByChannelOrDefault(const QString &channel) const; @@ -57,15 +67,18 @@ namespace BlackMisc //! Version for specific channel and platform QVersionNumber getQVersionForChannelAndPlatform(const QStringList &channelPlatform) const; - //! From database JSON + //! Guess the best channel/platform + QStringList guessMyDefaultChannelAndPlatform() const; + + //! From database JSON by array static CDistributionList fromDatabaseJson(const QJsonArray &array); - //! From database JSON + //! From database JSON by string static CDistributionList fromDatabaseJson(const QString &json); }; - //! Trait for global setup data - struct TDistributionInfo : public BlackMisc::TDataTrait + //! Trait for distributions + struct TDistributionsInfo : public BlackMisc::TDataTrait { //! Key in data cache static const char *key() { return "distributions"; }