diff --git a/samples/cli_client/client.cpp b/samples/cli_client/client.cpp index d4a427ebf..5f2cd67d1 100644 --- a/samples/cli_client/client.cpp +++ b/samples/cli_client/client.cpp @@ -15,23 +15,24 @@ Client::Client(BlackMisc::IContext &ctx) connect(m_net, &INetwork::atcPositionUpdate, this, &Client::atcPositionUpdate); connect(m_net, &INetwork::atcDisconnected, this, &Client::atcDisconnected); connect(m_net, &INetwork::connectionStatusChanged, this, &Client::connectionStatusChanged); - connect(m_net, &INetwork::ipQueryReplyReceived, this, &Client::ipQueryReplyReceived); - connect(m_net, &INetwork::frequencyQueryReplyReceived, this, &Client::freqQueryReplyReceived); - connect(m_net, &INetwork::serverQueryReplyReceived, this, &Client::serverQueryReplyReceived); - connect(m_net, &INetwork::atcQueryReplyReceived, this, &Client::atcQueryReplyReceived); - connect(m_net, &INetwork::atisQueryReplyReceived, this, &Client::atisQueryReplyReceived); - connect(m_net, &INetwork::nameQueryReplyReceived, this, &Client::nameQueryReplyReceived); - connect(m_net, &INetwork::capabilitiesQueryReplyReceived, this, &Client::capabilitiesQueryReplyReceived); + connect(m_net, &INetwork::ipReplyReceived, this, &Client::ipReplyReceived); + connect(m_net, &INetwork::frequencyReplyReceived, this, &Client::freqReplyReceived); + connect(m_net, &INetwork::serverReplyReceived, this, &Client::serverReplyReceived); + connect(m_net, &INetwork::atcReplyReceived, this, &Client::atcReplyReceived); + connect(m_net, &INetwork::atisReplyReceived, this, &Client::atisReplyReceived); + connect(m_net, &INetwork::realNameReplyReceived, this, &Client::realNameReplyReceived); + connect(m_net, &INetwork::capabilitiesReplyReceived, this, &Client::capabilitiesReplyReceived); connect(m_net, &INetwork::kicked, this, &Client::kicked); - connect(m_net, &INetwork::metarReceived, this, &Client::metarReceived); + connect(m_net, &INetwork::metarReplyReceived, this, &Client::metarReplyReceived); connect(m_net, &INetwork::pilotDisconnected, this, &Client::pilotDisconnected); - connect(m_net, &INetwork::aircraftInfoReceived, this, &Client::aircraftInfoReceived); - connect(m_net, &INetwork::pong, this, &Client::pong); + connect(m_net, &INetwork::icaoCodesReplyReceived, this, &Client::icaoCodesReplyReceived); + connect(m_net, &INetwork::pongReceived, this, &Client::pongReceived); connect(m_net, &INetwork::textMessagesReceived, this, &Client::textMessagesReceived); - connect(this, &Client::setServer, m_net, &INetwork::setServer); - connect(this, &Client::setCallsign, m_net, &INetwork::setCallsign); - connect(this, &Client::setRealName, m_net, &INetwork::setRealName); + connect(this, &Client::presetServer, m_net, &INetwork::presetServer); + connect(this, &Client::presetCallsign, m_net, &INetwork::presetCallsign); + connect(this, &Client::presetIcaoCodes, m_net, &INetwork::presetIcaoCodes); + connect(this, &Client::presetLoginMode, m_net, &INetwork::presetLoginMode); connect(this, &Client::initiateConnection, m_net, &INetwork::initiateConnection); connect(this, &Client::terminateConnection, m_net, &INetwork::terminateConnection); connect(this, &Client::sendTextMessages, m_net, &INetwork::sendTextMessages); @@ -40,24 +41,25 @@ Client::Client(BlackMisc::IContext &ctx) connect(this, &Client::sendServerQuery, m_net, &INetwork::sendServerQuery); connect(this, &Client::sendAtcQuery, m_net, &INetwork::sendAtcQuery); connect(this, &Client::sendAtisQuery, m_net, &INetwork::sendAtisQuery); - connect(this, &Client::sendNameQuery, m_net, &INetwork::sendNameQuery); + connect(this, &Client::sendRealNameQuery, m_net, &INetwork::sendRealNameQuery); connect(this, &Client::sendCapabilitiesQuery, m_net, &INetwork::sendCapabilitiesQuery); - connect(this, &Client::requestPlaneInfo, m_net, &INetwork::requestAircraftInfo); + connect(this, &Client::sendIcaoCodesQuery, m_net, &INetwork::sendIcaoCodesQuery); connect(this, &Client::setOwnAircraft, m_net, &INetwork::setOwnAircraft); connect(this, &Client::setOwnAircraftPosition, m_net, &INetwork::setOwnAircraftPosition); connect(this, &Client::setOwnAircraftSituation, m_net, &INetwork::setOwnAircraftSituation); connect(this, &Client::setOwnAircraftAvionics, m_net, &INetwork::setOwnAircraftAvionics); - connect(this, &Client::ping, m_net, &INetwork::ping); - connect(this, &Client::requestMetar, m_net, &INetwork::requestMetar); - connect(this, &Client::requestWeatherData, m_net, &INetwork::requestWeatherData); + connect(this, &Client::sendPing, m_net, &INetwork::sendPing); + connect(this, &Client::sendMetarQuery, m_net, &INetwork::sendMetarQuery); + connect(this, &Client::sendWeatherDataQuery, m_net, &INetwork::sendWeatherDataQuery); using namespace std::placeholders; m_commands["help"] = std::bind(&Client::help, this, _1); m_commands["echo"] = std::bind(&Client::echo, this, _1); m_commands["exit"] = std::bind(&Client::exit, this, _1); - m_commands["setserver"] = std::bind(&Client::setServerCmd, this, _1); - m_commands["setcallsign"] = std::bind(&Client::setCallsignCmd, this, _1); - m_commands["setrealname"] = std::bind(&Client::setRealNameCmd, this, _1); + m_commands["setserver"] = std::bind(&Client::presetServerCmd, this, _1); + m_commands["setcallsign"] = std::bind(&Client::presetCallsignCmd, this, _1); + m_commands["icaocodes"] = std::bind(&Client::presetIcaoCodesCmd, this, _1); + m_commands["loginmode"] = std::bind(&Client::presetLoginModeCmd, this, _1); m_commands["initconnect"] = std::bind(&Client::initiateConnectionCmd, this, _1); m_commands["termconnect"] = std::bind(&Client::terminateConnectionCmd, this, _1); m_commands["privmsg"] = std::bind(&Client::sendPrivateTextMessageCmd, this, _1); @@ -67,16 +69,16 @@ Client::Client(BlackMisc::IContext &ctx) m_commands["server"] = std::bind(&Client::sendServerQueryCmd, this, _1); m_commands["atc"] = std::bind(&Client::sendAtcQueryCmd, this, _1); m_commands["atis"] = std::bind(&Client::sendAtisQueryCmd, this, _1); - m_commands["name"] = std::bind(&Client::sendNameQueryCmd, this, _1); + m_commands["name"] = std::bind(&Client::sendRealNameQueryCmd, this, _1); m_commands["caps"] = std::bind(&Client::sendCapabilitiesQueryCmd, this, _1); - m_commands["aircraftinfo"] = std::bind(&Client::requestAircraftInfoCmd, this, _1); + m_commands["icao"] = std::bind(&Client::sendIcaoCodesQueryCmd, this, _1); m_commands["setaircraft"] = std::bind(&Client::setOwnAircraftCmd, this, _1); m_commands["setposition"] = std::bind(&Client::setOwnAircraftPositionCmd, this, _1); m_commands["setsituation"] = std::bind(&Client::setOwnAircraftSituationCmd, this, _1); m_commands["setavionics"] = std::bind(&Client::setOwnAircraftAvionicsCmd, this, _1); - m_commands["ping"] = std::bind(&Client::pingCmd, this, _1); - m_commands["metar"] = std::bind(&Client::requestMetarCmd, this, _1); - m_commands["weather"] = std::bind(&Client::requestWeatherDataCmd, this, _1); + m_commands["ping"] = std::bind(&Client::sendPingCmd, this, _1); + m_commands["metar"] = std::bind(&Client::sendMetarQueryCmd, this, _1); + m_commands["weather"] = std::bind(&Client::sendWeatherDataQueryCmd, this, _1); } void Client::command(QString line) @@ -121,26 +123,44 @@ void Client::exit(QTextStream &) emit quit(); } -void Client::setServerCmd(QTextStream &args) +void Client::presetServerCmd(QTextStream &args) { QString hostname; quint16 port; QString username; QString password; args >> hostname >> port >> username >> password; - emit setServer(BlackMisc::Network::CServer("", "", hostname, port, BlackMisc::Network::CUser(username, "", "", password))); + args.skipWhiteSpace(); + emit presetServer(BlackMisc::Network::CServer("", "", hostname, port, BlackMisc::Network::CUser(username, args.readAll(), "", password))); } -void Client::setCallsignCmd(QTextStream &args) +void Client::presetCallsignCmd(QTextStream &args) { QString callsign; args >> callsign; - emit setCallsign(callsign); + emit presetCallsign(callsign); } -void Client::setRealNameCmd(QTextStream &args) +void Client::presetIcaoCodesCmd(QTextStream &args) { - emit setRealName(args.readAll()); + QString acTypeICAO; + QString descriptionICAO; + QString airlineICAO; + QString livery; + QString color; + args >> acTypeICAO >> descriptionICAO >> airlineICAO >> livery >> color; + emit presetIcaoCodes(BlackMisc::Aviation::CAircraftIcao(acTypeICAO, descriptionICAO, airlineICAO, livery, color)); +} + +void Client::presetLoginModeCmd(QTextStream &args) +{ + QString modeString; + args >> modeString; + BlackCore::INetwork::LoginMode mode; + if (modeString == "normal") { mode = BlackCore::INetwork::LoginNormal; } + if (modeString == "observer") { mode = BlackCore::INetwork::LoginAsObserver; } + if (modeString == "stealth") { mode = BlackCore::INetwork::LoginStealth; } + emit presetLoginMode(mode); } void Client::initiateConnectionCmd(QTextStream &) @@ -209,11 +229,11 @@ void Client::sendAtisQueryCmd(QTextStream &args) emit sendAtisQuery(callsign); } -void Client::sendNameQueryCmd(QTextStream &args) +void Client::sendRealNameQueryCmd(QTextStream &args) { QString callsign; args >> callsign; - emit sendNameQuery(callsign); + emit sendRealNameQuery(callsign); } void Client::sendCapabilitiesQueryCmd(QTextStream &args) @@ -223,19 +243,15 @@ void Client::sendCapabilitiesQueryCmd(QTextStream &args) emit sendCapabilitiesQuery(callsign); } -void Client::requestAircraftInfoCmd(QTextStream &args) +void Client::sendIcaoCodesQueryCmd(QTextStream &args) { QString callsign; args >> callsign; - emit requestPlaneInfo(callsign); + emit sendIcaoCodesQuery(callsign); } void Client::setOwnAircraftCmd(QTextStream &args) { - QString callsign; - QString acTypeICAO; - QString airlineICAO; - QString livery; double lat; double lon; double alt; @@ -243,15 +259,23 @@ void Client::setOwnAircraftCmd(QTextStream &args) double pitch; double bank; double gs; - args >> callsign >> acTypeICAO >> airlineICAO >> livery >> lat >> lon >> alt >> hdg >> pitch >> bank >> gs; - emit setOwnAircraft(BlackMisc::Aviation::CAircraft(callsign, BlackMisc::Network::CUser(), BlackMisc::Aviation::CAircraftSituation( + double com1; + double com2; + int xpdrCode; + QString xpdrMode; + args >> lat >> lon >> alt >> hdg >> pitch >> bank >> gs >> com1 >> com2 >> xpdrCode >> xpdrMode; + BlackMisc::Aviation::CAircraft aircraft("", BlackMisc::Network::CUser(), BlackMisc::Aviation::CAircraftSituation( BlackMisc::Geo::CCoordinateGeodetic(lat, lon, 0), BlackMisc::Aviation::CAltitude(alt, BlackMisc::Aviation::CAltitude::MeanSeaLevel, BlackMisc::PhysicalQuantities::CLengthUnit::ft()), BlackMisc::Aviation::CHeading(hdg, BlackMisc::Aviation::CHeading::True, BlackMisc::PhysicalQuantities::CAngleUnit::deg()), BlackMisc::PhysicalQuantities::CAngle(pitch, BlackMisc::PhysicalQuantities::CAngleUnit::deg()), BlackMisc::PhysicalQuantities::CAngle(bank, BlackMisc::PhysicalQuantities::CAngleUnit::deg()), BlackMisc::PhysicalQuantities::CSpeed(gs, BlackMisc::PhysicalQuantities::CSpeedUnit::kts()) - ))); + )); + aircraft.setCom1System(BlackMisc::Aviation::CComSystem("COM1", BlackMisc::PhysicalQuantities::CFrequency(com1, BlackMisc::PhysicalQuantities::CFrequencyUnit::MHz()))); + aircraft.setCom2System(BlackMisc::Aviation::CComSystem("COM2", BlackMisc::PhysicalQuantities::CFrequency(com2, BlackMisc::PhysicalQuantities::CFrequencyUnit::MHz()))); + aircraft.setTransponder(BlackMisc::Aviation::CTransponder("Transponder", xpdrCode, xpdrMode)); + emit setOwnAircraft(aircraft); } void Client::setOwnAircraftPositionCmd(QTextStream &args) @@ -298,25 +322,25 @@ void Client::setOwnAircraftAvionicsCmd(QTextStream &args) ); } -void Client::pingCmd(QTextStream &args) +void Client::sendPingCmd(QTextStream &args) { QString callsign; args >> callsign; - emit ping(callsign); + emit sendPing(callsign); } -void Client::requestMetarCmd(QTextStream &args) +void Client::sendMetarQueryCmd(QTextStream &args) { QString airportICAO; args >> airportICAO; - emit requestMetar(airportICAO); + emit sendMetarQuery(airportICAO); } -void Client::requestWeatherDataCmd(QTextStream &args) +void Client::sendWeatherDataQueryCmd(QTextStream &args) { QString airportICAO; args >> airportICAO; - emit requestWeatherData(airportICAO); + emit sendWeatherDataQuery(airportICAO); } /****************************************************************************/ @@ -352,37 +376,37 @@ void Client::connectionStatusChanged(BlackCore::INetwork::ConnectionStatus oldSt } } -void Client::ipQueryReplyReceived(const QString &ip) +void Client::ipReplyReceived(const QString &ip) { std::cout << "IP_REPLY " << ip.toStdString() << std::endl; } -void Client::freqQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &freq) +void Client::freqReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &freq) { std::cout << "FREQ_REPLY " << callsign << " " << freq << std::endl; } -void Client::serverQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &hostname) +void Client::serverReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &hostname) { std::cout << "SERVER_REPLY " << callsign << " " << hostname.toStdString() << std::endl; } -void Client::atcQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, bool isATC) +void Client::atcReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, bool isATC) { std::cout << "ATC_REPLY " << callsign << (isATC ? " yes" : " no") << std::endl; } -void Client::atisQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CInformationMessage &atis) +void Client::atisReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CInformationMessage &atis) { std::cout << "ATIS_REPLY " << callsign << " " << atis << std::endl; } -void Client::nameQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &realname) +void Client::realNameReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &realname) { std::cout << "NAME_REPLY " << callsign << " " << realname.toStdString() << std::endl; } -void Client::capabilitiesQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, quint32 flags) +void Client::capabilitiesReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, quint32 flags) { std::cout << "CAPS_REPLY " << callsign << " " << flags << std::endl; } @@ -392,7 +416,7 @@ void Client::kicked(const QString &msg) std::cout << "KICKED " << msg.toStdString() << std::endl; } -void Client::metarReceived(const QString &data) +void Client::metarReplyReceived(const QString &data) { std::cout << "METAR " << data.toStdString() << std::endl; } @@ -402,12 +426,12 @@ void Client::pilotDisconnected(const BlackMisc::Aviation::CCallsign &callsign) std::cout << "PILOT_DISCONNECTED " << callsign << std::endl; } -void Client::aircraftInfoReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftIcao &icaoData) +void Client::icaoCodesReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftIcao &icaoData) { std::cout << "PLANE_INFO_REPLY " << callsign << " " << icaoData.toStdString(); } -void Client::pong(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CTime &elapsedTime) +void Client::pongReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CTime &elapsedTime) { std::cout << "PONG " << callsign << " " << elapsedTime << std::endl; } diff --git a/samples/cli_client/client.h b/samples/cli_client/client.h index dd2a58208..e82e8213f 100644 --- a/samples/cli_client/client.h +++ b/samples/cli_client/client.h @@ -30,9 +30,10 @@ private: //commands void help(QTextStream &args); void echo(QTextStream &args); void exit(QTextStream &args); - void setServerCmd(QTextStream &args); - void setCallsignCmd(QTextStream &args); - void setRealNameCmd(QTextStream &args); + void presetServerCmd(QTextStream &args); + void presetCallsignCmd(QTextStream &args); + void presetIcaoCodesCmd(QTextStream &args); + void presetLoginModeCmd(QTextStream &args); void initiateConnectionCmd(QTextStream &args); void terminateConnectionCmd(QTextStream &args); void sendPrivateTextMessageCmd(QTextStream &args); @@ -42,21 +43,23 @@ private: //commands void sendServerQueryCmd(QTextStream &args); void sendAtcQueryCmd(QTextStream &args); void sendAtisQueryCmd(QTextStream &args); - void sendNameQueryCmd(QTextStream &args); + void sendRealNameQueryCmd(QTextStream &args); void sendCapabilitiesQueryCmd(QTextStream &args); - void requestAircraftInfoCmd(QTextStream &args); + void sendIcaoCodesQueryCmd(QTextStream &args); void setOwnAircraftCmd(QTextStream &args); void setOwnAircraftPositionCmd(QTextStream &args); void setOwnAircraftSituationCmd(QTextStream &args); void setOwnAircraftAvionicsCmd(QTextStream &args); - void pingCmd(QTextStream &args); - void requestMetarCmd(QTextStream &args); - void requestWeatherDataCmd(QTextStream &args); + void sendPingCmd(QTextStream &args); + void sendMetarQueryCmd(QTextStream &args); + void sendWeatherDataQueryCmd(QTextStream &args); signals: //to send to INetwork - void setServer(const BlackMisc::Network::CServer &server); - void setCallsign(const BlackMisc::Aviation::CCallsign &callsign); - void setRealName(const QString &name); + void presetServer(const BlackMisc::Network::CServer &server); + void presetCallsign(const BlackMisc::Aviation::CCallsign &callsign); + void presetRealName(const QString &name); + void presetIcaoCodes(const BlackMisc::Aviation::CAircraftIcao &icao); + void presetLoginMode(BlackCore::INetwork::LoginMode mode); void initiateConnection(); void terminateConnection(); void sendTextMessages(const BlackMisc::Network::CTextMessageList &textMessages); @@ -66,35 +69,35 @@ signals: //to send to INetwork void sendServerQuery(const BlackMisc::Aviation::CCallsign &callsign); void sendAtcQuery(const BlackMisc::Aviation::CCallsign &callsign); void sendAtisQuery(const BlackMisc::Aviation::CCallsign &callsign); - void sendNameQuery(const BlackMisc::Aviation::CCallsign &callsign); + void sendRealNameQuery(const BlackMisc::Aviation::CCallsign &callsign); void sendCapabilitiesQuery(const BlackMisc::Aviation::CCallsign &callsign); - void requestPlaneInfo(const BlackMisc::Aviation::CCallsign &callsign); + void sendIcaoCodesQuery(const BlackMisc::Aviation::CCallsign &callsign); void setOwnAircraft(const BlackMisc::Aviation::CAircraft &aircraft); void setOwnAircraftPosition(const BlackMisc::Geo::CCoordinateGeodetic &position, const BlackMisc::Aviation::CAltitude &altitude); void setOwnAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation); void setOwnAircraftAvionics(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, const BlackMisc::Aviation::CTransponder &xpdr); - void ping(const BlackMisc::Aviation::CCallsign &callsign); - void requestMetar(const QString &airportICAO); - void requestWeatherData(const QString &airportICAO); + void sendPing(const BlackMisc::Aviation::CCallsign &callsign); + void sendMetarQuery(const QString &airportICAO); + void sendWeatherDataQuery(const QString &airportICAO); public slots: //to receive from INetwork void atcPositionUpdate(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &freq, const BlackMisc::Geo::CCoordinateGeodetic &pos, const BlackMisc::PhysicalQuantities::CLength &range); void atcDisconnected(const BlackMisc::Aviation::CCallsign &callsign); void connectionStatusChanged(BlackCore::INetwork::ConnectionStatus oldStatus, BlackCore::INetwork::ConnectionStatus newStatus); - void ipQueryReplyReceived(const QString &ip); - void freqQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &freq); - void serverQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &hostname); - void atcQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, bool isATC); - void atisQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CInformationMessage &atis); - void nameQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &realname); - void capabilitiesQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, quint32 flags); + void ipReplyReceived(const QString &ip); + void freqReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &freq); + void serverReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &hostname); + void atcReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, bool isATC); + void atisReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CInformationMessage &atis); + void realNameReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &realname); + void capabilitiesReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, quint32 flags); void kicked(const QString &msg); - void metarReceived(const QString &data); + void metarReplyReceived(const QString &data); void pilotDisconnected(const BlackMisc::Aviation::CCallsign &callsign); - void aircraftInfoReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftIcao &icaoData); - void pong(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CTime &elapsedTime); + void icaoCodesReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftIcao &icaoData); + void pongReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CTime &elapsedTime); void textMessagesReceived(const BlackMisc::Network::CTextMessageList &messages); private: diff --git a/src/blackcore/context_network.cpp b/src/blackcore/context_network.cpp index 1c98355f2..180391017 100644 --- a/src/blackcore/context_network.cpp +++ b/src/blackcore/context_network.cpp @@ -27,7 +27,7 @@ namespace BlackCore { // 1. Init by "network driver" - this->m_network = new CNetworkVatlib(CNetworkVatlib::LoginNormal, this); + this->m_network = new CNetworkVatlib(this); // 2. Init own aircraft this->initOwnAircraft(); @@ -42,15 +42,15 @@ namespace BlackCore // 4. connect signals and slots this->connect(this->m_network, &INetwork::connectionStatusChanged, this, &CContextNetwork::psFsdConnectionStatusChanged); this->connect(this->m_network, &INetwork::atcPositionUpdate, this, &CContextNetwork::psFsdAtcPositionUpdate); - this->connect(this->m_network, &INetwork::atisQueryReplyReceived, this, &CContextNetwork::psFsdAtisQueryReceived); - this->connect(this->m_network, &INetwork::atisQueryVoiceRoomReplyReceived, this, &CContextNetwork::psFsdAtisVoiceRoomQueryReceived); - this->connect(this->m_network, &INetwork::atisQueryLogoffTimeReplyReceived, this, &CContextNetwork::psFsdAtisLogoffTimeQueryReceived); - this->connect(this->m_network, &INetwork::metarReceived, this, &CContextNetwork::psFsdMetarReceived); - this->connect(this->m_network, &INetwork::nameQueryReplyReceived, this, &CContextNetwork::psFsdNameQueryReplyReceived); - this->connect(this->m_network, &INetwork::aircraftInfoReceived, this, &CContextNetwork::psFsdAircraftInfoReceived); + this->connect(this->m_network, &INetwork::atisReplyReceived, this, &CContextNetwork::psFsdAtisQueryReceived); + this->connect(this->m_network, &INetwork::atisVoiceRoomReplyReceived, this, &CContextNetwork::psFsdAtisVoiceRoomQueryReceived); + this->connect(this->m_network, &INetwork::atisLogoffTimeReplyReceived, this, &CContextNetwork::psFsdAtisLogoffTimeQueryReceived); + this->connect(this->m_network, &INetwork::metarReplyReceived, this, &CContextNetwork::psFsdMetarReceived); + this->connect(this->m_network, &INetwork::realNameReplyReceived, this, &CContextNetwork::psFsdRealNameReplyReceived); + this->connect(this->m_network, &INetwork::icaoCodesReplyReceived, this, &CContextNetwork::psFsdIcaoCodesReceived); this->connect(this->m_network, &INetwork::pilotDisconnected, this, &CContextNetwork::psFsdPilotDisconnected); this->connect(this->m_network, &INetwork::aircraftPositionUpdate, this, &CContextNetwork::psFsdAircraftUpdateReceived); - this->connect(this->m_network, &INetwork::frequencyQueryReplyReceived, this, &CContextNetwork::psFsdFrequencyReceived); + this->connect(this->m_network, &INetwork::frequencyReplyReceived, this, &CContextNetwork::psFsdFrequencyReceived); this->connect(this->m_network, &INetwork::textMessagesReceived, this, &CContextNetwork::psFsdTextMessageReceived); this->connect(this->m_network, &INetwork::statusMessage, this, &CContextNetwork::statusMessage); } @@ -107,8 +107,10 @@ namespace BlackCore } else { - this->m_ownAircraft.setPilot(currentServer.getUser()); - this->m_network->setServer(currentServer); + this->m_ownAircraft.setPilot(currentServer.getUser()); // still needed? + this->m_network->presetServer(currentServer); + this->m_network->presetCallsign(this->m_ownAircraft.getCallsign()); + this->m_network->presetIcaoCodes(this->m_ownAircraft.getIcaoInfo()); this->m_network->setOwnAircraft(this->m_ownAircraft); this->m_network->initiateConnection(); QString msg = "Connection pending "; @@ -259,7 +261,7 @@ namespace BlackCore /* * Name query */ - void CContextNetwork::psFsdNameQueryReplyReceived(const CCallsign &callsign, const QString &realname) + void CContextNetwork::psFsdRealNameReplyReceived(const CCallsign &callsign, const QString &realname) { // this->log(Q_FUNC_INFO, callsign.toQString(), realname); if (realname.isEmpty()) return; diff --git a/src/blackcore/context_network.h b/src/blackcore/context_network.h index 67e80ba3b..d7b9ad0b9 100644 --- a/src/blackcore/context_network.h +++ b/src/blackcore/context_network.h @@ -271,12 +271,12 @@ namespace BlackCore /*! * \brief Realname recevied */ - void psFsdNameQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &realname); + void psFsdRealNameReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &realname); /*! - * \brief Plane info received + * \brief Plane ICAO codes received */ - void psFsdAircraftInfoReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftIcao &icaoData); + void psFsdIcaoCodesReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftIcao &icaoData); /*! * \brief Aircraft position update received diff --git a/src/blackcore/context_network_aircraft.cpp b/src/blackcore/context_network_aircraft.cpp index b9db1e65e..4b7b6218d 100644 --- a/src/blackcore/context_network_aircraft.cpp +++ b/src/blackcore/context_network_aircraft.cpp @@ -19,7 +19,7 @@ namespace BlackCore /* * Aircraft info received */ - void CContextNetwork::psFsdAircraftInfoReceived(const CCallsign &callsign, const CAircraftIcao &icaoData) + void CContextNetwork::psFsdIcaoCodesReceived(const CCallsign &callsign, const CAircraftIcao &icaoData) { // this->log(Q_FUNC_INFO, callsign.toQString(), icaoData.toQString()); CAircraftList aircraftsWithCallsign = this->m_aircraftsInRange.findByCallsign(callsign); @@ -32,7 +32,7 @@ namespace BlackCore aircraft.calculcateDistanceToPlane(this->m_ownAircraft.getPosition()); this->m_aircraftsInRange.push_back(aircraft); emit this->m_network->sendFrequencyQuery(callsign); - emit this->m_network->sendNameQuery(callsign); + emit this->m_network->sendRealNameQuery(callsign); emit this->changedAircraftsInRange(); } else @@ -61,8 +61,8 @@ namespace BlackCore aircraft.calculcateDistanceToPlane(this->m_ownAircraft.getPosition()); this->m_aircraftsInRange.push_back(aircraft); emit this->m_network->sendFrequencyQuery(callsign); - emit this->m_network->sendNameQuery(callsign); - emit this->m_network->requestAircraftInfo(callsign); + emit this->m_network->sendRealNameQuery(callsign); + emit this->m_network->sendIcaoCodesQuery(callsign); emit this->changedAircraftsInRange(); } else diff --git a/src/blackcore/context_network_atc.cpp b/src/blackcore/context_network_atc.cpp index 1a346bd2a..53f56c5e7 100644 --- a/src/blackcore/context_network_atc.cpp +++ b/src/blackcore/context_network_atc.cpp @@ -63,7 +63,7 @@ namespace BlackCore if (metar.isEmpty() || metar.timeDiffReceivedMs() > 10 * 1000) { // outdated, or not in cache at all - this->m_network->requestMetar(airportIcaoCode.trimmed().toUpper()); + this->m_network->sendMetarQuery(airportIcaoCode.trimmed().toUpper()); // with this little trick we try to make an asynchronous signal / slot // based approach a synchronous return value @@ -183,7 +183,7 @@ namespace BlackCore this->m_atcStationsOnline.push_back(station); emit this->changedAtcStationsOnline(); emit this->m_network->sendAtisQuery(callsign); // request ATIS - emit this->m_network->sendNameQuery(callsign); + emit this->m_network->sendRealNameQuery(callsign); emit this->m_network->sendServerQuery(callsign); } else diff --git a/src/blackcore/network.h b/src/blackcore/network.h index e8e37ce28..42d08dffb 100644 --- a/src/blackcore/network.h +++ b/src/blackcore/network.h @@ -31,6 +31,16 @@ namespace BlackCore /*! * Interface for a connection to a multi-user flight simulation and ATC network. * + * The connection can be in one of three essential states: disconnected, connecting, and + * connected. (There is a fourth state, disconnected due to error, which is a substate of + * disconnected.) Some slots may only be called when connected, and some may only be called + * when disconnected; there is a naming convention to highlight this fact using prefixes: + * "preset" slots are only callable when disconnected, "send" slots are only callable when + * connected, and "set" slots are callable in any state. + * + * Slots with the word "query" in their names are handled asynchronously, with one or more + * "reply" signals being sent in response to each invokation of a query slot. + * * \warning If an INetwork signal is connected to a slot, and that slot emits a signal * which is connected to an INetwork slot, then at least one of those connections * must be a Qt::QueuedConnection. @@ -42,14 +52,19 @@ namespace BlackCore protected: /*! - * \brief Constructor - * \param parent + * Constructor */ INetwork(QObject *parent = nullptr) : QObject(parent) {} public: + /*! + * Destructor. + */ virtual ~INetwork() {} + /*! + * Flags for capabilities bitfield. + */ enum { AcceptsAtisResponses = 1 << 0, @@ -57,14 +72,30 @@ namespace BlackCore SupportsModelDescriptions = 1 << 2 }; - enum ConnectionStatus + /*! + * Login modes + */ + enum LoginMode { - Disconnected = 0, - DisconnectedError, - Connecting, - Connected + LoginNormal = 0, //!< Normal login + LoginAsObserver, //!< Login as observer + LoginStealth //!< Login stealth mode }; + /*! + * Status of the connection. + */ + enum ConnectionStatus + { + Disconnected = 0, //!< Not connected + DisconnectedError, //!< Disconnected due to socket error + Connecting, //!< Connection initiated but not established + Connected //!< Connection established + }; + + /*! + * Convert a ConnectionStatus to a string. + */ static QString connectionStatusToString(ConnectionStatus status) { int index = staticMetaObject.indexOfEnumerator("ConnectionStatus"); @@ -72,79 +103,340 @@ namespace BlackCore return metaEnum.valueToKey(status); } + /*! + * Returns true if the given ConnectionStatus represents an error state. + */ + static bool isErrorStatus(ConnectionStatus status) + { + return status == DisconnectedError; + } + + /*! + * Returns true if the current ConnectionStatus is a connected state. + */ virtual bool isConnected() const = 0; public slots: - // Network - virtual void setServer(const BlackMisc::Network::CServer &server) = 0; - virtual void setCallsign(const BlackMisc::Aviation::CCallsign &callsign) = 0; - virtual void setRealName(const QString &name) = 0; - virtual void initiateConnection() = 0; - virtual void terminateConnection() = 0; - virtual void ping(const BlackMisc::Aviation::CCallsign &callsign) = 0; + //////////////////////////////////////////////////////////////// + //! \name Network slots + //! @{ + //////////////////////////////////////////////////////////////// - virtual void sendNameQuery(const BlackMisc::Aviation::CCallsign &callsign) = 0; + /*! + * Set the server which will be connected to. + * \pre Network must be disconnected when calling this function. + */ + virtual void presetServer(const BlackMisc::Network::CServer &server) = 0; + + /*! + * Set our own callsign before connecting. + * \pre Network must be disconnected when calling this function. + */ + virtual void presetCallsign(const BlackMisc::Aviation::CCallsign &callsign) = 0; + + /*! + * Set our own aircraft ICAO codes before connecting. + * \pre Network must be disconnected when calling this function. + */ + virtual void presetIcaoCodes(const BlackMisc::Aviation::CAircraftIcao &icao) = 0; + + /*! + * Select a login mode before connecting. + * \pre Network must be disconnected when calling this function. + */ + virtual void presetLoginMode(LoginMode mode) = 0; + + /*! + * Initiate a connection to the network server. + * \pre Network must be disconnected when calling this function. + * \post Connection status changes from Disconnected to either Connecting or DisconnectedError. + */ + virtual void initiateConnection() = 0; + + /*! + * Ask the connection to the network server to terminate itself. + * \pre It is not legal to call this function when already disconnected. + * \post Connection status changes to Disconnected, but maybe not immediately. + */ + virtual void terminateConnection() = 0; + + /*! + * Send a ping message to a user with a specific callsign. + * \pre Network must be connected when calling this function. + * \sa pongReceived + */ + virtual void sendPing(const BlackMisc::Aviation::CCallsign &callsign) = 0; + + /*! + * Send a message querying the real name of the user with a specific callsign. + * \pre Network must be connected when calling this function. + * \sa realNameReplyReceived + */ + virtual void sendRealNameQuery(const BlackMisc::Aviation::CCallsign &callsign) = 0; + + /*! + * Send a message querying our own IP address as reported by the server. + * \pre Network must be connected when calling this function. + * \sa ipReplyReceived + */ virtual void sendIpQuery() = 0; + + /*! + * Send a message querying which server the user with a specific callsign is connected to. + * \pre Network must be connected when calling this function. + * \sa serverReplyReceived + */ virtual void sendServerQuery(const BlackMisc::Aviation::CCallsign &callsign) = 0; - // Text messages - virtual void sendTextMessages(const BlackMisc::Network::CTextMessageList &textMessages) = 0; + /*! + * Send one or more text messages. + * \pre Network must be connected when calling this function. + */ + virtual void sendTextMessages(const BlackMisc::Network::CTextMessageList &messages) = 0; - // ATC + //! @} + //////////////////////////////////////////////////////////////// + //! \name ATC slots + //! @{ + //////////////////////////////////////////////////////////////// + + /*! + * Send a message querying whether or not the user with a specific callsign is an ATC station. + * \pre Network must be connected when calling this function. + * \sa atcReplyReceived + */ virtual void sendAtcQuery(const BlackMisc::Aviation::CCallsign &callsign) = 0; + + /*! + * Send a message querying the ATIS for the ATC station with a specific callsign. + * \pre Network must be connected when calling this function. + * \sa atisReplyReceived + * \sa atisVoiceRoomReplyReceived + * \sa atisLogoffTimeReplyReceived + */ virtual void sendAtisQuery(const BlackMisc::Aviation::CCallsign &callsign) = 0; - // Aircraft + // TODO virtual void sendFlightPlan(...) = 0; + + //! @} + //////////////////////////////////////////////////////////////// + //! \name Aircraft slots + //! @{ + //////////////////////////////////////////////////////////////// + + /*! + * Send a message querying the capabilities of the client software of the user with a specific callsign. + * \pre Network must be connected when calling this function. + * \sa capabilitiesReplyReceived + */ virtual void sendCapabilitiesQuery(const BlackMisc::Aviation::CCallsign &callsign) = 0; - virtual void requestAircraftInfo(const BlackMisc::Aviation::CCallsign &callsign) = 0; + + /*! + * Send a message querying the ICAO codes of the aircraft of the user with a specific callsign. + * \pre Network must be connected when calling this function. + * \sa icaoCodesReplyReceived + */ + virtual void sendIcaoCodesQuery(const BlackMisc::Aviation::CCallsign &callsign) = 0; + + /*! + * Send a message querying the COM frequency of the user with a specific callsign. + * \pre Network must be connected when calling this function. + * \sa frequencyReplyReceived + */ virtual void sendFrequencyQuery(const BlackMisc::Aviation::CCallsign &callsign) = 0; + + /*! + * Set our own aircraft data. + * \param aircraft Only the situation and avionics parts are used. Callsign, user, and ICAO code parts are ignored. + */ virtual void setOwnAircraft(const BlackMisc::Aviation::CAircraft &aircraft) = 0; + + /*! + * Set the position and altitude of our own aircraft. + */ virtual void setOwnAircraftPosition(const BlackMisc::Geo::CCoordinateGeodetic &position, const BlackMisc::Aviation::CAltitude &altitude) = 0; + + /*! + * Set the position, altitude, orientation, and miscellaneous state of our own aircraft. + */ virtual void setOwnAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation) = 0; + + /*! + * Set the COM frequencies and transponder code and mode of our own aircraft. + */ virtual void setOwnAircraftAvionics(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, const BlackMisc::Aviation::CTransponder &transponder) = 0; - // Weather / flight plan - virtual void requestMetar(const QString &airportICAO) = 0; - virtual void requestWeatherData(const QString &airportICAO) = 0; - // TODO virtual void sendFlightPlan(...) = 0; + //! @} + //////////////////////////////////////////////////////////////// + //! \name Weather slots + //! @{ + //////////////////////////////////////////////////////////////// + + /*! + * Send a message querying the METAR for the airport with a specific ICAO code. + * \pre Network must be connected when calling this function. + * \sa metarReplyReceived + */ + virtual void sendMetarQuery(const QString &airportICAO) = 0; + + /*! + * Send a message querying the weather data for the airport with a specific ICAO code. + * \pre Network must be connected when calling this function. + * \sa temperatureDataReplyReceived + * \sa windDataReplyReceived + * \sa cloudDataReplyReceived + */ + virtual void sendWeatherDataQuery(const QString &airportICAO) = 0; signals: - // ATC + //! @} + //////////////////////////////////////////////////////////////// + //! \name ATC signals + //! @{ + //////////////////////////////////////////////////////////////// + + /*! + * We received a notification of the state of an ATC station on the network. + */ void atcPositionUpdate(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &freq, const BlackMisc::Geo::CCoordinateGeodetic &pos, const BlackMisc::PhysicalQuantities::CLength &range); - void atcDisconnected(const BlackMisc::Aviation::CCallsign &callsign); - void atcQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, bool isATC); - void atisQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CInformationMessage &atis); - void atisQueryVoiceRoomReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &url); - void atisQueryLogoffTimeReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &zuluTime); - void metarReceived(const QString &data); - // Aircraft + /*! + * We received a notification that an ATC station has disconnected from the network. + */ + void atcDisconnected(const BlackMisc::Aviation::CCallsign &callsign); + + /*! + * We received a reply to one of our queries. + * \sa sendAtcQuery + */ + void atcReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, bool isATC); + + /*! + * We received a reply to one of our ATIS queries. + * \sa sendAtisQuery + */ + void atisReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CInformationMessage &atis); + + /*! + * We received a reply to one of our ATIS queries, containing the controller's voice room URL. + * \sa sendAtisQuery + */ + void atisVoiceRoomReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &url); + + /*! + * We received a reply to one of our ATIS queries, containing the controller's planned logoff time. + * \sa sendAtisQuery + */ + void atisLogoffTimeReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &zuluTime); + + /*! + * We received a reply to one of our METAR queries. + * \sa sendMetarQuery + */ + void metarReplyReceived(const QString &data); + + //! @} + //////////////////////////////////////////////////////////////// + //! \name Aircraft signals + //! @{ + //////////////////////////////////////////////////////////////// + + /*! + * We received a notification that a pilot has disconnected from the network. + */ void pilotDisconnected(const BlackMisc::Aviation::CCallsign &callsign); - void aircraftInfoReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftIcao &icao); + + /*! + * We received a reply to one of our queries. + * \sa sendIcaoCodesQuery + */ + void icaoCodesReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftIcao &icao); + + /*! + * We received a notification of the state of another aircraft on the network. + */ void aircraftPositionUpdate(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CTransponder &transponder); + + /*! + * We received a reply to one of our queries. + * \sa sendFrequencyQuery + */ + void frequencyReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &freq); + // TODO void aircraftInterimPositionUpdate(...); - void frequencyQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &freq); - // Connection / Network in general + //! @} + //////////////////////////////////////////////////////////////// + //! \name Network signals + //! @{ + //////////////////////////////////////////////////////////////// + + /*! + * We sent a message about the status of the network connection, for the attention of the user. + */ void statusMessage(const BlackMisc::CStatusMessage &message); - void kicked(const QString &msg); - void connectionStatusChanged(ConnectionStatus oldStatus, ConnectionStatus newStatus); - void pong(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CTime &elapsedTime); - void capabilitiesQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, quint32 flags); - void ipQueryReplyReceived(const QString &ip); - void serverQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &hostname); - void nameQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &realname); - // Text messages + /*! + * We were kicked from the network. (A connectionStatusChanged signal will also be sent.) + */ + void kicked(const QString &msg); + + /*! + * The status of our connection has changed. + */ + void connectionStatusChanged(ConnectionStatus oldStatus, ConnectionStatus newStatus); + + /*! + * We received a reply to one of our pings. + * \sa sendPing + */ + void pongReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CTime &elapsedTime); + + /*! + * We received a reply to one of our queries. + * \param flags A combination of capabilities flags. + * \sa sendCapabilitiesQuery + */ + void capabilitiesReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, quint32 flags); + + /*! + * We received a reply to one of our queries. + * \param ip Our IP address, as seen by the server. + * \sa sendIpQuery + */ + void ipReplyReceived(const QString &ip); + + /*! + * We received a reply to one of our queries. + * \sa sendServerQuery + */ + void serverReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &hostname); + + /*! + * We received a reply to one of our queries. + * \sa sendRealNameQuery + */ + void realNameReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &realname); + + /*! + * We received one or more text messages from another user. + */ void textMessagesReceived(const BlackMisc::Network::CTextMessageList &messages); - // Weather - // TODO void temperatureDataReceived(...); - // TODO void windDataReceived(...); - // TODO void cloudDataReceived(...); + //! @} + //////////////////////////////////////////////////////////////// + //! \name Weather signals + //! @{ + //////////////////////////////////////////////////////////////// + + // TODO void temperatureDataReplyReceived(...); + // TODO void windDataReplyReceived(...); + // TODO void cloudDataReplyReceived(...); + + //! @} }; } // namespace diff --git a/src/blackcore/network_vatlib.cpp b/src/blackcore/network_vatlib.cpp index 39c556d06..b64835be5 100644 --- a/src/blackcore/network_vatlib.cpp +++ b/src/blackcore/network_vatlib.cpp @@ -28,19 +28,29 @@ namespace BlackCore void exceptionDispatcher(const char *caller); - CNetworkVatlib::CNetworkVatlib(CNetworkVatlib::LoginMode loginMode, QObject *parent) + CNetworkVatlib::CNetworkVatlib(QObject *parent) : INetwork(parent), - m_net(Cvatlib_Network::Create()), - m_loginMode(loginMode), + m_loginMode(LoginNormal), m_status(Cvatlib_Network::connStatus_Idle), m_fsdTextCodec(QTextCodec::codecForName("latin1")) { + connect(this, &CNetworkVatlib::terminate, this, &INetwork::terminateConnection, Qt::QueuedConnection); + + Q_ASSERT_X(m_fsdTextCodec, "CNetworkVatlib", "Missing default wire text encoding"); + //TODO reinit m_fsdTextCodec from WireTextEncoding config setting if present + + connect(&m_processingTimer, SIGNAL(timeout()), this, SLOT(process())); + connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(update())); + m_processingTimer.start(c_processingIntervalMsec); + } + + void CNetworkVatlib::initializeSession() + { + Q_ASSERT_X(isDisconnected(), "CNetworkVatlib", "attempted to reinitialize session while still connected"); + try { - connect(this, SIGNAL(terminate()), this, SLOT(terminateConnection()), Qt::QueuedConnection); - - Q_ASSERT_X(m_fsdTextCodec, "CNetworkVatlib", "Missing default wire text encoding"); - //TODO reinit m_fsdTextCodec from WireTextEncoding config setting if present + m_net.reset(Cvatlib_Network::Create()); QString capabilities; capabilities += m_net->capability_AtcInfo; @@ -49,7 +59,7 @@ namespace BlackCore capabilities += "=1:"; capabilities += m_net->capability_ModelDesc; capabilities += "=1"; - if (loginMode == LoginStealth) + if (m_loginMode == LoginStealth) { capabilities += "STEALTH"; // TODO m_net->capability_Stealth capabilities += "=1"; @@ -79,21 +89,19 @@ namespace BlackCore m_net->InstallOnCloudDataReceivedEvent(onCloudDataReceived, this); m_net->InstallOnPilotInfoRequestReceivedEvent(onPilotInfoRequestReceived, this); m_net->InstallOnPilotInfoReceivedEvent(onPilotInfoReceived, this); - - connect(&m_processingTimer, SIGNAL(timeout()), this, SLOT(process())); - connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(update())); - m_processingTimer.start(c_processingIntervalMsec); } catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } CNetworkVatlib::~CNetworkVatlib() { + if (!m_net) { return; } + try { - if (m_net->IsNetworkConnected()) + if (m_net->IsValid() && m_net->IsNetworkConnected()) { - m_net->LogoffAndDisconnect(0); + m_net->LogoffAndDisconnect(0); // emits a connectionStatusChanged signal } } catch (...) { exceptionDispatcher(Q_FUNC_INFO); } @@ -106,6 +114,8 @@ namespace BlackCore void CNetworkVatlib::process() { + if (!m_net) { return; } + try { if (m_net->IsValid() && m_net->IsSessionExists()) @@ -118,6 +128,8 @@ namespace BlackCore void CNetworkVatlib::update() { + if (!m_net) { return; } + try { if (m_net->IsValid() && m_net->IsSessionExists() && isConnected()) @@ -161,6 +173,34 @@ namespace BlackCore catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } + INetwork::ConnectionStatus convertConnectionStatus(Cvatlib_Network::connStatus status) + { + switch (status) + { + case Cvatlib_Network::connStatus_Idle: return INetwork::Disconnected; + case Cvatlib_Network::connStatus_Connecting: return INetwork::Connecting; + case Cvatlib_Network::connStatus_Connected: return INetwork::Connected; + case Cvatlib_Network::connStatus_Disconnected: return INetwork::Disconnected; + case Cvatlib_Network::connStatus_Error: return INetwork::DisconnectedError; + } + qFatal("unrecognised connection status"); + return INetwork::DisconnectedError; + } + + void CNetworkVatlib::changeConnectionStatus(Cvatlib_Network::connStatus status) + { + if (m_status != status) + { + qSwap(m_status, status); + emit connectionStatusChanged(convertConnectionStatus(status), convertConnectionStatus(m_status)); + + if (isDisconnected()) + { + m_updateTimer.stop(); + } + } + } + QByteArray CNetworkVatlib::toFSD(QString qstr) const { return m_fsdTextCodec->fromUnicode(qstr); @@ -176,11 +216,6 @@ namespace BlackCore return m_fsdTextCodec->toUnicode(cstr); } - bool CNetworkVatlib::isConnected() const - { - return m_status == Cvatlib_Network::connStatus_Connected; - } - void exceptionDispatcher(const char *caller) { try @@ -210,26 +245,30 @@ namespace BlackCore /********************************** INetwork slots ************************************/ /********************************** * * * * * * * * * * * * * * * * * * * ************************************/ - void CNetworkVatlib::setServer(const CServer &server) + void CNetworkVatlib::presetServer(const CServer &server) { Q_ASSERT_X(isDisconnected(), "CNetworkVatlib", "Can't change server details while still connected"); - this->m_server = server; + m_server = server; } - void CNetworkVatlib::setCallsign(const BlackMisc::Aviation::CCallsign &callsign) + void CNetworkVatlib::presetCallsign(const BlackMisc::Aviation::CCallsign &callsign) { Q_ASSERT_X(isDisconnected(), "CNetworkVatlib", "Can't change callsign while still connected"); - - m_ownAircraft.setCallsign(callsign); + m_callsign = callsign; } - void CNetworkVatlib::setRealName(const QString &name) + void CNetworkVatlib::presetIcaoCodes(const BlackMisc::Aviation::CAircraftIcao &icao) { - Q_ASSERT_X(isDisconnected(), "CNetworkVatlib", "Can't change name while still connected"); + Q_ASSERT_X(isDisconnected(), "CNetworkVatlib", "Can't change ICAO codes while still connected"); + m_icaoCodes = icao; + } - auto pilot = m_ownAircraft.getPilot(); - pilot.setRealName(name); - m_ownAircraft.setPilot(pilot); + void CNetworkVatlib::presetLoginMode(LoginMode mode) + { + Q_ASSERT_X(isDisconnected(), "CNetworkVatlib", "Can't change login mode while still connected"); + m_loginMode = mode; + + m_net.reset(nullptr); } void CNetworkVatlib::initiateConnection() @@ -238,12 +277,17 @@ namespace BlackCore try { - m_status = Cvatlib_Network::connStatus_Connecting; // paranoia + if (!m_net) + { + initializeSession(); + } + + changeConnectionStatus(Cvatlib_Network::connStatus_Connecting); // paranoia QByteArray callsign = toFSD(m_loginMode == LoginAsObserver ? - m_ownAircraft.getCallsign().getAsObserverCallsignString() : - m_ownAircraft.getCallsign().asString()); - QByteArray name = toFSD(m_ownAircraft.getPilot().getRealName()); + m_callsign.getAsObserverCallsignString() : + m_callsign.asString()); + QByteArray name = toFSD(m_server.getUser().getRealName()); if (this->m_loginMode == LoginAsObserver) { @@ -270,15 +314,22 @@ namespace BlackCore toFSD(m_server.getUser().getPassword()), info); } - m_net->ConnectAndLogon(); - if (! m_updateTimer.isActive()) + + if (m_net->ConnectAndLogon()) { - m_updateTimer.start(c_updateIntervalMsec); + if (! m_updateTimer.isActive()) + { + m_updateTimer.start(c_updateIntervalMsec); + } + } + else + { + changeConnectionStatus(Cvatlib_Network::connStatus_Error); } } catch (...) { - m_status = Cvatlib_Network::connStatus_Idle; + changeConnectionStatus(Cvatlib_Network::connStatus_Error); exceptionDispatcher(Q_FUNC_INFO); } } @@ -288,7 +339,11 @@ namespace BlackCore try { m_updateTimer.stop(); - m_net->LogoffAndDisconnect(c_logoffTimeoutSec); + + if (m_net && m_net->IsValid() && m_net->IsNetworkConnected()) + { + m_net->LogoffAndDisconnect(c_logoffTimeoutSec); + } } catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } @@ -319,6 +374,8 @@ namespace BlackCore void CNetworkVatlib::sendTextMessages(const BlackMisc::Network::CTextMessageList &messages) { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + if (messages.isEmpty()) return; try { @@ -345,6 +402,8 @@ namespace BlackCore void CNetworkVatlib::sendIpQuery() { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + try { m_net->SendInfoQuery(Cvatlib_Network::infoQuery_IP, "SERVER"); @@ -354,6 +413,8 @@ namespace BlackCore void CNetworkVatlib::sendFrequencyQuery(const BlackMisc::Aviation::CCallsign &callsign) { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + try { m_net->SendInfoQuery(Cvatlib_Network::infoQuery_Freq, toFSD(callsign)); @@ -363,6 +424,8 @@ namespace BlackCore void CNetworkVatlib::sendServerQuery(const BlackMisc::Aviation::CCallsign &callsign) { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + try { m_net->SendInfoQuery(Cvatlib_Network::infoQuery_Server, toFSD(callsign)); @@ -372,6 +435,8 @@ namespace BlackCore void CNetworkVatlib::sendAtcQuery(const BlackMisc::Aviation::CCallsign &callsign) { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + try { m_net->SendInfoQuery(Cvatlib_Network::infoQuery_ATC, toFSD(callsign)); @@ -381,6 +446,8 @@ namespace BlackCore void CNetworkVatlib::sendAtisQuery(const BlackMisc::Aviation::CCallsign &callsign) { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + try { m_net->SendInfoQuery(Cvatlib_Network::infoQuery_ATIS, toFSD(callsign)); @@ -388,8 +455,10 @@ namespace BlackCore catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } - void CNetworkVatlib::sendNameQuery(const BlackMisc::Aviation::CCallsign &callsign) + void CNetworkVatlib::sendRealNameQuery(const BlackMisc::Aviation::CCallsign &callsign) { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + try { m_net->SendInfoQuery(Cvatlib_Network::infoQuery_Name, toFSD(callsign)); @@ -399,6 +468,8 @@ namespace BlackCore void CNetworkVatlib::sendCapabilitiesQuery(const BlackMisc::Aviation::CCallsign &callsign) { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + try { m_net->SendInfoQuery(Cvatlib_Network::infoQuery_Capabilities, toFSD(callsign)); @@ -406,7 +477,7 @@ namespace BlackCore catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } - void CNetworkVatlib::replyToFrequencyQuery(const BlackMisc::Aviation::CCallsign &callsign) + void CNetworkVatlib::replyToFrequencyQuery(const BlackMisc::Aviation::CCallsign &callsign) // private { try { @@ -416,7 +487,7 @@ namespace BlackCore catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } - void CNetworkVatlib::replyToNameQuery(const BlackMisc::Aviation::CCallsign &callsign) + void CNetworkVatlib::replyToNameQuery(const BlackMisc::Aviation::CCallsign &callsign) // private { try { @@ -425,8 +496,10 @@ namespace BlackCore catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } - void CNetworkVatlib::requestAircraftInfo(const BlackMisc::Aviation::CCallsign &callsign) + void CNetworkVatlib::sendIcaoCodesQuery(const BlackMisc::Aviation::CCallsign &callsign) { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + try { m_net->RequestPlaneInfo(toFSD(callsign)); @@ -434,25 +507,25 @@ namespace BlackCore catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } - void CNetworkVatlib::sendAircraftInfo(const BlackMisc::Aviation::CCallsign &callsign) + void CNetworkVatlib::sendAircraftInfo(const BlackMisc::Aviation::CCallsign &callsign) // private { try { - const QByteArray acTypeICAObytes = toFSD(m_ownAircraft.getIcaoInfo().getDesignator()); - const QByteArray airlineICAObytes = toFSD(m_ownAircraft.getIcaoInfo().getAirline()); - const QByteArray liverybytes = toFSD(m_ownAircraft.getIcaoInfo().getLivery()); + const QByteArray acTypeICAObytes = toFSD(m_icaoCodes.getDesignator()); + const QByteArray airlineICAObytes = toFSD(m_icaoCodes.getAirline()); + const QByteArray liverybytes = toFSD(m_icaoCodes.getLivery()); std::vector keysValues; - if (!m_ownAircraft.getIcaoInfo().getDesignator().isEmpty()) + if (!m_icaoCodes.getDesignator().isEmpty()) { keysValues.push_back(m_net->acinfo_Equipment); keysValues.push_back(acTypeICAObytes); } - if (m_ownAircraft.getIcaoInfo().hasAirline()) + if (m_icaoCodes.hasAirline()) { keysValues.push_back(m_net->acinfo_Airline); keysValues.push_back(airlineICAObytes); } - if (m_ownAircraft.getIcaoInfo().hasLivery()) + if (m_icaoCodes.hasLivery()) { keysValues.push_back(m_net->acinfo_Livery); keysValues.push_back(liverybytes); @@ -463,8 +536,10 @@ namespace BlackCore catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } - void CNetworkVatlib::ping(const BlackMisc::Aviation::CCallsign &callsign) + void CNetworkVatlib::sendPing(const BlackMisc::Aviation::CCallsign &callsign) { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + try { m_net->PingUser(toFSD(callsign)); @@ -472,8 +547,10 @@ namespace BlackCore catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } - void CNetworkVatlib::requestMetar(const QString &airportICAO) + void CNetworkVatlib::sendMetarQuery(const QString &airportICAO) { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + try { m_net->RequestMetar(toFSD(airportICAO)); @@ -481,8 +558,10 @@ namespace BlackCore catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } - void CNetworkVatlib::requestWeatherData(const QString &airportICAO) + void CNetworkVatlib::sendWeatherDataQuery(const QString &airportICAO) { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + try { m_net->RequestWeatherData(toFSD(airportICAO)); @@ -499,24 +578,9 @@ namespace BlackCore return static_cast(cbvar); } - CNetworkVatlib::ConnectionStatus convertConnectionStatus(Cvatlib_Network::connStatus status) + void CNetworkVatlib::onConnectionStatusChanged(Cvatlib_Network *, Cvatlib_Network::connStatus, Cvatlib_Network::connStatus newStatus, void *cbvar) { - switch (status) - { - case Cvatlib_Network::connStatus_Idle: return CNetworkVatlib::Disconnected; - case Cvatlib_Network::connStatus_Connecting: return CNetworkVatlib::Connecting; - case Cvatlib_Network::connStatus_Connected: return CNetworkVatlib::Connected; - case Cvatlib_Network::connStatus_Disconnected: return CNetworkVatlib::Disconnected; - case Cvatlib_Network::connStatus_Error: return CNetworkVatlib::DisconnectedError; - } - qFatal("unrecognised connection status"); - return CNetworkVatlib::DisconnectedError; - } - - void CNetworkVatlib::onConnectionStatusChanged(Cvatlib_Network *, Cvatlib_Network::connStatus oldStatus, Cvatlib_Network::connStatus newStatus, void *cbvar) - { - cbvar_cast(cbvar)->m_status = newStatus; - emit cbvar_cast(cbvar)->connectionStatusChanged(convertConnectionStatus(oldStatus), convertConnectionStatus(newStatus)); + cbvar_cast(cbvar)->changeConnectionStatus(newStatus); } void CNetworkVatlib::onTextMessageReceived(Cvatlib_Network *, const char *from, const char *to, const char *msg, void *cbvar) @@ -596,16 +660,17 @@ namespace BlackCore void CNetworkVatlib::onKicked(Cvatlib_Network *, const char *reason, void *cbvar) { emit cbvar_cast(cbvar)->kicked(cbvar_cast(cbvar)->fromFSD(reason)); + emit cbvar_cast(cbvar)->terminate(); } void CNetworkVatlib::onPong(Cvatlib_Network *, const char *callsign, INT elapsedTime, void *cbvar) { - emit cbvar_cast(cbvar)->pong(cbvar_cast(cbvar)->fromFSD(callsign), CTime(elapsedTime, CTimeUnit::s())); + emit cbvar_cast(cbvar)->pongReceived(cbvar_cast(cbvar)->fromFSD(callsign), CTime(elapsedTime, CTimeUnit::s())); } void CNetworkVatlib::onMetarReceived(Cvatlib_Network *, const char *data, void *cbvar) { - emit cbvar_cast(cbvar)->metarReceived(cbvar_cast(cbvar)->fromFSD(data)); + emit cbvar_cast(cbvar)->metarReplyReceived(cbvar_cast(cbvar)->fromFSD(data)); } void CNetworkVatlib::onInfoQueryRequestReceived(Cvatlib_Network *, const char *callsignString, Cvatlib_Network::infoQuery type, const char *, void *cbvar) @@ -630,11 +695,11 @@ namespace BlackCore { switch (type) { - case Cvatlib_Network::infoQuery_Freq: emit cbvar_cast(cbvar)->frequencyQueryReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), CFrequency(cbvar_cast(cbvar)->fromFSD(data).toFloat(), CFrequencyUnit::MHz())); break; - case Cvatlib_Network::infoQuery_Server: emit cbvar_cast(cbvar)->serverQueryReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); break; - case Cvatlib_Network::infoQuery_ATC: emit cbvar_cast(cbvar)->atcQueryReplyReceived(cbvar_cast(cbvar)->fromFSD(data2), *data == 'Y'); break; - case Cvatlib_Network::infoQuery_Name: emit cbvar_cast(cbvar)->nameQueryReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); break; - case Cvatlib_Network::infoQuery_IP: emit cbvar_cast(cbvar)->ipQueryReplyReceived(cbvar_cast(cbvar)->fromFSD(data)); break; + case Cvatlib_Network::infoQuery_Freq: emit cbvar_cast(cbvar)->frequencyReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), CFrequency(cbvar_cast(cbvar)->fromFSD(data).toFloat(), CFrequencyUnit::MHz())); break; + case Cvatlib_Network::infoQuery_Server: emit cbvar_cast(cbvar)->serverReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); break; + case Cvatlib_Network::infoQuery_ATC: emit cbvar_cast(cbvar)->atcReplyReceived(cbvar_cast(cbvar)->fromFSD(data2), *data == 'Y'); break; + case Cvatlib_Network::infoQuery_Name: emit cbvar_cast(cbvar)->realNameReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); break; + case Cvatlib_Network::infoQuery_IP: emit cbvar_cast(cbvar)->ipReplyReceived(cbvar_cast(cbvar)->fromFSD(data)); break; } } @@ -653,7 +718,7 @@ namespace BlackCore } keysValues += 2; } - emit cbvar_cast(cbvar)->capabilitiesQueryReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), flags); + emit cbvar_cast(cbvar)->capabilitiesReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), flags); } void CNetworkVatlib::onAtisReplyReceived(Cvatlib_Network *, const char *callsign, Cvatlib_Network::atisLineType lineType, const char *data, void *cbvar) @@ -662,17 +727,17 @@ namespace BlackCore if (lineType == Cvatlib_Network::atisLineType_VoiceRoom) { - emit cbvar_cast(cbvar)->atisQueryVoiceRoomReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); + emit cbvar_cast(cbvar)->atisVoiceRoomReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); } if (lineType == Cvatlib_Network::atisLineType_ZuluLogoff) { - emit cbvar_cast(cbvar)->atisQueryLogoffTimeReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); + emit cbvar_cast(cbvar)->atisLogoffTimeReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); } if (lineType == Cvatlib_Network::atisLineType_LineCount) { atis.setType(CInformationMessage::ATIS); - emit cbvar_cast(cbvar)->atisQueryReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), atis); + emit cbvar_cast(cbvar)->atisReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), atis); cbvar_cast(cbvar)->m_atisParts.remove(cbvar_cast(cbvar)->fromFSD(callsign)); } else @@ -734,7 +799,7 @@ namespace BlackCore terminate: emit cbvar_cast(cbvar)->statusMessage(BlackMisc::CStatusMessage(BlackMisc::CStatusMessage::TypeTrafficNetwork, BlackMisc::CStatusMessage::SeverityError, msg)); - emit cbvar_cast(cbvar)->terminate(); + emit cbvar_cast(cbvar)->terminate(); // private, will be handled during the next pass of the Qt event loop } void CNetworkVatlib::onWindDataReceived(Cvatlib_Network *, Cvatlib_Network::WindLayer /** layers **/[4], void * /** cbvar **/) @@ -769,7 +834,7 @@ namespace BlackCore else if (key == net->acinfo_Livery) { icao.setLivery(*keysValues); } keysValues++; } - emit cbvar_cast(cbvar)->aircraftInfoReceived(cbvar_cast(cbvar)->fromFSD(callsign), icao); + emit cbvar_cast(cbvar)->icaoCodesReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), icao); } } // namespace diff --git a/src/blackcore/network_vatlib.h b/src/blackcore/network_vatlib.h index e30be0c0b..2a3fd839d 100644 --- a/src/blackcore/network_vatlib.h +++ b/src/blackcore/network_vatlib.h @@ -27,40 +27,36 @@ namespace BlackCore Q_OBJECT public: - enum LoginMode - { - LoginNormal = 0, - LoginAsObserver, - LoginStealth - }; - - CNetworkVatlib(LoginMode loginMode = LoginNormal, QObject *parent = nullptr); + CNetworkVatlib(QObject *parent = nullptr); virtual ~CNetworkVatlib(); - bool isConnected() const; + bool isConnected() const { return m_status == Cvatlib_Network::connStatus_Connected; } public: // INetwork slots overrides // Network - virtual void setServer(const BlackMisc::Network::CServer &server); - virtual void setCallsign(const BlackMisc::Aviation::CCallsign &callsign); - virtual void setRealName(const QString &name); + virtual void presetServer(const BlackMisc::Network::CServer &server); + virtual void presetCallsign(const BlackMisc::Aviation::CCallsign &callsign); + virtual void presetIcaoCodes(const BlackMisc::Aviation::CAircraftIcao &icao); + virtual void presetLoginMode(LoginMode mode); virtual void initiateConnection(); virtual void terminateConnection(); + virtual void sendPing(const BlackMisc::Aviation::CCallsign &callsign); + + virtual void sendRealNameQuery(const BlackMisc::Aviation::CCallsign &callsign); virtual void sendIpQuery(); virtual void sendServerQuery(const BlackMisc::Aviation::CCallsign &callsign); - virtual void sendNameQuery(const BlackMisc::Aviation::CCallsign &callsign); - virtual void sendCapabilitiesQuery(const BlackMisc::Aviation::CCallsign &callsign); - virtual void ping(const BlackMisc::Aviation::CCallsign &callsign); - - // Weather - virtual void requestWeatherData(const QString &airportICAO); // Text messages virtual void sendTextMessages(const BlackMisc::Network::CTextMessageList &messages); + // ATC + virtual void sendAtcQuery(const BlackMisc::Aviation::CCallsign &callsign); + virtual void sendAtisQuery(const BlackMisc::Aviation::CCallsign &callsign); + // Aircraft - virtual void requestAircraftInfo(const BlackMisc::Aviation::CCallsign &callsign); + virtual void sendCapabilitiesQuery(const BlackMisc::Aviation::CCallsign &callsign); + virtual void sendIcaoCodesQuery(const BlackMisc::Aviation::CCallsign &callsign); virtual void sendFrequencyQuery(const BlackMisc::Aviation::CCallsign &callsign); virtual void setOwnAircraft(const BlackMisc::Aviation::CAircraft &aircraft); virtual void setOwnAircraftPosition(const BlackMisc::Geo::CCoordinateGeodetic &position, const BlackMisc::Aviation::CAltitude &altitude); @@ -68,10 +64,9 @@ namespace BlackCore virtual void setOwnAircraftAvionics(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, const BlackMisc::Aviation::CTransponder &xpdr); - // ATC - virtual void sendAtcQuery(const BlackMisc::Aviation::CCallsign &callsign); - virtual void sendAtisQuery(const BlackMisc::Aviation::CCallsign &callsign); - virtual void requestMetar(const QString &airportICAO); + // Weather + virtual void sendMetarQuery(const QString &airportICAO); + virtual void sendWeatherDataQuery(const QString &airportICAO); private slots: void replyToFrequencyQuery(const BlackMisc::Aviation::CCallsign &callsign); @@ -105,6 +100,8 @@ namespace BlackCore QByteArray toFSD(QString qstr) const; QByteArray toFSD(const BlackMisc::Aviation::CCallsign &callsign) const; QString fromFSD(const char *cstr) const; + void initializeSession(); + void changeConnectionStatus(Cvatlib_Network::connStatus newStatus); bool isDisconnected() const { return m_status != Cvatlib_Network::connStatus_Connecting && m_status != Cvatlib_Network::connStatus_Connected; } private slots: @@ -127,7 +124,9 @@ namespace BlackCore LoginMode m_loginMode; Cvatlib_Network::connStatus m_status; BlackMisc::Network::CServer m_server; - BlackMisc::Aviation::CAircraft m_ownAircraft; + BlackMisc::Aviation::CCallsign m_callsign; + BlackMisc::Aviation::CAircraftIcao m_icaoCodes; + BlackMisc::Aviation::CAircraft m_ownAircraft; // not using callsign, user, or icao parts of this member because they can't be changed when connected QMap m_atisParts; QTimer m_processingTimer; diff --git a/src/blackmisc/collection.h b/src/blackmisc/collection.h index a01319024..2fe56dc2e 100644 --- a/src/blackmisc/collection.h +++ b/src/blackmisc/collection.h @@ -52,27 +52,21 @@ namespace BlackMisc /*! * \brief Copy constructor. - * \param other */ CCollection(const CCollection &other) : m_pimpl(other.pimpl() ? other.pimpl()->clone() : nullptr) {} /*! * \brief Move constructor. - * \param other */ CCollection(CCollection &&other) : m_pimpl(other.m_pimpl.take()) {} /*! * \brief Copy assignment. - * \param other - * \return */ CCollection &operator =(const CCollection &other) { m_pimpl.reset(other.pimpl() ? other.pimpl()->clone() : nullptr); return *this; } /*! * \brief Move assignment. - * \param other - * \return */ CCollection &operator =(CCollection && other) { m_pimpl.reset(other.m_pimpl.take()); return *this; } @@ -80,7 +74,6 @@ namespace BlackMisc * \brief Create a new collection with a specific implementation type. * \tparam C Becomes the collection's implementation type. * \param c Initial value for the collection; default is empty, but it could contain elements if desired. The value is copied. - * \return */ template static CCollection fromImpl(C c = C()) { return CCollection(new Pimpl(std::move(c))); } @@ -92,68 +85,57 @@ namespace BlackMisc /*! * \brief Like changeImpl, but uses the implementation type of another collection. - * \param other * \pre The other collection must be initialized. */ void useImplOf(const CCollection &other) { PimplPtr p = other.pimpl()->cloneEmpty(); for (auto i = cbegin(); i != cend(); ++i) p->insert(*i); m_pimpl.reset(p.take()); } /*! * \brief Returns iterator at the beginning of the collection. - * \return */ iterator begin() { return pimpl() ? pimpl()->begin() : iterator(); } /*! * \brief Returns iterator at the beginning of the collection. - * \return */ const_iterator begin() const { return pimpl() ? pimpl()->begin() : const_iterator(); } /*! * \brief Returns iterator at the beginning of the collection. - * \return */ const_iterator cbegin() const { return pimpl() ? pimpl()->cbegin() : const_iterator(); } /*! * \brief Returns iterator one past the end of the collection. - * \return */ iterator end() { return pimpl() ? pimpl()->end() : iterator(); } /*! * \brief Returns iterator one past the end of the collection. - * \return */ const_iterator end() const { return pimpl() ? pimpl()->end() : const_iterator(); } /*! * \brief Returns iterator one past the end of the collection. - * \return */ const_iterator cend() const { return pimpl() ? pimpl()->cend() : const_iterator(); } /*! * \brief Swap this collection with another. - * \param other */ void swap(CCollection &other) { m_pimpl.swap(other.m_pimpl); } /*! * \brief Returns number of elements in the collection. - * \return */ size_type size() const { return pimpl() ? pimpl()->size() : 0; } /*! * \brief Returns true if the collection is empty. - * \return */ bool empty() const { return pimpl() ? pimpl()->empty() : true; } /*! * \brief Synonym for empty. - * \return */ bool isEmpty() const { return empty(); } @@ -164,7 +146,6 @@ namespace BlackMisc /*! * \brief Inserts an element into the collection. - * \param value * \return An iterator to the position where value was inserted. * \pre The collection must be initialized. */ @@ -172,7 +153,6 @@ namespace BlackMisc /*! * \brief Synonym for insert. - * \param value * \return An iterator to the position where value was inserted. * \pre The collection must be initialized. */ @@ -180,7 +160,6 @@ namespace BlackMisc /*! * \brief Remove the element pointed to by the given iterator. - * \param pos * \return An iterator to the position of the next element after the one removed. * \pre The collection must be initialized. */ @@ -188,8 +167,6 @@ namespace BlackMisc /*! * \brief Remove the range of elements between two iterators. - * \param it1 - * \param it2 * \return An iterator to the position of the next element after the one removed. * \pre The sequence must be initialized. */ @@ -197,16 +174,12 @@ namespace BlackMisc /*! * \brief Test for equality. - * \param other - * \return * \todo Improve inefficient implementation. */ bool operator ==(const CCollection &other) const { return (empty() && other.empty()) ? true : (size() != other.size() ? false : *pimpl() == *other.pimpl()); } /*! * \brief Test for inequality. - * \param other - * \return * \todo Improve inefficient implementation. */ bool operator !=(const CCollection &other) const { return !(*this == other); } diff --git a/src/blackmisc/containerbase.h b/src/blackmisc/containerbase.h index f55c94049..ed9b7b1b8 100644 --- a/src/blackmisc/containerbase.h +++ b/src/blackmisc/containerbase.h @@ -29,14 +29,12 @@ namespace BlackMisc public: /*! * \brief Return a copy containing only those elements for which a given predicate returns true. - * \param p - * \return */ template C findBy(Predicate p) const { C result = derived(); - result.erase(std::remove_if(result.begin(), result.end(), [ = ](const T & value) { return !p(value); }), result.end()); + result.erase(std::remove_if(result.begin(), result.end(), [ = ](const T &value) { return !p(value); }), result.end()); return result; } @@ -44,7 +42,6 @@ namespace BlackMisc * \brief Return a copy containing only those elements matching a particular key/value pair. * \param key1 A pointer to a member function of T. * \param value1 Will be compared to the return value of key1. - * \return */ template C findBy(K1 key1, V1 value1) const @@ -58,7 +55,6 @@ namespace BlackMisc * \param value1 Will be compared to the return value of key1. * \param key2 A pointer to a member function of T. * \param value2 Will be compared to the return value of key2. - * \return */ template C findBy(K1 key1, V1 value1, K2 key2, V2 value2) const @@ -74,7 +70,6 @@ namespace BlackMisc * \param value2 Will be compared to the return value of key2. * \param key3 A pointer to a member function of T. * \param value3 Will be compared to the return value of key3. - * \return */ template C findBy(K1 key1, V1 value1, K2 key2, V2 value2, K3 key3, V3 value3) const @@ -84,12 +79,19 @@ namespace BlackMisc /*! * \brief Return a copy containing only those elements matching a given value map. - * \param valueMap - * \return */ C findBy(const CValueMap &valueMap) const { - return findBy([ & ](const T & value) { return value == valueMap; }); + return findBy([ & ](const T &value) { return value == valueMap; }); + } + + /*! + * \brief Return true if there is an element for which a given predicate returns true + */ + template + bool contains(Predicate p) const + { + return std::any_of(derived().begin(), derived().end(), p); } /*! @@ -99,25 +101,13 @@ namespace BlackMisc */ bool contains(const T &object) const { - return std::binary_search(derived().begin(), derived().end(), object); + return std::find(derived().begin(), derived().end(), object) != derived().end(); } /*! - * \brief Return true if there is an element for which a given predicate returns true - * \param p - * \return - */ - template - bool contains(Predicate p) const - { - return std::any_of(derived().begin(), derived().end(), p); - } - - /*! - * \brief Return true if there is an element matching a particular key/value pair. + * \brief Return a copy containing only those elements matching a particular key/value pair. * \param key1 A pointer to a member function of T. * \param value1 Will be compared to the return value of key1. - * \return */ template bool contains(K1 key1, V1 value1) const @@ -125,36 +115,6 @@ namespace BlackMisc return contains(BlackMisc::Predicates::MemberEqual(key1, value1)); } - /*! - * \brief Remove given object - * \param object remove this object from in container - */ - void remove(const T &object) - { - std::remove(derived().begin(), derived().end(), object); - } - - /*! - * \brief Remove elements for which a given predicate returns true. - * \param p - */ - template - void removeIf(Predicate p) - { - std::remove_if(derived().begin(), derived().end(), p); - } - - /*! - * \brief Remove elements matching a particular key/value pair. - * \param key1 A pointer to a member function of T. - * \param value1 Will be compared to the return value of key1. - */ - template - void removeIf(K1 key1, V1 value1) - { - removeIf(BlackMisc::Predicates::MemberEqual(key1, value1)); - } - public: // CValueObject overrides /*! * \copydoc CValueObject::toQVariant() @@ -174,7 +134,7 @@ namespace BlackMisc { QString str; // qualifying stringify with this-> to workaround bug in GCC 4.7.2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56402 - std::for_each(derived().begin(), derived().end(), [ & ](const T & value) { str += (str.isEmpty() ? "{" : ",") + this->stringify(value, i18n); }); + std::for_each(derived().begin(), derived().end(), [ & ](const T &value) { str += (str.isEmpty() ? "{" : ",") + this->stringify(value, i18n); }); if (str.isEmpty()) { str = "{"; } return str += "}"; } @@ -212,7 +172,7 @@ namespace BlackMisc virtual void marshallToDbus(QDBusArgument &argument) const { argument.beginArray(qMetaTypeId()); - std::for_each(derived().begin(), derived().end(), [ & ](const T & value) { argument << value; }); + std::for_each(derived().begin(), derived().end(), [ & ](const T &value) { argument << value; }); argument.endArray(); } diff --git a/src/blackmisc/iterator.h b/src/blackmisc/iterator.h index 79396ba59..56b2c9d2d 100644 --- a/src/blackmisc/iterator.h +++ b/src/blackmisc/iterator.h @@ -46,27 +46,21 @@ namespace BlackMisc /*! * \brief Copy constructor. - * \param other */ ConstForwardIterator(const ConstForwardIterator &other) : m_pimpl(other.pimpl() ? other.pimpl()->clone() : nullptr) {} /*! * \brief Move constructor. - * \param other */ ConstForwardIterator(ConstForwardIterator &&other) : m_pimpl(other.m_pimpl.take()) {} /*! * \brief Copy assignment. - * \param other - * \return */ ConstForwardIterator &operator =(const ConstForwardIterator &other) { m_pimpl.reset(other.pimpl() ? other.pimpl()->clone() : nullptr); return *this; } /*! * \brief Move assignment. - * \param other - * \return */ ConstForwardIterator &operator =(ConstForwardIterator &&other) { m_pimpl.reset(other.m_pimpl.take()); return *this; } @@ -74,20 +68,17 @@ namespace BlackMisc * \brief Create a new iterator with a specific implementation type. * \tparam C Becomes the iterator's implementation type. * \param c Initial value for the iterator. The value is copied. - * \return */ template static ConstForwardIterator fromImpl(I i) { return ConstForwardIterator(new Pimpl(std::move(i))); } /*! * \brief Returns a reference to the object pointed to. - * \return * \pre The iterator must be initialized and valid. */ const_reference operator *() const { Q_ASSERT(m_pimpl); return **pimpl(); } /*! * \brief Arrow operator provides access to members of the object pointed to. - * \return * \pre The iterator must be initialized and valid. */ const_pointer operator ->() const { Q_ASSERT(m_pimpl); return &**pimpl(); } @@ -108,7 +99,6 @@ namespace BlackMisc /*! * \brief Advance the iterator by a certain amount. - * \param n * \return Reference to the iterator at the new position. * \pre The iterator must be initialized and valid. */ @@ -116,7 +106,6 @@ namespace BlackMisc /*! * \brief Advance the iterator by a certain amount. - * \param n * \return Copy of the iterator in its new position. * \pre The iterator must be initialized and valid. */ @@ -124,23 +113,18 @@ namespace BlackMisc /*! * \brief Test for equality. - * \param other - * \return * \pre Both iterators must originate from the same collection, and not mix begin/end with cbegin/cend. */ bool operator ==(const ConstForwardIterator &other) const { return (pimpl() && other.pimpl()) ? *pimpl() == *other.pimpl() : pimpl() == other.pimpl(); } /*! * \brief Test for inequality. - * \param other - * \return * \pre Both iterators must originate from the same collection, and not mix begin/end with cbegin/cend. */ bool operator !=(const ConstForwardIterator &other) const { return !(*this == other); } /*! * \brief Return opaque pointer to underlying implementation iterator object. - * \return * \pre The iterator must have been initialized. * \todo Returning by void* is rotten, but GCC gives a very cryptic error if I make it a function template with a cast inside. */ @@ -210,27 +194,21 @@ namespace BlackMisc /*! * \brief Copy constructor. - * \param other */ ConstBidirectionalIterator(const ConstBidirectionalIterator &other) : m_pimpl(other.pimpl() ? other.pimpl()->clone() : nullptr) {} /*! * \brief Move constructor. - * \param other */ ConstBidirectionalIterator(ConstBidirectionalIterator &&other) : m_pimpl(other.m_pimpl.take()) {} /*! * \brief Copy assignment. - * \param other - * \return */ ConstBidirectionalIterator &operator =(const ConstBidirectionalIterator &other) { m_pimpl.reset(other.pimpl() ? other.pimpl()->clone() : nullptr); return *this; } /*! * \brief Move assignment. - * \param other - * \return */ ConstBidirectionalIterator &operator =(ConstBidirectionalIterator &&other) { m_pimpl.reset(other.m_pimpl.take()); return *this; } @@ -238,20 +216,17 @@ namespace BlackMisc * \brief Create a new iterator with a specific implementation type. * \tparam C Becomes the iterator's implementation type. * \param c Initial value for the iterator. The value is copied. - * \return */ template static ConstBidirectionalIterator fromImpl(I i) { return ConstBidirectionalIterator(new Pimpl(std::move(i))); } /*! * \brief Returns a reference to the object pointed to. - * \return * \pre The iterator must be initialized and valid. */ const_reference operator *() const { Q_ASSERT(m_pimpl); return **pimpl(); } /*! * \brief Arrow operator provides access to members of the object pointed to. - * \return * \pre The iterator must be initialized and valid. */ const_pointer operator ->() const { Q_ASSERT(m_pimpl); return &**pimpl(); } @@ -286,7 +261,6 @@ namespace BlackMisc /*! * \brief Advance the iterator by a certain amount. - * \param n * \return Reference to the iterator at the new position. * \pre The iterator must be initialized and valid. */ @@ -294,7 +268,6 @@ namespace BlackMisc /*! * \brief Advance the iterator by a certain amount. - * \param n * \return Copy of the iterator in its new position. * \pre The iterator must be initialized and valid. */ @@ -302,7 +275,6 @@ namespace BlackMisc /*! * \brief Backtrack the iterator by a certain amount. - * \param n * \return Reference to the iterator at the new position. * \pre The iterator must be initialized and valid. */ @@ -310,7 +282,6 @@ namespace BlackMisc /*! * \brief Backtrack the iterator by a certain amount. - * \param n * \return Copy of the iterator in its new position. * \pre The iterator must be initialized and valid. */ @@ -318,39 +289,30 @@ namespace BlackMisc /*! * \brief Return the distance between two iterators. - * \param other - * \return * \pre Both iterators must originate from the same collection, and not mix begin/end with cbegin/cend. */ difference_type operator -(const ConstBidirectionalIterator &other) const { Q_ASSERT(m_pimpl && other.m_pimpl); return *pimpl() - *other.pimpl(); } /*! * \brief Test for equality. - * \param other - * \return * \pre Both iterators must originate from the same collection, and not mix begin/end with cbegin/cend. */ bool operator ==(const ConstBidirectionalIterator &other) const { return (pimpl() && other.pimpl()) ? *pimpl() == *other.pimpl() : pimpl() == other.pimpl(); } /*! * \brief Test for inequality. - * \param other - * \return * \pre Both iterators must originate from the same collection, and not mix begin/end with cbegin/cend. */ bool operator !=(const ConstBidirectionalIterator &other) const { return !(*this == other); } /*! * \brief For sorting. - * \param other - * \return * \pre Both iterators must originate from the same collection, and not mix begin/end with cbegin/cend. */ bool operator <(const ConstBidirectionalIterator &other) const { Q_ASSERT(m_pimpl && other.m_pimpl); return *pimpl() < *other.pimpl(); } /*! * \brief Return opaque pointer to underlying implementation iterator object. - * \return * \pre The iterator must have been initialized. * \todo Returning by void* is rotten, but GCC gives a very cryptic error if I make it a function template with a cast inside. */ @@ -428,27 +390,21 @@ namespace BlackMisc /*! * \brief Copy constructor. - * \param other */ BidirectionalIterator(const BidirectionalIterator &other) : m_pimpl(other.pimpl() ? other.pimpl()->clone() : nullptr) {} /*! * \brief Move constructor. - * \param other */ BidirectionalIterator(BidirectionalIterator &&other) : m_pimpl(other.m_pimpl.take()) {} /*! * \brief Copy assignment. - * \param other - * \return */ BidirectionalIterator &operator =(const BidirectionalIterator &other) { m_pimpl.reset(other.pimpl() ? other.pimpl()->clone() : nullptr); return *this; } /*! * \brief Move assignment. - * \param other - * \return */ BidirectionalIterator &operator =(BidirectionalIterator &&other) { m_pimpl.reset(other.m_pimpl.take()); return *this; } @@ -456,34 +412,29 @@ namespace BlackMisc * \brief Create a new iterator with a specific implementation type. * \tparam C Becomes the iterator's implementation type. * \param c Initial value for the iterator. The value is copied. - * \return */ template static BidirectionalIterator fromImpl(I i) { return BidirectionalIterator(new Pimpl(std::move(i))); } /*! * \brief Returns a reference to the object pointed to. - * \return * \pre The iterator must be initialized and valid. */ const_reference operator *() const { Q_ASSERT(m_pimpl); return **pimpl(); } /*! * \brief Returns a reference to the object pointed to. - * \return * \pre The iterator must be initialized and valid. */ reference operator *() { Q_ASSERT(m_pimpl); return **pimpl(); } /*! * \brief Arrow operator provides access to members of the object pointed to. - * \return * \pre The iterator must be initialized and valid. */ const_pointer operator ->() const { Q_ASSERT(m_pimpl); return &**pimpl(); } /*! * \brief Arrow operator provides access to members of the object pointed to. - * \return * \pre The iterator must be initialized and valid. */ pointer operator ->() { Q_ASSERT(m_pimpl); return &**pimpl(); } @@ -518,7 +469,6 @@ namespace BlackMisc /*! * \brief Advance the iterator by a certain amount. - * \param n * \return Reference to the iterator at the new position. * \pre The iterator must be initialized and valid. */ @@ -526,7 +476,6 @@ namespace BlackMisc /*! * \brief Advance the iterator by a certain amount. - * \param n * \return Copy of the iterator in its new position. * \pre The iterator must be initialized and valid. */ @@ -534,7 +483,6 @@ namespace BlackMisc /*! * \brief Backtrack the iterator by a certain amount. - * \param n * \return Reference to the iterator at the new position. * \pre The iterator must be initialized and valid. */ @@ -542,7 +490,6 @@ namespace BlackMisc /*! * \brief Backtrack the iterator by a certain amount. - * \param n * \return Copy of the iterator in its new position. * \pre The iterator must be initialized and valid. */ @@ -550,39 +497,30 @@ namespace BlackMisc /*! * \brief Return the distance between two iterators. - * \param other - * \return * \pre Both iterators must originate from the same collection, and not mix begin/end with cbegin/cend. */ difference_type operator -(const BidirectionalIterator &other) const { Q_ASSERT(m_pimpl && other.m_pimpl); return *pimpl() - *other.pimpl(); } /*! * \brief Test for equality. - * \param other - * \return * \pre Both iterators must originate from the same collection, and not mix begin/end with cbegin/cend. */ bool operator ==(const BidirectionalIterator &other) const { return (pimpl() && other.pimpl()) ? *pimpl() == *other.pimpl() : pimpl() == other.pimpl(); } /*! * \brief Test for inequality. - * \param other - * \return * \pre Both iterators must originate from the same collection, and not mix begin/end with cbegin/cend. */ bool operator !=(const BidirectionalIterator &other) const { return !(*this == other); } /*! * \brief For sorting. - * \param other - * \return * \pre Both iterators must originate from the same collection, and not mix begin/end with cbegin/cend. */ bool operator <(const BidirectionalIterator &other) const { Q_ASSERT(m_pimpl && other.m_pimpl); return *pimpl() < *other.pimpl(); } /*! * \brief Return opaque pointer to underlying implementation iterator object. - * \return * \pre The iterator must have been initialized. * \todo Returning by void* is rotten, but GCC gives a very cryptic error if I make it a function template with a cast inside. */ diff --git a/src/blackmisc/sequence.h b/src/blackmisc/sequence.h index af9de197a..ac8d30efe 100644 --- a/src/blackmisc/sequence.h +++ b/src/blackmisc/sequence.h @@ -52,27 +52,21 @@ namespace BlackMisc /*! * \brief Copy constructor. - * \param other */ CSequence(const CSequence &other) : m_pimpl(other.pimpl() ? other.pimpl()->clone() : nullptr) {} /*! * \brief Move constructor. - * \param other */ CSequence(CSequence &&other) : m_pimpl(other.m_pimpl.take()) {} /*! * \brief Copy assignment. - * \param other - * \return */ CSequence &operator =(const CSequence &other) { m_pimpl.reset(other.pimpl() ? other.pimpl()->clone() : nullptr); return *this; } /*! * \brief Move assignment. - * \param other - * \return */ CSequence &operator =(CSequence &&other) { m_pimpl.reset(other.m_pimpl.take()); return *this; } @@ -80,7 +74,6 @@ namespace BlackMisc * \brief Create a new sequence with a specific implementation type. * \tparam C Becomes the sequence's implementation type. * \param c Initial value for the sequence; default is empty, but it could contain elements if desired. The value is copied. - * \return */ template static CSequence fromImpl(C c = C()) { return CSequence(new Pimpl(std::move(c))); } @@ -92,112 +85,93 @@ namespace BlackMisc /*! * \brief Like changeImpl, but uses the implementation type of another sequence. - * \param other * \pre The other sequence must be initialized. */ void useImplOf(const CSequence &other) { PimplPtr p = other.pimpl()->cloneEmpty(); for (auto i = cbegin(); i != cend(); ++i) p->push_back(*i); m_pimpl.reset(p.take()); } /*! * \brief Returns iterator at the beginning of the sequence. - * \return */ iterator begin() { return pimpl() ? pimpl()->begin() : iterator(); } /*! * \brief Returns iterator at the beginning of the sequence. - * \return */ const_iterator begin() const { return pimpl() ? pimpl()->begin() : const_iterator(); } /*! * \brief Returns iterator at the beginning of the sequence. - * \return */ const_iterator cbegin() const { return pimpl() ? pimpl()->cbegin() : const_iterator(); } /*! * \brief Returns iterator one past the end of the sequence. - * \return */ iterator end() { return pimpl() ? pimpl()->end() : iterator(); } /*! * \brief Returns iterator one past the end of the sequence. - * \return */ const_iterator end() const { return pimpl() ? pimpl()->end() : const_iterator(); } /*! * \brief Returns iterator one past the end of the sequence. - * \return */ const_iterator cend() const { return pimpl() ? pimpl()->cend() : const_iterator(); } /*! * \brief Swap this sequence with another. - * \param other */ void swap(CSequence &other) { m_pimpl.swap(other.m_pimpl); } /*! * \brief Access an element by its index. - * \param index - * \return * \pre The sequence must be initialized and the index in bounds. */ reference operator [](size_type index) { Q_ASSERT(pimpl()); return pimpl()->operator [](index); } /*! * \brief Access an element by its index. - * \param index - * \return * \pre The sequence must be initialized and the index in bounds. */ const_reference operator [](size_type index) const { Q_ASSERT(pimpl()); return pimpl()->operator [](index); } /*! * \brief Access the first element. - * \return * \pre The sequence must not be empty. */ reference front() { Q_ASSERT(!empty()); return pimpl()->front(); } /*! * \brief Access the first element. - * \return * \pre The sequence must not be empty. */ const_reference front() const { Q_ASSERT(!empty()); return pimpl()->front(); } /*! * \brief Access the last element. - * \return * \pre The sequence must not be empty. */ reference back() { Q_ASSERT(!empty()); return pimpl()->back(); } /*! * \brief Access the last element. - * \return * \pre The sequence must not be empty. */ const_reference back() const { Q_ASSERT(!empty()); return pimpl()->back(); } /*! * \brief Returns number of elements in the sequence. - * \return */ size_type size() const { return pimpl() ? pimpl()->size() : 0; } /*! * \brief Returns true if the sequence is empty. - * \return */ bool empty() const { return pimpl() ? pimpl()->empty() : true; } /*! * \brief Synonym for empty. - * \return */ bool isEmpty() const { return empty(); } @@ -208,8 +182,6 @@ namespace BlackMisc /*! * \brief Inserts an element into the sequence. - * \param before - * \param value * \return An iterator to the position where value was inserted. * \pre The sequence must be initialized. */ @@ -217,14 +189,12 @@ namespace BlackMisc /*! * \brief Appends an element at the end of the sequence. - * \param value * \pre The sequence must be initialized. */ void push_back(const T &value) { Q_ASSERT(pimpl()); pimpl()->push_back(value); } /*! * \brief Synonym for push_back. - * \param value * \pre The sequence must be initialized. */ void insert(const T &value) { push_back(value); } @@ -237,7 +207,6 @@ namespace BlackMisc /*! * \brief Remove the element pointed to by the given iterator. - * \param pos * \return An iterator to the position of the next element after the one removed. * \pre The sequence must be initialized. */ @@ -245,8 +214,6 @@ namespace BlackMisc /*! * \brief Remove the range of elements between two iterators. - * \param it1 - * \param it2 * \return An iterator to the position of the next element after the one removed. * \pre The sequence must be initialized. */ @@ -254,8 +221,6 @@ namespace BlackMisc /*! * \brief Modify by applying a value map to each element for which a given predicate returns true. - * \param p - * \param newValues */ template void applyIf(Predicate p, const CValueMap &newValues) @@ -267,7 +232,6 @@ namespace BlackMisc * \brief Modify by applying a value map to each element matching a particular key/value pair. * \param key1 A pointer to a member function of T. * \param value1 Will be compared to the return value of key1. - * \param newValues */ template void applyIf(K1 key1, V1 value1, const CValueMap &newValues) @@ -277,18 +241,50 @@ namespace BlackMisc /*! * \brief Modify by applying a value map to each element matching a given value map. - * \param pattern - * \param newValues */ void applyIf(const CValueMap &pattern, const CValueMap &newValues) { applyIf([ & ](const T &value) { return value == pattern; }, newValues); } + /*! + * \brief Remove elements for which a given predicate returns true. + */ + template + void removeIf(Predicate p) + { + std::remove_if(begin(), end(), p); + } + + /*! + * \brief Remove elements matching a particular key/value pair. + * \param key1 A pointer to a member function of T. + * \param value1 Will be compared to the return value of key1. + */ + template + void removeIf(K1 key1, V1 value1) + { + removeIf(BlackMisc::Predicates::MemberEqual(key1, value1)); + } + + /*! + * \brief Remove the given object, if it is contained. + */ + void remove(const T &object) + { + std::remove(begin(), end(), object); + } + + /*! + * \brief Replace elements matching the given element with a replacement. + */ + void replace(const T &original, const T &replacement) + { + std::replace(begin(), end(), original, replacement); + } + /*! * \brief Replace elements for which a given predicate returns true. - * \param p - * \param replacement */ template void replaceIf(Predicate p, const T &replacement) @@ -300,7 +296,6 @@ namespace BlackMisc * \brief Replace elements matching a particular key/value pair. * \param key1 A pointer to a member function of T. * \param value1 Will be compared to the return value of key1. - * \param replacement */ template void replaceIf(K1 key1, V1 value1, const T &replacement) @@ -310,8 +305,6 @@ namespace BlackMisc /*! * \brief Replace elements for which a given predicate returns true. If there is no match, push the new element on the end. - * \param p - * \param replacement */ template void replaceOrAdd(Predicate p, const T &replacement) @@ -320,11 +313,19 @@ namespace BlackMisc else { push_back(replacement); } } + /*! + * \brief Replace elements matching the given element. If there is no match, push the new element on the end. + */ + void replaceOrAdd(const T &original, const T &replacement) + { + if (this->contains(original)) { replace(original, replacement); } + else { push_back(replacement); } + } + /*! * \brief Replace elements matching a particular key/value pair. If there is no match, push the new element on the end. * \param key1 A pointer to a member function of T. * \param value1 Will be compared to the return value of key1. - * \param replacement */ template void replaceOrAdd(K1 key1, V1 value1, const T &replacement) @@ -335,7 +336,6 @@ namespace BlackMisc /*! * \brief In-place sort by a given comparator predicate. - * \param p */ template void sort(Predicate p) { @@ -374,8 +374,6 @@ namespace BlackMisc /*! * \brief Return a copy sorted by a given comparator predicate. - * \param p - * \return */ template CSequence sorted(Predicate p) const @@ -388,7 +386,6 @@ namespace BlackMisc /*! * \brief Return a copy sorted by a particular key. * \param key1 A pointer to a member function of T. - * \return */ template CSequence sortedBy(K1 key1) const @@ -400,7 +397,6 @@ namespace BlackMisc * \brief Return a copy sorted by some particular keys. * \param key1 A pointer to a member function of T. * \param key2 A pointer to a member function of T. - * \return */ template CSequence sortedBy(K1 key1, K2 key2) const @@ -413,7 +409,6 @@ namespace BlackMisc * \param key1 A pointer to a member function of T. * \param key2 A pointer to a member function of T. * \param key3 A pointer to a member function of T. - * \return */ template CSequence sortedBy(K1 key1, K2 key2, K3 key3) const @@ -423,16 +418,12 @@ namespace BlackMisc /*! * \brief Test for equality. - * \param other - * \return * \todo Improve inefficient implementation. */ bool operator ==(const CSequence &other) const { return (empty() && other.empty()) ? true : (size() != other.size() ? false : *pimpl() == *other.pimpl()); } /*! * \brief Test for inequality. - * \param other - * \return * \todo Improve inefficient implementation. */ bool operator !=(const CSequence &other) const { return !(*this == other); } diff --git a/tests/blackcore/testnetwork.cpp b/tests/blackcore/testnetwork.cpp index 3dc24cf45..1db3e1441 100644 --- a/tests/blackcore/testnetwork.cpp +++ b/tests/blackcore/testnetwork.cpp @@ -15,38 +15,42 @@ using namespace BlackMisc::PhysicalQuantities; void BlackCoreTest::CTestNetwork::networkTest(BlackCore::INetwork *net) { + QString string = net->connectionStatusToString(INetwork::Connected); + QVERIFY(string == "Connected"); + Expect e(net); EXPECT_UNIT(e) - .send(&INetwork::setServer, CServer("", "", "vatsim-germany.org", 6809, CUser("guest", "", "", "guest"))) - .send(&INetwork::setCallsign, "BLACK") + .send(&INetwork::presetServer, CServer("", "", "vatsim-germany.org", 6809, CUser("guest", "", "", "guest"))) + .send(&INetwork::presetCallsign, "BLACK") + .send(&INetwork::presetIcaoCodes, CAircraftIcao("C172", "P1L", "YYY", "YYY", "white")) .send(&INetwork::initiateConnection) .expect(&INetwork::connectionStatusChanged, [](INetwork::ConnectionStatus, INetwork::ConnectionStatus newStatus) { QVERIFY(newStatus == INetwork::Connecting); qDebug() << "CONNECTING"; - } - ).expect(&INetwork::connectionStatusChanged, [](INetwork::ConnectionStatus, INetwork::ConnectionStatus newStatus) + }) + .expect(&INetwork::connectionStatusChanged, [](INetwork::ConnectionStatus, INetwork::ConnectionStatus newStatus) { QVERIFY(newStatus == INetwork::Connected); qDebug() << "CONNECTED"; - } - ).wait(10); + }) + .wait(10); EXPECT_UNIT(e) - .send(&INetwork::ping, "server") - .expect(&INetwork::pong, [](CCallsign callsign, PhysicalQuantities::CTime elapsedTime) + .send(&INetwork::sendPing, "server") + .expect(&INetwork::pongReceived, [](CCallsign callsign, PhysicalQuantities::CTime elapsedTime) { qDebug() << "PONG" << callsign << elapsedTime; - } - ).wait(10); + }) + .wait(10); EXPECT_UNIT(e) .send(&INetwork::terminateConnection) - .expect(&INetwork::connectionStatusChanged, [](INetwork::ConnectionStatus s) + .expect(&INetwork::connectionStatusChanged, [](INetwork::ConnectionStatus, INetwork::ConnectionStatus newStatus) { - QVERIFY(s == INetwork::Disconnected); + QVERIFY(newStatus == INetwork::Disconnected); qDebug() << "DISCONNECTED"; - } - ).wait(10); + }) + .wait(10); }