refs #533, fixes "CContextSimulator::ps_addRemoteAircraft is never called"

* reordered use of fireDelayedReadyForModelMatching
* better calls / params depending on received packet(FSInn / Icao code)
* fixed search in DB data
* works now with and without DB data present
This commit is contained in:
Klaus Basan
2015-12-02 00:50:00 +01:00
parent 39796f2f06
commit a863f99c9d
6 changed files with 178 additions and 104 deletions

View File

@@ -166,10 +166,8 @@ namespace BlackCore
Q_ASSERT_X(c2, Q_FUNC_INFO, "connect failed"); Q_ASSERT_X(c2, Q_FUNC_INFO, "connect failed");
QMetaObject::Connection c3 = connect(this, &CAirspaceMonitor::removedAircraft, receiver, removedAircraftSlot); QMetaObject::Connection c3 = connect(this, &CAirspaceMonitor::removedAircraft, receiver, removedAircraftSlot);
Q_ASSERT_X(c3, Q_FUNC_INFO, "connect failed"); Q_ASSERT_X(c3, Q_FUNC_INFO, "connect failed");
//! \todo remove old workaround if new version with receiver works
// trick is to use the Queued signal here // trick is to use the Queued signal here
// analyzer (own thread) -> airspaceAircraftSnapshot -> AirspaceMonitor -> airspaceAircraftSnapshot queued in main thread // analyzer (own thread) -> airspaceAircraftSnapshot -> AirspaceMonitor -> airspaceAircraftSnapshot queued in main thread
// QMetaObject::Connection c4 = this->connect(this, &CAirspaceMonitor::airspaceAircraftSnapshot, receiver, aircraftSnapshotSlot);
QMetaObject::Connection c4 = this->connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, receiver, aircraftSnapshotSlot, Qt::QueuedConnection); QMetaObject::Connection c4 = this->connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, receiver, aircraftSnapshotSlot, Qt::QueuedConnection);
Q_ASSERT_X(c4, Q_FUNC_INFO, "connect failed"); Q_ASSERT_X(c4, Q_FUNC_INFO, "connect failed");
return QList<QMetaObject::Connection>({ c1, c2, c3, c4}); return QList<QMetaObject::Connection>({ c1, c2, c3, c4});
@@ -252,7 +250,7 @@ namespace BlackCore
CUserList CAirspaceMonitor::getUsers() const CUserList CAirspaceMonitor::getUsers() const
{ {
CUserList users; CUserList users;
foreach(CAtcStation station, this->m_atcStationsOnline) foreach (CAtcStation station, this->m_atcStationsOnline)
{ {
CUser user = station.getController(); CUser user = station.getController();
users.push_back(user); users.push_back(user);
@@ -482,30 +480,6 @@ namespace BlackCore
if (flags & INetwork::SupportsAircraftConfigs) m_network->sendAircraftConfigQuery(callsign); if (flags & INetwork::SupportsAircraftConfigs) m_network->sendAircraftConfigQuery(callsign);
} }
void CAirspaceMonitor::ps_customFSinnPacketReceived(const CCallsign &callsign, const QString &airlineIcaoDesignator, const QString &aircraftIcaoDesignator, const QString &combinedAircraftType, const QString &model)
{
if (!this->m_connected || callsign.isEmpty() || model.isEmpty()) { return; }
// Request of other client, I can get the other's model from that
Q_UNUSED(combinedAircraftType);
CPropertyIndexVariantMap vm({ CClient::IndexModel, CAircraftModel::IndexModelString }, model);
vm.addValue({ CClient::IndexModel, CAircraftModel::IndexModelType }, static_cast<int>(CAircraftModel::TypeQueriedFromNetwork));
if (!this->m_otherClients.containsCallsign(callsign))
{
// with custom packets it can happen,
// the packet is received before any other packet
this->m_otherClients.push_back(CClient(callsign));
}
this->m_otherClients.applyIf(&CClient::getCallsign, callsign, vm);
// ICAO response from custom data
if (!aircraftIcaoDesignator.isEmpty())
{
// hand over, same functionality as would be needed here
this->ps_icaoCodesReceived(callsign, aircraftIcaoDesignator, airlineIcaoDesignator, "");
}
}
void CAirspaceMonitor::ps_serverReplyReceived(const CCallsign &callsign, const QString &server) void CAirspaceMonitor::ps_serverReplyReceived(const CCallsign &callsign, const QString &server)
{ {
if (!this->m_connected || callsign.isEmpty() || server.isEmpty()) { return; } if (!this->m_connected || callsign.isEmpty() || server.isEmpty()) { return; }
@@ -563,6 +537,7 @@ namespace BlackCore
void CAirspaceMonitor::fireDelayedReadyForModelMatching(const CCallsign &callsign, int trial, int delayMs) void CAirspaceMonitor::fireDelayedReadyForModelMatching(const CCallsign &callsign, int trial, int delayMs)
{ {
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "missing callsign");
BlackMisc::singleShot(delayMs, QThread::currentThread(), [ = ]() BlackMisc::singleShot(delayMs, QThread::currentThread(), [ = ]()
{ {
this->ps_sendReadyForModelMatching(callsign, trial + 1); this->ps_sendReadyForModelMatching(callsign, trial + 1);
@@ -603,22 +578,23 @@ namespace BlackCore
void CAirspaceMonitor::ps_sendReadyForModelMatching(const CCallsign &callsign, int trial) void CAirspaceMonitor::ps_sendReadyForModelMatching(const CCallsign &callsign, int trial)
{ {
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "missing callsign");
// some checks for special conditions, e.g. logout -> empty list, but still signals pending // some checks for special conditions, e.g. logout -> empty list, but still signals pending
CSimulatedAircraft remoteAircraft; CSimulatedAircraft remoteAircraft;
{ {
QReadLocker l(&m_lockAircraft); QReadLocker l(&m_lockAircraft);
if (!this->m_connected || this->m_aircraftInRange.isEmpty()) { return; } if (!this->m_connected) { return; }
if (!this->m_aircraftInRange.containsCallsign(callsign)) { return; }
// build simulated aircraft and crosscheck if all data are available // build simulated aircraft and crosscheck if all data are available
remoteAircraft = CSimulatedAircraft(this->m_aircraftInRange.findFirstByCallsign(callsign)); remoteAircraft = CSimulatedAircraft(this->m_aircraftInRange.findFirstByCallsign(callsign));
Q_ASSERT_X(remoteAircraft.hasValidCallsign(), Q_FUNC_INFO, "Invalid callsign");
} }
// check if the name and ICAO query went properly through // check if the name and ICAO query went properly through,
bool dataComplete = // those usually means the aircraft are in range and can be used
remoteAircraft.hasAircraftDesignator() && bool inRange = remoteAircraft.hasValidCallsign();
(!m_serverSupportsNameQuery || remoteAircraft.getModel().hasModelString()); bool dataComplete = inRange && remoteAircraft.hasAircraftDesignator() &&
(!m_serverSupportsNameQuery || remoteAircraft.getModel().hasModelString());
if (trial < 3 && !dataComplete) if (trial < 3 && !dataComplete)
{ {
@@ -627,8 +603,21 @@ namespace BlackCore
return; return;
} }
Q_ASSERT(remoteAircraft.hasAircraftDesignator()); if (!inRange)
Q_ASSERT(!m_serverSupportsNameQuery || remoteAircraft.hasValidRealName()); {
// here we assume user has logged out, incomplete data because of traffic sim, etc.
CLogMessage(this).debug() << "Aircraft not in range anymore " << callsign.toQString();
return;
}
if (!dataComplete)
{
// even after all the trials, still no designator
// something is wrong here
CLogMessage(this).warning("Cannot retrieve model information for %1") << callsign.toQString();
return; // maybe we like to continue here, hard so say
}
Q_ASSERT_X(!m_serverSupportsNameQuery || remoteAircraft.hasValidRealName(), Q_FUNC_INFO, "invalid model data");
emit this->readyForModelMatching(remoteAircraft); emit this->readyForModelMatching(remoteAircraft);
} }
@@ -764,12 +753,40 @@ namespace BlackCore
} }
} }
void CAirspaceMonitor::ps_customFSinnPacketReceived(const CCallsign &callsign, const QString &airlineIcaoDesignator, const QString &aircraftIcaoDesignator, const QString &combinedAircraftType, const QString &model)
{
if (!this->m_connected || callsign.isEmpty() || model.isEmpty()) { return; }
// Request of other client, I can get the other's model from that
Q_UNUSED(combinedAircraftType);
CPropertyIndexVariantMap vm({ CClient::IndexModel, CAircraftModel::IndexModelString }, model);
vm.addValue({ CClient::IndexModel, CAircraftModel::IndexModelType }, static_cast<int>(CAircraftModel::TypeQueriedFromNetwork));
if (!this->m_otherClients.containsCallsign(callsign))
{
// with custom packets it can happen that
// the packet is received before any other packet
this->m_otherClients.push_back(CClient(callsign));
}
this->m_otherClients.applyIf(&CClient::getCallsign, callsign, vm); // update client info
// ICAO response from custom data
if (!aircraftIcaoDesignator.isEmpty())
{
// hand over, same functionality as would be needed here
this->icaoOrFsdDataReceived(callsign, aircraftIcaoDesignator, airlineIcaoDesignator, "", model, CAircraftModel::TypeFsdData);
}
}
void CAirspaceMonitor::ps_icaoCodesReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &aircraftIcaoDesignator, const QString &airlineIcaoDesignator, const QString &livery) void CAirspaceMonitor::ps_icaoCodesReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &aircraftIcaoDesignator, const QString &airlineIcaoDesignator, const QString &livery)
{
this->icaoOrFsdDataReceived(callsign, aircraftIcaoDesignator, airlineIcaoDesignator, livery, "", CAircraftModel::TypeQueriedFromNetwork);
}
void CAirspaceMonitor::icaoOrFsdDataReceived(const CCallsign &callsign, const QString &aircraftIcaoDesignator, const QString &airlineIcaoDesignator, const QString &livery, const QString &modelString, CAircraftModel::ModelType type)
{ {
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "not in main thread"); Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "not in main thread");
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "no callsign"); Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "no callsign");
if (!this->m_connected) { return; } if (!this->m_connected) { return; }
if (aircraftIcaoDesignator.isEmpty() && airlineIcaoDesignator.isEmpty() && livery.isEmpty()) { return; } if (aircraftIcaoDesignator.isEmpty() && airlineIcaoDesignator.isEmpty() && livery.isEmpty()) { return; }
CSimulatedAircraft remoteAircraft(this->getAircraftInRangeForCallsign(callsign)); CSimulatedAircraft remoteAircraft(this->getAircraftInRangeForCallsign(callsign));
@@ -779,69 +796,97 @@ namespace BlackCore
if (existingAircraft) if (existingAircraft)
{ {
model = remoteAircraft.getModel(); model = remoteAircraft.getModel();
m_modelCache.remove(callsign); m_modelCache.remove(callsign); // normally already removed
} }
else if (m_modelCache.contains(callsign)) else if (m_modelCache.contains(callsign))
{ {
model = m_modelCache[callsign]; model = m_modelCache[callsign];
} }
// already matched with DB? // already matched with DB?
if (model.getModelType() != CAircraftModel::TypeQueriedFromNetwork && model.getModelType() != CAircraftModel::TypeFsdData) { return; } if (!model.canInitializeFromFsd()) { return; }
// update model string if not yet existing
if (!model.hasModelString() && !modelString.isEmpty()) { model.setModelString(modelString); }
if (model.getModelType() == CAircraftModel::TypeUnknown || model.getModelType() == CAircraftModel::TypeQueriedFromNetwork)
{
model.setModelType(type); // update type if no type yet
}
// we have no DB model yet, but do we have model string? // we have no DB model yet, but do we have model string?
if (model.hasModelString()) if (model.hasModelString())
{ {
// if we find the model here we have a fully defined DB model
CAircraftModel modelFromDb(this->getModelForModelString(model.getModelString())); CAircraftModel modelFromDb(this->getModelForModelString(model.getModelString()));
if (modelFromDb.hasValidDbKey()) { model = modelFromDb; } if (modelFromDb.hasValidDbKey()) { model = modelFromDb; }
} }
// only if not yet matched with DB // only if not yet matched with DB
if (!model.hasValidDbKey() && CLivery::isValidCombinedCode(livery)) if (!model.hasValidDbKey())
{ {
CAircraftModelList models(this->getModelsForAircraftDesignatorAndLiveryCombinedCode(aircraftIcaoDesignator, livery)); // try to match by livery
if (models.isEmpty()) if (CLivery::isValidCombinedCode(livery))
{ {
// no models for that livery // search DB model by livery
CLivery databaseLivery(this->getLiveryForCombinedCode(livery)); CAircraftModelList models(this->getModelsForAircraftDesignatorAndLiveryCombinedCode(aircraftIcaoDesignator, livery));
if (databaseLivery.hasValidDbKey()) if (models.isEmpty())
{ {
// we have found a livery in the DB // no models for that livery, search for livery only
model.setLivery(databaseLivery); CLivery databaseLivery(this->getLiveryForCombinedCode(livery));
if (databaseLivery.hasValidDbKey())
{
// we have found a livery in the DB
model.setLivery(databaseLivery);
}
} }
else else
{ {
// create a pseudo livery, try to find airline first // model by livery data found
CAirlineIcaoCode airlineIcao(this->getAirlineIcaoCodeForDesignator(airlineIcaoDesignator)); model = models.front();
if (!airlineIcao.hasValidDbKey()) { airlineIcao = CAirlineIcaoCode(airlineIcaoDesignator); }
CLivery liveryDummy(livery, airlineIcao, "Generated");
model.setLivery(liveryDummy);
} }
}
// if no DB livery, create own dummy livery
if (!model.hasValidDbKey() && !model.getLivery().hasValidDbKey())
{
// create a pseudo livery, try to find airline first
CAirlineIcaoCode airlineIcao(this->getAirlineIcaoCodeForDesignator(airlineIcaoDesignator));
if (!airlineIcao.hasValidDbKey())
{
// no DB data, we update as much as possible
airlineIcao = model.getAirlineIcaoCode();
airlineIcao.updateMissingParts(CAirlineIcaoCode(airlineIcaoDesignator));
}
CLivery liveryDummy(livery, airlineIcao, "Generated");
model.setLivery(liveryDummy);
}
if (!model.getAircraftIcaoCode().hasValidDbKey())
{
CAircraftIcaoCode aircraftIcao(this->getAircraftIcaoCodeForDesignator(aircraftIcaoDesignator)); CAircraftIcaoCode aircraftIcao(this->getAircraftIcaoCodeForDesignator(aircraftIcaoDesignator));
if (!aircraftIcao.hasValidDbKey()) { aircraftIcao = CAircraftIcaoCode(aircraftIcaoDesignator); } if (!aircraftIcao.hasValidDbKey())
model.setModelType(CAircraftModel::TypeFsdData); {
// no DB data, we update as much as possible
aircraftIcao = model.getAircraftIcaoCode();
aircraftIcao.updateMissingParts(CAircraftIcaoCode(aircraftIcaoDesignator));
}
model.setAircraftIcaoCode(aircraftIcao);
}
} // model from DB
{
QWriteLocker l(&m_lockAircraft);
if (this->m_aircraftInRange.containsCallsign(callsign))
{
// we know the aircraft, so we update it
this->m_aircraftInRange.setAircraftModel(callsign, model);
} }
else else
{ {
// model by livery data // keep in cache, as aircraft is not already known
model = models.front();
}
}
int c = 0;
{
QWriteLocker l(&m_lockAircraft);
if (!this->m_aircraftInRange.containsCallsign(callsign))
{
this->m_modelCache.insert(callsign, model); this->m_modelCache.insert(callsign, model);
return;
} }
} // lock
// we know the aircraft, so we update
c = this->m_aircraftInRange.setAircraftModel(callsign, model);
}
if (c > 0) { ps_sendReadyForModelMatching(callsign, 1); }
} }
void CAirspaceMonitor::ps_aircraftUpdateReceived(const CAircraftSituation &situation, const CTransponder &transponder) void CAirspaceMonitor::ps_aircraftUpdateReceived(const CAircraftSituation &situation, const CTransponder &transponder)
@@ -856,9 +901,8 @@ namespace BlackCore
this->storeAircraftSituation(situation); this->storeAircraftSituation(situation);
emit this->addedAircraftSituation(situation); emit this->addedAircraftSituation(situation);
QWriteLocker l(&m_lockAircraft); bool existsInRange = this->m_aircraftInRange.containsCallsign(callsign);
bool exists = this->m_aircraftInRange.containsCallsign(callsign); if (!existsInRange)
if (!exists)
{ {
// new aircraft // new aircraft
CSimulatedAircraft aircraft; CSimulatedAircraft aircraft;
@@ -869,23 +913,27 @@ namespace BlackCore
this->updateWithVatsimDataFileData(aircraft); this->updateWithVatsimDataFileData(aircraft);
// ICAO from cache if avialable // ICAO from cache if avialable
bool setModel = false; bool setModelFromCache = false;
if (this->m_modelCache.contains(callsign))
{ {
CAircraftModel model = this->m_modelCache.value(callsign); CAircraftModel model;
this->m_modelCache.remove(callsign); QWriteLocker l(&m_lockAircraft);
aircraft.setModel(model); if (this->m_modelCache.contains(callsign))
setModel = true; {
} model = this->m_modelCache.value(callsign);
this->m_modelCache.remove(callsign);
aircraft.setModel(model);
setModelFromCache = true;
}
// only place where aircraft is added // only place where aircraft is added
this->m_aircraftInRange.push_back(aircraft); this->m_aircraftInRange.push_back(aircraft);
// new client, there is a chance it has been already created by custom packet // new client, there is a chance it has been already created by custom packet
if (!this->m_otherClients.containsCallsign(callsign)) if (!this->m_otherClients.containsCallsign(callsign))
{ {
CClient c(callsign); CClient c(callsign);
this->m_otherClients.push_back(c); // initial, will be filled by data later this->m_otherClients.push_back(c); // initial, will be filled by data later
}
} }
// only if still connected // only if still connected
@@ -894,7 +942,11 @@ namespace BlackCore
// the order here makes some sense, as we hope to receive ICAO codes last, and everthing else already in place // the order here makes some sense, as we hope to receive ICAO codes last, and everthing else already in place
// Send a custom FSinn query only if we don't have the exact model yet // Send a custom FSinn query only if we don't have the exact model yet
CClient c = this->m_otherClients.findByCallsign(callsign).frontOrDefault(); CClient c;
{
QReadLocker l(&m_lockAircraft);
c = this->m_otherClients.findByCallsign(callsign).frontOrDefault();
}
CAircraftModel::ModelType modelType = c.getAircraftModel().getModelType(); CAircraftModel::ModelType modelType = c.getAircraftModel().getModelType();
if (modelType != CAircraftModel::TypeQueriedFromNetwork && modelType != CAircraftModel::TypeDatabaseEntry) if (modelType != CAircraftModel::TypeQueriedFromNetwork && modelType != CAircraftModel::TypeDatabaseEntry)
{ {
@@ -905,14 +957,19 @@ namespace BlackCore
this->m_network->sendCapabilitiesQuery(callsign); this->m_network->sendCapabilitiesQuery(callsign);
this->m_network->sendServerQuery(callsign); this->m_network->sendServerQuery(callsign);
// keep as last // do this as last thing
if (setModel) if (setModelFromCache)
{ {
this->fireDelayedReadyForModelMatching(callsign); // we have had at least some information,
// means either ICAO codes or FSInn package has already been received
this->ps_sendReadyForModelMatching(callsign, 1);
} }
else else
{ {
// no info yet, query ICAO codes at least
// allow some time for the data to arrive before ready for model matching
this->m_network->sendIcaoCodesQuery(callsign); this->m_network->sendIcaoCodesQuery(callsign);
this->fireDelayedReadyForModelMatching(callsign);
} }
emit this->addedAircraft(aircraft); emit this->addedAircraft(aircraft);
} // connected } // connected
@@ -928,7 +985,10 @@ namespace BlackCore
vm.addValue(CSimulatedAircraft::IndexDistanceToOwnAircraft, distance); vm.addValue(CSimulatedAircraft::IndexDistanceToOwnAircraft, distance);
// here I expect always a changed value // here I expect always a changed value
this->m_aircraftInRange.applyIfCallsign(callsign, vm); {
QWriteLocker l(&m_lockAircraft);
this->m_aircraftInRange.applyIfCallsign(callsign, vm);
}
} }
emit this->changedAircraftInRange(); emit this->changedAircraftInRange();
@@ -946,25 +1006,25 @@ namespace BlackCore
// Interim packets do not have groundspeed, hence set the last known value. // Interim packets do not have groundspeed, hence set the last known value.
// If there is no full position available yet, throw this interim position away. // If there is no full position available yet, throw this interim position away.
CAircraftSituation iterimSituation(situation); CAircraftSituation interimSituation(situation);
{ {
QReadLocker l(&m_lockSituations); QReadLocker l(&m_lockSituations);
auto history = this->m_situationsByCallsign[callsign]; auto history = this->m_situationsByCallsign[callsign];
if (history.empty()) { return; } // we need one full situation if (history.empty()) { return; } // we need one full situation
iterimSituation.setCurrentUtcTime(); interimSituation.setCurrentUtcTime();
iterimSituation.setGroundspeed(history.latestValue().getGroundSpeed()); interimSituation.setGroundspeed(history.latestValue().getGroundSpeed());
} }
// store situation history // store situation history
this->storeAircraftSituation(iterimSituation); this->storeAircraftSituation(interimSituation);
emit this->addedAircraftSituation(iterimSituation); emit this->addedAircraftSituation(interimSituation);
// update aircraft // update aircraft
//! \todo skip aircraft updates for interim positions as for performance reasons //! \todo skip aircraft updates for interim positions as for performance reasons
CLength distance = getOwnAircraft().calculateGreatCircleDistance(iterimSituation.getPosition()); CLength distance = getOwnAircraft().calculateGreatCircleDistance(interimSituation.getPosition());
distance.switchUnit(CLengthUnit::NM()); // lloks nicer distance.switchUnit(CLengthUnit::NM()); // lloks nicer
CPropertyIndexVariantMap vm; CPropertyIndexVariantMap vm;
vm.addValue(CSimulatedAircraft::IndexSituation, iterimSituation); vm.addValue(CSimulatedAircraft::IndexSituation, interimSituation);
vm.addValue(CSimulatedAircraft::IndexDistanceToOwnAircraft, distance); vm.addValue(CSimulatedAircraft::IndexDistanceToOwnAircraft, distance);
// here I expect always a changed value // here I expect always a changed value

View File

@@ -217,7 +217,7 @@ namespace BlackCore
BlackMisc::Aviation::CCallsignSet m_aircraftSupportingParts; //!< aircraft supporting parts, thread safe access required BlackMisc::Aviation::CCallsignSet m_aircraftSupportingParts; //!< aircraft supporting parts, thread safe access required
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CFlightPlan> m_flightPlanCache; QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CFlightPlan> m_flightPlanCache;
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Simulation::CAircraftModel> m_modelCache; QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Simulation::CAircraftModel> m_modelCache; //!< any model information recevived from network temporarily stored until it is "completed". Will be removed when aircraft is moved to aircraft in range
INetwork *m_network = nullptr; INetwork *m_network = nullptr;
CAirspaceAnalyzer *m_analyzer = nullptr; //!< owned analyzer CAirspaceAnalyzer *m_analyzer = nullptr; //!< owned analyzer
@@ -246,6 +246,9 @@ namespace BlackCore
//! Schedule a ready for model matching //! Schedule a ready for model matching
void fireDelayedReadyForModelMatching(const BlackMisc::Aviation::CCallsign &callsign, int trial = 1, int delayMs = 2500); void fireDelayedReadyForModelMatching(const BlackMisc::Aviation::CCallsign &callsign, int trial = 1, int delayMs = 2500);
//! FSD or icao query received
void icaoOrFsdDataReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &aircraftIcaoDesignator, const QString &airlineIcaoDesignator, const QString &livery, const QString &modelString, BlackMisc::Simulation::CAircraftModel::ModelType type);
//! Store an aircraft situation //! Store an aircraft situation
//! \threadsafe //! \threadsafe
void storeAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation); void storeAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);

