diff --git a/src/blackmisc/network/client.cpp b/src/blackmisc/network/client.cpp index 934d8c697..bf02d77e7 100644 --- a/src/blackmisc/network/client.cpp +++ b/src/blackmisc/network/client.cpp @@ -38,37 +38,53 @@ namespace BlackMisc return m_user.hasCallsign(); } - void CClient::setCapability(bool hasCapability, CClient::Capabilities capability) + void CClient::addCapability(CClient::Capability capability) { - m_capabilities.addValue(static_cast(capability), hasCapability); + Capabilities cap = this->getCapabilities(); + cap |= capability; + this->setCapabilities(cap); } - void CClient::setCapabilities(const CPropertyIndexVariantMap &capabilities) + void CClient::removeCapability(CClient::Capability capability) { - m_capabilities = capabilities; + Capabilities cap = this->getCapabilities(); + cap &= ~capability; + this->setCapabilities(cap); + + } + + void CClient::setCapabilities(const Capabilities &capabilities) + { + m_capabilities = static_cast(capabilities); } QString CClient::getCapabilitiesAsString() const { + const Capabilities cap = this->getCapabilities(); QStringList sl; - if (this->hasCapability(FsdAtisCanBeReceived)) sl << "ATIS"; - if (this->hasCapability(FsdWithInterimPositions)) sl << "interim pos."; - if (this->hasCapability(FsdWithIcaoCodes)) sl << "ICAO"; - if (this->hasCapability(FsdWithAircraftConfig)) sl << "aircraft config"; - if (sl.isEmpty()) return ""; + if (cap.testFlag(FsdAtisCanBeReceived)) sl << "ATIS"; + if (cap.testFlag(FsdWithInterimPositions)) sl << "interim pos."; + if (cap.testFlag(FsdWithIcaoCodes)) sl << "ICAO"; + if (cap.testFlag(FsdWithAircraftConfig)) sl << "aircraft config"; + if (cap.testFlag(FsdWithGroundFlag)) sl << "gnd.flag"; + if (cap.testFlag(FsdModelString)) sl << "modelstring"; + if (sl.isEmpty()) { return QStringLiteral(""); } return sl.join(", "); } - bool CClient::hasCapability(CClient::Capabilities capability) const + bool CClient::hasCapability(Capability capability) const { - if (m_capabilities.contains(capability)) - { - return m_capabilities.value(capability).toBool(); - } - else - { - return false; - } + return this->getCapabilities().testFlag(capability); + } + + bool CClient::hasAircraftPartsCapability() const + { + return this->hasCapability(FsdWithAircraftConfig); + } + + bool CClient::hasGndFlagCapability() const + { + return this->hasCapability(FsdWithGroundFlag); } void CClient::setUserCallsign(const Aviation::CCallsign &callsign) @@ -76,34 +92,29 @@ namespace BlackMisc m_user.setCallsign(callsign); } + void CClient::setQueriedModelString(const QString &modelString) + { + m_modelString = modelString.trimmed(); + if (!modelString.isEmpty()) { this->addCapability(CClient::FsdModelString); } + } + CVariant CClient::propertyByIndex(const CPropertyIndex &index) const { if (index.isMyself()) { return CVariant::from(*this); } const ColumnIndex i = index.frontCasted(); switch (i) { - case IndexCapabilities: - return CVariant::fromValue(m_capabilities); - case IndexCapabilitiesString: - return CVariant(this->getCapabilitiesAsString()); - case IndexCallsign: - return this->getCallsign().propertyByIndex(index.copyFrontRemoved()); - case IndexUser: - return this->getUser().propertyByIndex(index.copyFrontRemoved()); - case IndexModelString: - return CVariant(m_modelString); - case IndexServer: - return CVariant(m_server); - case IndexVoiceCapabilities: - return m_voiceCapabilities.propertyByIndex(index.copyFrontRemoved()); - case IndexVoiceCapabilitiesPixmap: - return CVariant::from(m_voiceCapabilities.toPixmap()); - case IndexVoiceCapabilitiesIcon: - return CVariant::fromValue(m_voiceCapabilities.toIcon()); - case IndexVoiceCapabilitiesString: - return CVariant(m_voiceCapabilities.toQString(true)); - default: - return CValueObject::propertyByIndex(index); + case IndexCapabilities: return CVariant::fromValue(m_capabilities); + case IndexCapabilitiesString: return CVariant(this->getCapabilitiesAsString()); + case IndexCallsign: return this->getCallsign().propertyByIndex(index.copyFrontRemoved()); + case IndexUser: return this->getUser().propertyByIndex(index.copyFrontRemoved()); + case IndexModelString: return CVariant(m_modelString); + case IndexServer: return CVariant(m_server); + case IndexVoiceCapabilities: return m_voiceCapabilities.propertyByIndex(index.copyFrontRemoved()); + case IndexVoiceCapabilitiesPixmap: return CVariant::from(m_voiceCapabilities.toPixmap()); + case IndexVoiceCapabilitiesIcon: return CVariant::fromValue(m_voiceCapabilities.toIcon()); + case IndexVoiceCapabilitiesString: return CVariant(m_voiceCapabilities.toQString(true)); + default: return CValueObject::propertyByIndex(index); } } @@ -113,27 +124,13 @@ namespace BlackMisc const ColumnIndex i = index.frontCasted(); switch (i) { - case IndexCapabilities: - m_capabilities = variant.value(); - break; - case IndexModelString: - m_modelString = variant.toQString(); - break; - case IndexServer: - m_server = variant.toQString(); - break; - case IndexUser: - m_user.setPropertyByIndex(index.copyFrontRemoved(), variant); - break; - case IndexCallsign: - m_user.setCallsign(variant.value()); - break; - case IndexVoiceCapabilities: - m_voiceCapabilities.setPropertyByIndex(index.copyFrontRemoved(), variant); - break; - default: - CValueObject::setPropertyByIndex(index, variant); - break; + case IndexCapabilities: m_capabilities = variant.toInt(); break; + case IndexModelString: m_modelString = variant.toQString(); break; + case IndexServer: m_server = variant.toQString(); break; + case IndexUser: m_user.setPropertyByIndex(index.copyFrontRemoved(), variant); break; + case IndexCallsign: m_user.setCallsign(variant.value()); break; + case IndexVoiceCapabilities: m_voiceCapabilities.setPropertyByIndex(index.copyFrontRemoved(), variant); break; + default: CValueObject::setPropertyByIndex(index, variant); break; } } } // namespace diff --git a/src/blackmisc/network/client.h b/src/blackmisc/network/client.h index 4c07af47e..a9195651c 100644 --- a/src/blackmisc/network/client.h +++ b/src/blackmisc/network/client.h @@ -12,18 +12,16 @@ #ifndef BLACKMISC_NETWORK_CLIENT_H #define BLACKMISC_NETWORK_CLIENT_H +#include "user.h" +#include "voicecapabilities.h" +#include "blackmisc/simulation/aircraftmodel.h" #include "blackmisc/aviation/callsign.h" #include "blackmisc/blackmiscexport.h" #include "blackmisc/icon.h" #include "blackmisc/metaclass.h" -#include "blackmisc/network/user.h" -#include "blackmisc/network/voicecapabilities.h" #include "blackmisc/propertyindex.h" -#include "blackmisc/propertyindexvariantmap.h" -#include "blackmisc/simulation/aircraftmodel.h" #include "blackmisc/valueobject.h" #include "blackmisc/variant.h" - #include #include @@ -51,25 +49,29 @@ namespace BlackMisc }; //! The Capabilities enum - enum Capabilities + enum Capability { - FsdWithInterimPositions = CPropertyIndex::GlobalIndexClientCapabilities, //!< interim positions - FsdWithIcaoCodes, //!< basically means it is a pilot client handling ICAO code pacakages - FsdAtisCanBeReceived, //!< ATIS - FsdWithAircraftConfig //!< Aircraft parts + None = 0, + FsdWithInterimPositions = 1 << 0, + FsdWithIcaoCodes = 1 << 1, //!< basically means it is a pilot client handling ICAO code packages + FsdAtisCanBeReceived = 1 << 2, //!< ATIS + FsdWithAircraftConfig = 1 << 3, //!< Aircraft parts + FsdWithGroundFlag = 1 << 4, //!< supports gnd. flag (in position) + FsdModelString = 1 << 5 }; + Q_DECLARE_FLAGS(Capabilities, Capability) //! Default constructor. CClient() = default; //! Construct by callsign and optional model string - CClient(const BlackMisc::Aviation::CCallsign &callsign, const QString &modelString = {}); + CClient(const Aviation::CCallsign &callsign, const QString &modelString = {}); //! Constructor. CClient(const CUser &user) : m_user(user) {} //! Callsign used with other client - const BlackMisc::Aviation::CCallsign &getCallsign() const { return m_user.getCallsign(); } + const Aviation::CCallsign &getCallsign() const { return m_user.getCallsign(); } //! ATC client bool isAtc() const { return getCallsign().isAtcAlikeCallsign(); } @@ -78,19 +80,28 @@ namespace BlackMisc bool isValid() const; //! Get capabilities - CPropertyIndexVariantMap getCapabilities() const { return m_capabilities; } - - //! Set capability - void setCapability(bool hasCapability, Capabilities capability); + Capabilities getCapabilities() const { return static_cast(m_capabilities); } //! Set capabilities - void setCapabilities(const CPropertyIndexVariantMap &capabilities); + void setCapabilities(const Capabilities &capabilities); //! Get capabilities QString getCapabilitiesAsString() const; //! Has capability? - bool hasCapability(Capabilities capability) const; + bool hasCapability(Capability capability) const; + + //! Supports aircraft parts? + bool hasAircraftPartsCapability() const; + + //! Supports gnd.flag? + bool hasGndFlagCapability() const; + + //! Add capability + void addCapability(Capability capability); + + //! Remove capability + void removeCapability(Capability capability); //! Get voice capabilities const CVoiceCapabilities &getVoiceCapabilities() const { return m_voiceCapabilities;} @@ -126,7 +137,7 @@ namespace BlackMisc bool hasQueriedModelString() const { return !m_modelString.isEmpty(); } //! Set model - void setQueriedModelString(const QString &modelString) { m_modelString = modelString.trimmed(); } + void setQueriedModelString(const QString &modelString); //! \copydoc BlackMisc::Mixin::Icon::toIcon() CIcon toIcon() const { return m_user.toIcon(); } @@ -142,7 +153,7 @@ namespace BlackMisc private: CUser m_user; - CPropertyIndexVariantMap m_capabilities; + int m_capabilities = static_cast(None); QString m_modelString; QString m_server; CVoiceCapabilities m_voiceCapabilities; @@ -151,7 +162,7 @@ namespace BlackMisc CClient, BLACK_METAMEMBER(user), BLACK_METAMEMBER(modelString), - BLACK_METAMEMBER(capabilities, 0, DisabledForComparison | DisabledForJson), + BLACK_METAMEMBER(capabilities), BLACK_METAMEMBER(server), BLACK_METAMEMBER(voiceCapabilities) ); diff --git a/src/blackmisc/network/clientlist.cpp b/src/blackmisc/network/clientlist.cpp index 57da5ef13..8164e30ac 100644 --- a/src/blackmisc/network/clientlist.cpp +++ b/src/blackmisc/network/clientlist.cpp @@ -17,5 +17,16 @@ namespace BlackMisc CClientList::CClientList(const CSequence &other) : CSequence(other) { } + + bool CClientList::hasCapability(const Aviation::CCallsign &callsign, CClient::Capability capability) const + { + return this->getCapabilities(callsign).testFlag(capability); + } + + CClient::Capabilities CClientList::getCapabilities(const Aviation::CCallsign &callsign) const + { + if (this->isEmpty()) { return static_cast(CClient::None); } + return this->findFirstByCallsign(callsign).getCapabilities(); + } } // namespace } // namespace diff --git a/src/blackmisc/network/clientlist.h b/src/blackmisc/network/clientlist.h index fb6f77d88..4fa4960b3 100644 --- a/src/blackmisc/network/clientlist.h +++ b/src/blackmisc/network/clientlist.h @@ -27,8 +27,8 @@ namespace BlackMisc //! Value object encapsulating a list of voice rooms. class BLACKMISC_EXPORT CClientList : public CSequence, - public BlackMisc::Aviation::ICallsignObjectList, - public BlackMisc::Mixin::MetaType + public Aviation::ICallsignObjectList, + public Mixin::MetaType { public: BLACKMISC_DECLARE_USING_MIXIN_METATYPE(CClientList) @@ -38,6 +38,12 @@ namespace BlackMisc //! Construct from a base class object. CClientList(const CSequence &other); + + //! Has client for callsign the given capability? + bool hasCapability(const Aviation::CCallsign &callsign, CClient::Capability capability) const; + + //! Capabilities of client for callsign + CClient::Capabilities getCapabilities(const Aviation::CCallsign &callsign) const; }; } //namespace } // namespace diff --git a/src/blackmisc/propertyindex.h b/src/blackmisc/propertyindex.h index 9353c7322..1a0aaa5af 100644 --- a/src/blackmisc/propertyindex.h +++ b/src/blackmisc/propertyindex.h @@ -115,15 +115,14 @@ namespace BlackMisc GlobalIndexCCoordinateGeodetic = 5200, GlobalIndexCElevationPlane = 5300, GlobalIndexCClient = 6000, - GlobalIndexClientCapabilities = 6100, //!< used with map key - GlobalIndexCUser = 6200, - GlobalIndexCAuthenticatedUser = 6300, - GlobalIndexCRole = 6400, - GlobalIndexCServer = 6500, - GlobalIndexCFsdSetup = 6600, - GlobalIndexCUrl = 6700, - GlobalIndexCUrlLog = 6800, - GlobalIndexCRemoteFile = 6900, + GlobalIndexCUser = 6100, + GlobalIndexCAuthenticatedUser = 6200, + GlobalIndexCRole = 6300, + GlobalIndexCServer = 6400, + GlobalIndexCFsdSetup = 6500, + GlobalIndexCUrl = 6600, + GlobalIndexCUrlLog = 6700, + GlobalIndexCRemoteFile = 6800, GlobalIndexCEcosystem = 7000, GlobalIndexCRawFsdMessage = 7100, GlobalIndexCAircraftModel = 8000, diff --git a/src/blackmisc/test/testing.cpp b/src/blackmisc/test/testing.cpp index 7d94124cb..626b82445 100644 --- a/src/blackmisc/test/testing.cpp +++ b/src/blackmisc/test/testing.cpp @@ -119,16 +119,16 @@ namespace BlackMisc CClientList CTesting::getClients(int number) { - BlackMisc::Network::CClientList list; + CClientList list; for (int i = 0; i < number; i++) { - CCallsign cs(QString("DXX%1").arg(i)); - QString rn = QString("Joe Doe%1").arg(i); + const CCallsign cs(QString("DXX%1").arg(i)); + const QString rn = QString("Joe Doe%1").arg(i); CUser user(QString::number(i), rn, cs); user.setCallsign(cs); CClient client(user); - client.setCapability(true, CClient::FsdWithInterimPositions); - client.setCapability(true, CClient::FsdWithIcaoCodes); + client.addCapability(CClient::FsdWithInterimPositions); + client.addCapability(CClient::FsdWithIcaoCodes); const QString myFooModel = QString("fooModel %1").arg(i); client.setQueriedModelString(myFooModel); list.push_back(client);