1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
#ifndef DBC_CLASSES_H
#define DBC_CLASSES_H
#include <QColor>
#include <QString>
#include <QStringList>
#include <QVariant>
#include "can_structs.h"
/*classes to encapsulate data from a DBC file. Really, the stuff of interest
are the nodes, messages, signals, attributes, and comments.
These things sort of form a hierarchy. Nodes send and receive messages.
Messages are comprised of signals. Nodes, signals, and messages potentially have attribute values.
All of them can have comments.
*/
enum DBC_SIG_VAL_TYPE
{
UNSIGNED_INT,
SIGNED_INT,
SP_FLOAT,
DP_FLOAT,
STRING
};
enum DBC_ATTRIBUTE_VAL_TYPE
{
ATTR_INT,
ATTR_FLOAT,
ATTR_STRING,
ATTR_ENUM,
};
enum DBC_ATTRIBUTE_TYPE
{
ATTR_TYPE_GENERAL,
ATTR_TYPE_NODE,
ATTR_TYPE_MESSAGE,
ATTR_TYPE_SIG,
ATTR_TYPE_ANY
};
class DBC_ATTRIBUTE
{
public:
QString name;
DBC_ATTRIBUTE_VAL_TYPE valType;
DBC_ATTRIBUTE_TYPE attrType;
double upper, lower;
QStringList enumVals;
QVariant defaultValue;
};
class DBC_ATTRIBUTE_VALUE
{
public:
QString attrName;
QVariant value;
};
class DBC_VAL_ENUM_ENTRY
{
public:
int value;
QString descript;
};
class DBC_NODE
{
public:
QString name;
QString comment;
QString sourceFileName;
QList<DBC_ATTRIBUTE_VALUE> attributes;
DBC_ATTRIBUTE_VALUE *findAttrValByName(QString name);
DBC_ATTRIBUTE_VALUE *findAttrValByIdx(int idx);
friend bool operator<(const DBC_NODE& l, const DBC_NODE& r)
{
return (l.name.toLower() < r.name.toLower());
}
};
class DBC_MESSAGE; //forward reference so that DBC_SIGNAL can compile before we get to real definition of DBC_MESSAGE
class DBC_SIGNAL;
/*
* Both DBC_SIGNAL and DBC_MESSAGE used to use a lot of pointers. This worked in QT5 because QList was
* sort of a linked list. It was a QVector that stores pointers to objects on the heap. Since those
* objects would not move this allowed for taking pointers to them. However, QT6 causes a problem here
* as now QVector and QList are the exact same and both store items actually in the list, not as pointers.
* This causes invalidation any time a size modifying call is done on the QVector/QList.
* So, the easiest solution to keep the code mostly the same and things working like they did
* is to re-introduce pointers with smart pointers.
*
*/
class DBC_SIGNAL
{
public: //TODO: Clean up this class so that not everything is public. There is one private member which is a start...
DBC_SIGNAL() = default;
enum DbcMuxStringFormat {
MuxStringFormat_DbcFile,
MuxStringFormat_UI
};
QString name;
int startBit = 1;
int signalSize = 1;
bool intelByteOrder = false; //true is obviously little endian. False is big endian
bool isMultiplexor = false;
bool isMultiplexed = false;
void addMultiplexRange(int min, int max);
bool hasExtendedMultiplexing = false;
QList<DBC_SIGNAL *> multiplexedChildren;
DBC_SIGNAL *multiplexParent = nullptr;
QString multiplexDbcString(DbcMuxStringFormat fmt = MuxStringFormat_DbcFile) const;
void copyMultiplexValuesFromSignal(const DBC_SIGNAL &signal);
bool parseDbcMultiplexUiString(const QString &multiplexes, QString &errorString);
bool multiplexesIdenticalToSignal(DBC_SIGNAL *other) const;
DBC_SIG_VAL_TYPE valType = DBC_SIG_VAL_TYPE::UNSIGNED_INT;
double factor = 1.0;
double bias = 0;
double min = 0;
double max = 1;
DBC_NODE *receiver = nullptr; //it is fast to have a pointer but dangerous... Make sure to walk the whole tree and delete everything so nobody has stale references.
DBC_MESSAGE *parentMessage = nullptr;
QString unitName;
QString comment;
QVariant cachedValue;
QList<DBC_ATTRIBUTE_VALUE> attributes;
QList<DBC_VAL_ENUM_ENTRY> valList;
DBC_SIGNAL *self;
bool processAsText(const CANFrame &frame, QString &outString, bool outputName = true, bool outputUnit = true);
bool processAsInt(const CANFrame &frame, int32_t &outValue);
bool processAsDouble(const CANFrame &frame, double &outValue);
bool getValueString(int64_t intVal, QString &outString);
QString makePrettyOutput(double floatVal, int64_t intVal, bool outputName = true, bool isInteger = false, bool outputUnit = true);
QString processSignalTree(const CANFrame &frame);
DBC_ATTRIBUTE_VALUE *findAttrValByName(QString name);
DBC_ATTRIBUTE_VALUE *findAttrValByIdx(int idx);
bool isSignalInMessage(const CANFrame &frame);
bool isValueMatchingMultiplex(int val) const;
int getSimpleMultiplexValue();
friend bool operator<(const DBC_SIGNAL& l, const DBC_SIGNAL& r)
{
return (l.name.toLower() < r.name.toLower());
}
private:
QList<QPair<int, int>> multiplexLowAndHighValues;
};
class DBCSignalHandler; //forward declaration to keep from having to include dbchandler.h in this file and thus create a loop
class DBC_MESSAGE
{
public:
DBC_MESSAGE();
uint32_t ID;
bool extendedID;
QString name;
QString comment;
unsigned int len;
DBC_NODE *sender;
QColor bgColor;
QColor fgColor;
QList<DBC_ATTRIBUTE_VALUE> attributes;
DBCSignalHandler *sigHandler;
DBC_SIGNAL* multiplexorSignal;
DBC_ATTRIBUTE_VALUE *findAttrValByName(QString name);
DBC_ATTRIBUTE_VALUE *findAttrValByIdx(int idx);
friend bool operator<(const DBC_MESSAGE& l, const DBC_MESSAGE& r)
{
return (l.name.toLower() < r.name.toLower());
}
};
#endif // DBC_CLASSES_H
|