View File

@@ -41,8 +41,8 @@ namespace BlackMisc
CAirlineIcaoCode CAirlineIcaoCodeList::findByVDesignator(const QString &designator) CAirlineIcaoCode CAirlineIcaoCodeList::findByVDesignator(const QString &designator)
{ {
if (CAirlineIcaoCode::isValidAirlineDesignator(designator)) { return CAirlineIcaoCode(); } if (!CAirlineIcaoCode::isValidAirlineDesignator(designator)) { return CAirlineIcaoCode(); }
return this->findFirstBy([&](const CAirlineIcaoCode & code) return this->findFirstByOrDefault([&](const CAirlineIcaoCode & code)
{ {
return code.matchesVDesignator(designator); return code.matchesVDesignator(designator);
}); });

View File

@@ -142,6 +142,14 @@ namespace BlackMisc
} }
} }
bool CAircraftModel::canInitializeFromFsd() const
{
bool nw = this->getModelType() == CAircraftModel::TypeQueriedFromNetwork ||
this->getModelType() == CAircraftModel::TypeFsdData ||
this->getModelType() == CAircraftModel::TypeUnknown;
return nw;
}
int CAircraftModel::comparePropertyByIndex(const CAircraftModel &compareValue, const CPropertyIndex &index) const int CAircraftModel::comparePropertyByIndex(const CAircraftModel &compareValue, const CPropertyIndex &index) const
{ {
if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::comparePropertyByIndex(compareValue, index);} if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::comparePropertyByIndex(compareValue, index);}

View File

@@ -94,6 +94,9 @@ namespace BlackMisc
//! \copydoc CValueObject::setPropertyByIndex //! \copydoc CValueObject::setPropertyByIndex
void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index);
//! Can be initialized from FSD
bool canInitializeFromFsd() const;
//! Compare for index //! Compare for index
int comparePropertyByIndex(const CAircraftModel &compareValue, const CPropertyIndex &index) const; int comparePropertyByIndex(const CAircraftModel &compareValue, const CPropertyIndex &index) const;

View File

@@ -48,7 +48,7 @@ namespace BlackMisc
CAircraftModel CAircraftModelList::findFirstByModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const CAircraftModel CAircraftModelList::findFirstByModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const
{ {
return this->findFirstBy([ = ](const CAircraftModel & model) return this->findFirstByOrDefault([ = ](const CAircraftModel & model)
{ {
return model.matchesModelString(modelString, sensitivity); return model.matchesModelString(modelString, sensitivity);
}); });