mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-06 18:25:37 +08:00
Ref T243, adjust offset for timestamp based objects when keeping the order
This commit is contained in:
@@ -238,11 +238,7 @@ namespace BlackMisc
|
||||
return emptyParts;
|
||||
}
|
||||
|
||||
// with the latest updates of T243 the order and the offsets are supposed to be correct
|
||||
// so even mixing fast/slow updates shall work
|
||||
Q_ASSERT_X(m_aircraftParts.isSortedAdjustedLatestFirst(), Q_FUNC_INFO, "Wrong sort order");
|
||||
|
||||
// Ref T243, KB 2018-02, can be removed in future, we verify parts above
|
||||
// Ref T243, KB 2018-02, can be removed in future, we verify parts when we add parts
|
||||
// Parts are supposed to be in correct order
|
||||
// const auto end = std::is_sorted_until(m_aircraftParts.begin(), m_aircraftParts.end(), [](auto && a, auto && b) { return b.getAdjustedMSecsSinceEpoch() < a.getAdjustedMSecsSinceEpoch(); });
|
||||
// const auto validParts = makeRange(m_aircraftParts.begin(), end);
|
||||
@@ -328,36 +324,54 @@ namespace BlackMisc
|
||||
}
|
||||
|
||||
// we add new situations at front and keep the latest values (real time) first
|
||||
m_aircraftSituations.push_frontKeepLatestFirst(situation, IRemoteAircraftProvider::MaxSituationsPerCallsign);
|
||||
m_aircraftSituations.push_frontKeepLatestFirstAdjustOffset(situation, IRemoteAircraftProvider::MaxSituationsPerCallsign);
|
||||
|
||||
|
||||
// with the latest updates of T243 the order and the offsets are supposed to be correct
|
||||
// so even mixing fast/slow updates shall work
|
||||
Q_ASSERT_X(!m_aircraftSituations.containsZeroOrNegativeOffsetTime(), Q_FUNC_INFO, "Missing offset time");
|
||||
Q_ASSERT_X(m_aircraftSituations.isSortedAdjustedLatestFirst(), Q_FUNC_INFO, "Wrong sort order");
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
void CInterpolator<Derived>::addAircraftParts(const CAircraftParts &parts)
|
||||
{
|
||||
const bool hasOffset = parts.hasOffsetTime();
|
||||
const qint64 offset =
|
||||
hasOffset ?
|
||||
parts.getTimeOffsetMs() :
|
||||
m_aircraftSituations.isEmpty() ? IRemoteAircraftProvider::DefaultOffsetTimeMs : m_aircraftSituations.front().getTimeOffsetMs();
|
||||
if (!hasOffset)
|
||||
{
|
||||
const qint64 offset =
|
||||
hasOffset ?
|
||||
parts.getTimeOffsetMs() :
|
||||
m_aircraftSituations.isEmpty() ? IRemoteAircraftProvider::DefaultOffsetTimeMs : m_aircraftSituations.front().getTimeOffsetMs();
|
||||
CAircraftParts copy(parts);
|
||||
copy.setTimeOffsetMs(offset);
|
||||
CInterpolator<Derived>::addAircraftParts(copy);
|
||||
return;
|
||||
}
|
||||
|
||||
// here we have an offset
|
||||
Q_ASSERT_X(parts.hasOffsetTime(), Q_FUNC_INFO, "Missing parts offset");
|
||||
if (m_aircraftParts.isEmpty())
|
||||
{
|
||||
// make sure we have enough parts to do start interpolating immediately without waiting for more updates
|
||||
// the offsets here (addMSecs) do not really matter
|
||||
CAircraftParts copy(parts);
|
||||
copy.setTimeOffsetMs(offset);
|
||||
copy.addMsecs(-2 * offset);
|
||||
copy.addMsecs(-2 * parts.getTimeOffsetMs());
|
||||
m_aircraftParts.push_frontKeepLatestFirst(copy);
|
||||
copy.addMsecs(offset);
|
||||
copy.addMsecs(parts.getTimeOffsetMs());
|
||||
m_aircraftParts.push_frontKeepLatestFirst(copy);
|
||||
}
|
||||
|
||||
// we add new situations at front and keep the latest values (real time) first
|
||||
m_aircraftParts.push_frontKeepLatestFirst(parts, IRemoteAircraftProvider::MaxSituationsPerCallsign);
|
||||
if (!hasOffset) { m_aircraftParts.front().setTimeOffsetMs(offset); }
|
||||
m_aircraftParts.push_frontKeepLatestFirstAdjustOffset(parts, IRemoteAircraftProvider::MaxSituationsPerCallsign);
|
||||
|
||||
// force remote provider to cleanup
|
||||
IRemoteAircraftProvider::removeOutdatedParts(m_aircraftParts);
|
||||
|
||||
// with the latest updates of T243 the order and the offsets are supposed to be correct
|
||||
// so even mixing fast/slow updates shall work
|
||||
Q_ASSERT_X(!m_aircraftParts.containsZeroOrNegativeOffsetTime(), Q_FUNC_INFO, "Missing offset time");
|
||||
Q_ASSERT_X(m_aircraftParts.isSortedAdjustedLatestFirst(), Q_FUNC_INFO, "Wrong sort order");
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
|
||||
@@ -232,17 +232,18 @@ namespace BlackMisc
|
||||
{
|
||||
c.truncate(maxElements - 1);
|
||||
}
|
||||
if (!c.isEmpty() && value.isOlderThan(c.front()))
|
||||
const bool needSort = !c.isEmpty() && value.isOlderThan(c.front());
|
||||
c.push_front(value);
|
||||
if (needSort)
|
||||
{
|
||||
ITimestampObjectList::sortLatestFirst();
|
||||
}
|
||||
c.push_front(value);
|
||||
}
|
||||
|
||||
template<class OBJ, class CONTAINER>
|
||||
bool ITimestampObjectList<OBJ, CONTAINER>::isSortedLatestLast() const
|
||||
{
|
||||
if (this->container().isEmpty()) { return true; }
|
||||
if (this->container().size() < 2) { return true; }
|
||||
qint64 max = -1;
|
||||
for (const ITimestampBased &obj : this->container())
|
||||
{
|
||||
@@ -257,7 +258,7 @@ namespace BlackMisc
|
||||
template<class OBJ, class CONTAINER>
|
||||
bool ITimestampObjectList<OBJ, CONTAINER>::isSortedLatestFirst() const
|
||||
{
|
||||
if (this->container().isEmpty()) { return true; }
|
||||
if (this->container().size() < 2) { return true; }
|
||||
qint64 min = std::numeric_limits <qint64>::max();
|
||||
for (const ITimestampBased &obj : this->container())
|
||||
{
|
||||
@@ -282,6 +283,16 @@ namespace BlackMisc
|
||||
this->container().sort(Predicates::MemberLess(&OBJ::getAdjustedMSecsSinceEpoch));
|
||||
}
|
||||
|
||||
template<class OBJ, class CONTAINER>
|
||||
bool ITimestampWithOffsetObjectList<OBJ, CONTAINER>::containsZeroOrNegativeOffsetTime() const
|
||||
{
|
||||
for (const ITimestampWithOffsetBased &obj : this->container())
|
||||
{
|
||||
if (obj.getTimeOffsetMs() <= 0) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class OBJ, class CONTAINER>
|
||||
ITimestampWithOffsetObjectList<OBJ, CONTAINER>::ITimestampWithOffsetObjectList() : ITimestampObjectList<OBJ, CONTAINER>()
|
||||
{
|
||||
@@ -297,17 +308,41 @@ namespace BlackMisc
|
||||
{
|
||||
c.truncate(maxElements - 1);
|
||||
}
|
||||
if (!c.isEmpty() && value.isOlderThanAdjusted(c.front()))
|
||||
const bool needSort = !c.isEmpty() && value.isOlderThanAdjusted(c.front());
|
||||
c.push_front(value);
|
||||
if (needSort)
|
||||
{
|
||||
ITimestampWithOffsetObjectList::sortAdjustedLatestFirst();
|
||||
}
|
||||
c.push_front(value);
|
||||
}
|
||||
|
||||
template<class OBJ, class CONTAINER>
|
||||
void ITimestampWithOffsetObjectList<OBJ, CONTAINER>::push_frontKeepLatestFirstAdjustOffset(const OBJ &value, int maxElements)
|
||||
{
|
||||
ITimestampObjectList<OBJ, CONTAINER>::push_frontKeepLatestFirst(value, maxElements);
|
||||
|
||||
// now sorted by timestamp
|
||||
// this reflects normally the incoming order
|
||||
CONTAINER &c = this->container();
|
||||
if (c.size() < 2) { return; }
|
||||
const ITimestampWithOffsetBased &front = c.front();
|
||||
ITimestampWithOffsetBased &second = c[1];
|
||||
if (!front.isOlderThanAdjusted(second)) { return; }
|
||||
const qint64 maxOs = front.getAdjustedMSecsSinceEpoch() - second.getMSecsSinceEpoch();
|
||||
const qint64 avgOs = (maxOs + qMax(front.getTimeOffsetMs(), maxOs)) / 2;
|
||||
second.setTimeOffsetMs(avgOs);
|
||||
|
||||
// ts
|
||||
// 8: os 2 adj 10
|
||||
// 6: os 2 adj 8
|
||||
// 5: os 5 adj 10 => max os 3
|
||||
// 0: os 5 adj 5
|
||||
}
|
||||
|
||||
template<class OBJ, class CONTAINER>
|
||||
bool ITimestampWithOffsetObjectList<OBJ, CONTAINER>::isSortedAdjustedLatestLast() const
|
||||
{
|
||||
if (this->container().isEmpty()) { return true; }
|
||||
if (this->container().size() < 2) { return true; }
|
||||
qint64 max = -1;
|
||||
for (const ITimestampWithOffsetBased &obj : this->container())
|
||||
{
|
||||
@@ -321,14 +356,13 @@ namespace BlackMisc
|
||||
template<class OBJ, class CONTAINER>
|
||||
bool ITimestampWithOffsetObjectList<OBJ, CONTAINER>::isSortedAdjustedLatestFirst() const
|
||||
{
|
||||
if (this->container().isEmpty()) { return true; }
|
||||
if (this->container().size() < 2) { return true; }
|
||||
qint64 min = std::numeric_limits <qint64>::max();
|
||||
for (const ITimestampWithOffsetBased &obj : this->container())
|
||||
{
|
||||
if (!obj.hasValidTimestamp()) { return false; }
|
||||
if (obj.getAdjustedMSecsSinceEpoch() > min) { return false; }
|
||||
min = obj.getAdjustedMSecsSinceEpoch();
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -125,9 +125,16 @@ namespace BlackMisc
|
||||
//! Sort by adjusted timestamp
|
||||
void sortAdjustedOldestFirst();
|
||||
|
||||
//! Any negative or zero offset time?
|
||||
bool containsZeroOrNegativeOffsetTime() const;
|
||||
|
||||
//! Insert as first element by keeping maxElements and the latest first
|
||||
void push_frontKeepLatestAdjustedFirst(const OBJ &value, int maxElements = -1);
|
||||
|
||||
//! Insert as first element by keeping maxElements and the latest first
|
||||
//! \remark adjust offset so adjusted values are sorted
|
||||
void push_frontKeepLatestFirstAdjustOffset(const OBJ &value, int maxElements = -1);
|
||||
|
||||
//! Is completely sorted: latest last
|
||||
//! \remark all object must have a valid timestamp
|
||||
bool isSortedAdjustedLatestLast() const;
|
||||
|
||||
Reference in New Issue
Block a user