fix: multiplexed value display to not jump all around
- feat: now have a array to cache values and always display them in the order in the DBC, also keep track of which values are not stale to not display 0 on init
This commit is contained in:
+21
-11
@@ -573,26 +573,34 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
|
|||||||
{
|
{
|
||||||
tempString.append(" <" + msg->name + ">\n");
|
tempString.append(" <" + msg->name + ">\n");
|
||||||
if (msg->comment.length() > 1) tempString.append(msg->comment + "\n");
|
if (msg->comment.length() > 1) tempString.append(msg->comment + "\n");
|
||||||
|
//Iterate signals in their fixed DBC index order so the displayed lines keep
|
||||||
|
//the same position from frame to frame and don't jump around when a new
|
||||||
|
//multiplex value arrives, which makes the output much easier to read.
|
||||||
for (int j = 0; j < msg->sigHandler->getCount(); j++)
|
for (int j = 0; j < msg->sigHandler->getCount(); j++)
|
||||||
{
|
{
|
||||||
QString sigString;
|
QString sigString;
|
||||||
DBC_SIGNAL* sig = msg->sigHandler->findSignalByIdx(j);
|
DBC_SIGNAL* sig = msg->sigHandler->findSignalByIdx(j);
|
||||||
|
|
||||||
if ( (sig->multiplexParent == nullptr) && sig->processAsText(thisFrame, sigString))
|
if (sig->isSignalInMessage(thisFrame))
|
||||||
{
|
{
|
||||||
tempString.append(sigString);
|
//Signal really is part of this exact frame: a plain signal, the
|
||||||
tempString.append("\n");
|
//multiplexor itself, or a multiplexed child whose multiplex value
|
||||||
if (sig->isMultiplexor)
|
//matches this frame. Show the freshly decoded value and remember it
|
||||||
|
//(per this model) so other multiplex branches can keep showing it.
|
||||||
|
if (sig->processAsText(thisFrame, sigString))
|
||||||
{
|
{
|
||||||
qDebug() << "Multiplexor. Diving into the tree";
|
sigDisplayCache[sig] = sigString;
|
||||||
tempString.append(sig->processSignalTree(thisFrame));
|
tempString.append(sigString);
|
||||||
|
tempString.append("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sig->isMultiplexed && overwriteDups) //wasn't in this exact frame but is in the message. Use cached value
|
else if (sig->isMultiplexed && overwriteDups && sigDisplayCache.contains(sig))
|
||||||
{
|
{
|
||||||
bool isInteger = false;
|
//Multiplexed child from a different branch, so it isn't in this exact
|
||||||
if (sig->valType == UNSIGNED_INT || sig->valType == SIGNED_INT) isInteger = true;
|
//frame. Show the last value this view actually decoded for it. Using our
|
||||||
tempString.append(sig->makePrettyOutput(sig->cachedValue.toDouble(), sig->cachedValue.toLongLong(), true, isInteger));
|
//own cache (not DBC_SIGNAL::cachedValue) means values another window
|
||||||
|
//decodes for the same signal can't bleed in here.
|
||||||
|
tempString.append(sigDisplayCache.value(sig));
|
||||||
tempString.append("\n");
|
tempString.append("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -882,6 +890,8 @@ void CANFrameModel::clearFrames(bool forceClearFilters)
|
|||||||
filters.clear();
|
filters.clear();
|
||||||
busFilters.clear();
|
busFilters.clear();
|
||||||
}
|
}
|
||||||
|
//forget any cached multiplex signal values so a fresh capture doesn't display stale data
|
||||||
|
sigDisplayCache.clear();
|
||||||
frames.reserve(preallocSize);
|
frames.reserve(preallocSize);
|
||||||
filteredFrames.reserve(preallocSize);
|
filteredFrames.reserve(preallocSize);
|
||||||
this->endResetModel();
|
this->endResetModel();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
#include <QHash>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include "can_structs.h"
|
#include "can_structs.h"
|
||||||
@@ -89,6 +90,10 @@ private:
|
|||||||
QMap<int, bool> filters;
|
QMap<int, bool> filters;
|
||||||
QMap<int, bool> busFilters;
|
QMap<int, bool> busFilters;
|
||||||
DBCHandler *dbcHandler;
|
DBCHandler *dbcHandler;
|
||||||
|
//model-owned cache of the last rendered text for each signal, used to keep multiplexed
|
||||||
|
//signals from other branches visible. Kept separate from DBC_SIGNAL::cachedValue so that
|
||||||
|
//other windows decoding the same signal can't clobber what this view shows.
|
||||||
|
mutable QHash<DBC_SIGNAL *, QString> sigDisplayCache; //mutable: updated from const data()
|
||||||
QMutex mutex;
|
QMutex mutex;
|
||||||
bool interpretFrames; //should we use the dbcHandler?
|
bool interpretFrames; //should we use the dbcHandler?
|
||||||
bool overwriteDups; //should we display all frames or only the newest for each ID?
|
bool overwriteDups; //should we display all frames or only the newest for each ID?
|
||||||
|
|||||||
Reference in New Issue
Block a user