147 lines
4.7 KiB
C++
147 lines
4.7 KiB
C++
#include "boolseriesadapter.h"
|
|
|
|
BoolSeriesAdapter::BoolSeriesAdapter(QObject *parent)
|
|
: QObject{parent}
|
|
{
|
|
|
|
}
|
|
|
|
LogsModel *BoolSeriesAdapter::logsModel() const
|
|
{
|
|
return m_model;
|
|
}
|
|
|
|
void BoolSeriesAdapter::setLogsModel(LogsModel *logsModel)
|
|
{
|
|
if (m_model != logsModel) {
|
|
m_model = logsModel;
|
|
emit logsModelChanged();
|
|
// update();
|
|
connect(logsModel, &LogsModel::logEntryAdded, this, &BoolSeriesAdapter::logEntryAdded);
|
|
}
|
|
|
|
}
|
|
|
|
QXYSeries *BoolSeriesAdapter::xySeries() const
|
|
{
|
|
return m_series;
|
|
}
|
|
|
|
void BoolSeriesAdapter::setXySeries(QXYSeries *series)
|
|
{
|
|
if (m_series != series) {
|
|
m_series = series;
|
|
emit xySeriesChanged();
|
|
|
|
m_series->clear();
|
|
m_series->append(QDateTime::currentDateTime().addYears(1).toMSecsSinceEpoch(), 0);
|
|
m_series->append(0, 0);
|
|
qWarning() << "Initialized series" << m_series->count();
|
|
}
|
|
}
|
|
|
|
bool BoolSeriesAdapter::inverted() const
|
|
{
|
|
return m_inverted;
|
|
}
|
|
|
|
void BoolSeriesAdapter::setInverted(bool inverted)
|
|
{
|
|
if (m_inverted != inverted) {
|
|
m_inverted = inverted;
|
|
emit invertedChanged();
|
|
}
|
|
}
|
|
|
|
void BoolSeriesAdapter::logEntryAdded(LogEntry *entry)
|
|
{
|
|
if (!m_series) {
|
|
return;
|
|
}
|
|
|
|
int idx = findIndex(entry->timestamp().toMSecsSinceEpoch());
|
|
qreal value = entry->value().toBool() != m_inverted ? 1 : 0;
|
|
|
|
if (m_series->count() >= 2000) {
|
|
qCWarning(dcLogEngine()) << "Thing logs too excessively. Discarding entry.";
|
|
return;
|
|
}
|
|
|
|
// QDebug dbg = qWarning();
|
|
// dbg << "List before insert:\n";
|
|
// for (int i = 0; i < m_series->count(); i++) {
|
|
// dbg << i << QDateTime::fromMSecsSinceEpoch(m_series->at(i).x()) << m_series->at(i).y() << "\n";
|
|
// }
|
|
|
|
// qWarning() << "Inserting" << entry->timestamp() << entry->value() << "real value:" << value << "at" << idx << "total:" << m_series->count();
|
|
// We're keeping a fake entry at the beginning (timestamp 0) with a static value of 0
|
|
// and on in the beginning (+1 year from now) for which we'll update the value according to
|
|
// the newest real entry to continue painting the last value.
|
|
|
|
// Update the future value if this is the new newest real entry
|
|
if (idx == 1) {
|
|
m_series->replace(0, QDateTime::currentDateTime().addYears(1).toMSecsSinceEpoch(), value);
|
|
}
|
|
// If the next older entry is different than this, first insert the other value right before this one
|
|
if (qFuzzyIsNull(m_series->at(idx).y()) != qFuzzyIsNull(value)) {
|
|
m_series->insert(idx, QPointF(entry->timestamp().toMSecsSinceEpoch() - 1, !value));
|
|
}
|
|
|
|
m_series->insert(idx, QPointF(entry->timestamp().toMSecsSinceEpoch(), value));
|
|
|
|
// If the next newer entry is differnt than this, also insert this value right before the next one
|
|
if (qFuzzyIsNull(m_series->at(idx-1).y()) != qFuzzyIsNull(value)) {
|
|
m_series->insert(idx, QPointF(m_series->at(idx-1).x() - 1, value));
|
|
}
|
|
|
|
// qWarning() << "***** series count" << m_series->count();
|
|
// dbg << "List after insert:\n";
|
|
// for (int i = 0; i < m_series->count(); i++) {
|
|
// dbg << i << QDateTime::fromMSecsSinceEpoch(m_series->at(i).x()) << m_series->at(i).y() << "\n";
|
|
// }
|
|
}
|
|
|
|
quint64 BoolSeriesAdapter::findIndex(qulonglong timestamp)
|
|
{
|
|
if (m_series->count() == 2) {
|
|
return 1;
|
|
}
|
|
|
|
// In 99.9% of the cases we'll be prepending (adding live entries) or appending (fetching history)
|
|
if (timestamp < m_series->at(m_series->count() - 2).x()) {
|
|
return m_series->count() - 1;
|
|
}
|
|
if (timestamp > m_series->at(1).x()) {
|
|
return 1;
|
|
}
|
|
|
|
// If for any reason a entry in the middle is added (can't think of one but hey), a binary search will probably do.
|
|
int idx = m_series->count() / 2;
|
|
int range = idx;
|
|
int i = 0;
|
|
while (true) {
|
|
// qWarning() << "CNT:" << m_series->count()
|
|
// << "first:" << QDateTime::fromMSecsSinceEpoch(m_series->at(1).x())
|
|
// << "last:" << QDateTime::fromMSecsSinceEpoch(m_series->at(m_series->count()- 2).x())
|
|
// << "current:" << idx << QDateTime::fromMSecsSinceEpoch(m_series->at(idx).x())
|
|
// << "search:" << QDateTime::fromMSecsSinceEpoch(timestamp);
|
|
if (timestamp >= m_series->at(idx).x() && timestamp < m_series->at(idx-1).x()) {
|
|
return idx;
|
|
}
|
|
if (timestamp <= m_series->at(idx).x() && timestamp > m_series->at(idx+1).x()) {
|
|
return idx+1;
|
|
}
|
|
range = qMax(1, range / 2);
|
|
if (timestamp > m_series->at(idx).x()) {
|
|
idx = idx - range;
|
|
} else {
|
|
idx = idx + range;
|
|
}
|
|
|
|
if (i++ > 2000) {
|
|
break;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|