XNSim/XNCore/XNDDSInterface.h
2025-04-28 12:25:20 +08:00

189 lines
5.0 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "XNObject.h"
#include <fastcdr/xcdr/optional.hpp>
template <typename T>
struct is_std_array : std::false_type {
};
template <typename T, std::size_t N>
struct is_std_array<std::array<T, N>> : std::true_type {
};
// 变量模板简化使用
template <typename T>
inline constexpr bool is_std_array_v = is_std_array<T>::value;
class XNDDSInterface : public XNObject
{
Q_OBJECT
public:
explicit XNDDSInterface(QObject *parent = nullptr) : XNObject(parent) {}
virtual ~XNDDSInterface() {}
template <typename T>
QByteArray getQByteArray(eprosima::fastcdr::optional<T> data)
{
QByteArray value;
// 如果T是普通类型将data中的数据转换为QByteArray
if constexpr (std::is_arithmetic_v<T>) {
QDataStream dataStream(&value, QIODevice::WriteOnly);
dataStream.setByteOrder(QDataStream::LittleEndian);
if (data) {
dataStream << data.value();
} else {
dataStream << (T)0;
}
}
// 如果T是std::array则需要根据T的类型和大小生成一个std::array<T, N>的QByteArray
else if constexpr (is_std_array_v<T>) {
if (data) {
value = getQByteArrayFromStdArray(data.value());
} else {
T zero = {};
value = getQByteArrayFromStdArray(zero);
}
}
return value;
}
template <typename T, std::size_t N>
QByteArray getQByteArrayFromStdArray(std::array<T, N> 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<T>) {
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 <typename T>
QString getQString(eprosima::fastcdr::optional<T> data)
{
if constexpr (std::is_arithmetic_v<T>) {
if (data) {
return QString::number(data.value());
} else {
return QString::number(0);
}
} else if constexpr (std::is_same_v<T, std::string>) {
if (data) {
return getQStringFromStdArray(data.value());
} else {
T zero = {};
return getQStringFromStdArray(zero);
}
}
return QString();
}
template <typename T, std::size_t N>
QString getQStringFromStdArray(std::array<T, N> data)
{
QStringList list;
for (std::size_t i = 0; i < N; ++i) {
if constexpr (std::is_arithmetic_v<T>) {
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<QString, std::function<QString()>> getDataFunction;
QVector<std::function<QByteArray()>> 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()); })