#pragma once #include "XNObject.h" #include template struct is_std_array : std::false_type { }; template struct is_std_array> : std::true_type { }; // 变量模板简化使用 template inline constexpr bool is_std_array_v = is_std_array::value; class XNDDSInterface : public XNObject { Q_OBJECT public: explicit XNDDSInterface(QObject *parent = nullptr) : XNObject(parent) {} virtual ~XNDDSInterface() {} template QByteArray getQByteArray(eprosima::fastcdr::optional data) { QByteArray value; // 如果T是普通类型,将data中的数据转换为QByteArray if constexpr (std::is_arithmetic_v) { QDataStream dataStream(&value, QIODevice::WriteOnly); dataStream.setByteOrder(QDataStream::LittleEndian); if (data) { dataStream << data.value(); } else { dataStream << (T)0; } } // 如果T是std::array,则需要根据T的类型和大小,生成一个std::array的QByteArray else if constexpr (is_std_array_v) { if (data) { value = getQByteArrayFromStdArray(data.value()); } else { T zero = {}; value = getQByteArrayFromStdArray(zero); } } return value; } template QByteArray getQByteArrayFromStdArray(std::array data) { QByteArray value; QDataStream dataStream(&value, QIODevice::WriteOnly); dataStream.setByteOrder(QDataStream::LittleEndian); for (std::size_t i = 0; i < N; ++i) { if constexpr (std::is_arithmetic_v) { dataStream << data[i]; } else { dataStream << getQByteArrayFromStdArray(data[i]); } } return value; } QByteArray getUDPPackage() { QByteArray package; QByteArray header = this->header.mid(0, 5); package.append(header); for (auto func : getByteArrayFunction) { package.append(func()); } package[4] = package.size(); return package; } template QString getQString(eprosima::fastcdr::optional data) { if constexpr (std::is_arithmetic_v) { if (data) { return QString::number(data.value()); } else { return QString::number(0); } } else if constexpr (std::is_same_v) { if (data) { return getQStringFromStdArray(data.value()); } else { T zero = {}; return getQStringFromStdArray(zero); } } return QString(); } template QString getQStringFromStdArray(std::array data) { QStringList list; for (std::size_t i = 0; i < N; ++i) { if constexpr (std::is_arithmetic_v) { list.append(QString::number(data[i])); } else { list.append(getQStringFromStdArray(data[i])); } } return list.join(","); } QString getData(const QString &varName) { int index1 = -1; int index2 = -1; QString trueVarName = varName; // 检查变量名中是否存在数组标记 if (varName.contains('[')) { // 解析数组索引 int startPos = varName.indexOf('['); int midPos = varName.indexOf("]["); int endPos = varName.lastIndexOf(']'); // 如果是二维数组 (格式: name[index1][index2]) if (midPos != -1) { bool ok1 = false, ok2 = false; index1 = varName.mid(startPos + 1, midPos - startPos - 1).toInt(&ok1); index2 = varName.mid(midPos + 2, endPos - midPos - 2).toInt(&ok2); if (!ok1 || !ok2) { qWarning() << "无法解析数组索引:" << varName; index1 = 0; index2 = 0; } } // 如果是一维数组 (格式: name[index1]) else if (startPos != -1 && endPos != -1) { bool ok = false; index1 = varName.mid(startPos + 1, endPos - startPos - 1).toInt(&ok); if (!ok) { qWarning() << "无法解析数组索引:" << varName; index1 = 0; } } trueVarName = varName.left(startPos); } auto it = getDataFunction.find(trueVarName); if (it == getDataFunction.end()) { return QString(); // 返回空字符串表示未找到 } if (index1 < 0) { QMutexLocker locker(&mutex); return it.value()(); } else if (index2 < 0) { QMutexLocker locker(&mutex); QStringList list = it.value()().split(","); if (index1 >= list.size()) { qWarning() << "数组索引超出范围:" << varName; return QString(); } return list[index1]; } else { QMutexLocker locker(&mutex); QStringList list = it.value()().split(","); if (index1 >= list.size()) { qWarning() << "数组索引超出范围:" << varName; return QString(); } QStringList list2 = list[index1].split(" "); if (index2 >= list2.size()) { qWarning() << "数组索引超出范围:" << varName; return QString(); } return list2[index2]; } } protected: QHash> getDataFunction; QVector> getByteArrayFunction; QMutex mutex; QByteArray header; }; #define MAP_GET_DATA_FUNC(NAME) \ getDataFunction[#NAME] = [this]() { return getQString(data.NAME()); }; \ getByteArrayFunction.push_back([this]() { return getQByteArray(data.NAME()); })