refs #395, moved thread safe aircraft parts / situations (from interpolator) to airspace

* access via provider, access now possible also beyond the scope of interpolator
* will be used in (to be written airpace analyzer)
* renamed some member functions as required
* fixed some asserts / Doxygen comments
* adjusted unit tests
* added vtolAircraft flag for interpolator, not fully used everywhere

remarks: update signals for parts / situation still only needed in XP driver
This commit is contained in:
Klaus Basan
2015-04-21 04:01:09 +02:00
committed by Mathew Sutcliffe
parent 32e65669a3
commit 48188dd28d
17 changed files with 356 additions and 506 deletions

View File

@@ -23,101 +23,18 @@ namespace BlackCore
CContinuousWorker(parent, workerName),
CRemoteAircraftAwareReadOnly(provider)
{
Q_ASSERT(provider);
this->m_situationsByCallsign = this->remoteAircraftSituations().splitPerCallsign();
this->m_partsByCallsign = this->remoteAircraftParts().splitPerCallsign();
bool c = provider->connectRemoteAircraftProviderSignals(
std::bind(&IInterpolator::ps_onAddedAircraftSituation, this, std::placeholders::_1),
std::bind(&IInterpolator::ps_onAddedAircraftParts, this, std::placeholders::_1),
std::bind(&IInterpolator::ps_onRemovedAircraft, this, std::placeholders::_1)
);
Q_ASSERT(c);
Q_UNUSED(c);
Q_ASSERT_X(provider, Q_FUNC_INFO, "missing provider");
}
CAircraftSituationList IInterpolator::getInterpolatedSituations(qint64 currentTimeMsSinceEpoch)
{
QReadLocker l(&m_lockSituations);
const CSituationsPerCallsign situationsCopy(m_situationsByCallsign);
l.unlock();
CAircraftSituationList latestInterpolations;
if (currentTimeMsSinceEpoch < 0) { currentTimeMsSinceEpoch = QDateTime::currentMSecsSinceEpoch(); }
for (const CCallsign &cs : situationsCopy.keys())
{
InterpolationStatus status;
CAircraftSituation situation = getInterpolatedSituation(cs, currentTimeMsSinceEpoch, status, &situationsCopy);
if (status.allTrue())
{
latestInterpolations.push_back(situation);
}
else
{
// not OK can mean not enough situations
// further logging could go here
}
}
return latestInterpolations;
}
IInterpolator::CSituationsPerCallsign IInterpolator::getSituationsByCallsign() const
{
QReadLocker l(&m_lockSituations);
return m_situationsByCallsign;
}
CAircraftPartsList IInterpolator::getAndRemovePartsBeforeTime(const CCallsign &callsign, qint64 cutoffTime, BlackCore::IInterpolator::PartsStatus &partsStatus)
CAircraftPartsList IInterpolator::getPartsBeforeTime(const CCallsign &callsign, qint64 cutoffTime, BlackCore::IInterpolator::PartsStatus &partsStatus)
{
static const CAircraftPartsList empty;
Q_ASSERT_X(!callsign.isEmpty(), "getAndRemovePartsBeforeTime", "empty callsign");
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "empty callsign");
partsStatus.reset();
QWriteLocker l(&m_lockParts);
if (this->m_partsByCallsign.contains(callsign))
{
partsStatus.supportsParts = true;
if (cutoffTime < 0) { return this->m_partsByCallsign[callsign]; }
return this->m_partsByCallsign[callsign].findBeforeAndRemove(cutoffTime);
}
else
{
// did we ever have parts for this callsign
partsStatus.supportsParts = m_aircraftSupportingParts.contains(callsign);
return empty;
}
}
void IInterpolator::clear()
{
QWriteLocker s(&m_lockSituations);
QWriteLocker p(&m_lockParts);
m_situationsByCallsign.clear();
m_partsByCallsign.clear();
}
bool IInterpolator::hasDataForCallsign(const CCallsign &callsign) const
{
if (callsign.isEmpty()) { return false; }
QReadLocker s(&m_lockSituations);
if (m_situationsByCallsign.contains(callsign)) { return true; }
QReadLocker p(&m_lockParts);
return m_partsByCallsign.contains(callsign);
}
CAircraftSituationList IInterpolator::getSituationsForCallsign(const CCallsign &callsign) const
{
QReadLocker l(&m_lockSituations);
static const CAircraftSituationList empty;
if (!m_situationsByCallsign.contains(callsign)) { return empty; }
return m_situationsByCallsign[callsign];
}
CAircraftPartsList IInterpolator::getPartsForCallsign(const CCallsign &callsign) const
{
QReadLocker l(&m_lockParts);
static const CAircraftPartsList empty;
if (!m_partsByCallsign.contains(callsign)) { return empty; }
return m_partsByCallsign[callsign];
partsStatus.supportsParts = this->isRemoteAircraftSupportingParts(callsign);
if (!partsStatus.supportsParts) { return empty; }
return this->remoteAircraftParts(callsign, cutoffTime);
}
void IInterpolator::enableDebugMessages(bool enabled)
@@ -125,61 +42,6 @@ namespace BlackCore
this->m_withDebugMsg = enabled;
}
void IInterpolator::forceSortingOfAddedValues(bool sort)
{
this->m_forceSortWhenAddingValues = sort;
}
void IInterpolator::ps_onAddedAircraftSituation(const CAircraftSituation &situation)
{
QWriteLocker lock(&m_lockSituations);
const CCallsign callsign(situation.getCallsign());
Q_ASSERT_X(!callsign.isEmpty(), "ps_onAddedAircraftSituation", "empty callsign");
if (callsign.isEmpty()) { return; }
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << situation.getCallsign() << situation.getMSecsSinceEpoch(); }
// list from new to old
CAircraftSituationList &l = this->m_situationsByCallsign[callsign];
l.push_frontMaxElements(situation, MaxSituationsPerCallsign);
if (this->m_forceSortWhenAddingValues) { l.sortLatestFirst(); }
// check sort order
Q_ASSERT(l.size() < 2 || l[0].getMSecsSinceEpoch() >= l[1].getMSecsSinceEpoch());
}
void IInterpolator::ps_onAddedAircraftParts(const CAircraftParts &parts)
{
QWriteLocker lock(&m_lockParts);
const CCallsign callsign(parts.getCallsign());
Q_ASSERT_X(!callsign.isEmpty(), "ps_onAddedAircraftParts", "empty callsign");
if (callsign.isEmpty()) { return; }
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << parts.getCallsign() << parts.getMSecsSinceEpoch(); }
// list sorted from new to old
CAircraftPartsList &l = this->m_partsByCallsign[callsign];
l.push_frontMaxElements(parts, MaxPartsPerCallsign);
if (this->m_forceSortWhenAddingValues) { l.sortLatestFirst(); }
if (m_aircraftSupportingParts.contains(callsign)) { return; }
m_aircraftSupportingParts.push_back(callsign); // mark as callsign which supports parts
// check sort order
Q_ASSERT(l.size() < 2 || l[0].getMSecsSinceEpoch() >= l[1].getMSecsSinceEpoch());
}
void IInterpolator::ps_onRemovedAircraft(const CCallsign &callsign)
{
QWriteLocker ls(&m_lockSituations);
QWriteLocker lp(&m_lockParts);
Q_ASSERT(!callsign.isEmpty());
if (callsign.isEmpty()) { return; }
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign; }
this->m_partsByCallsign.remove(callsign);
this->m_situationsByCallsign.remove(callsign);
this->m_aircraftSupportingParts.remove(callsign);
}
bool IInterpolator::InterpolationStatus::allTrue() const
{
return interpolationSucceeded && changedPosition;