243 lines
8.0 KiB
C++
243 lines
8.0 KiB
C++
#pragma once
|
||
#include <nlohmannjson.hpp>
|
||
#include <QVariant>
|
||
#include <QMap>
|
||
#include <QMutex>
|
||
#include <QString>
|
||
#include <QMutexLocker>
|
||
#include <QDebug>
|
||
#include <vector>
|
||
#include <utility>
|
||
|
||
|
||
|
||
class paramSyncManager :public QObject{
|
||
Q_OBJECT
|
||
public:
|
||
std::vector<QString> missionKey;
|
||
// 构造函数:从JSON数据初始化参数
|
||
explicit paramSyncManager(bSignalHub* _signalHub,const nlohmann::ordered_json& json = nlohmann::ordered_json::object()
|
||
):_signalHub(_signalHub){
|
||
loadFromJson(json);
|
||
}
|
||
//获取参数值,如果不存在则返回默认值
|
||
QVariant get(QString group, QString name, QVariant defaultValue) {
|
||
QString fullKey;
|
||
{
|
||
QMutexLocker locker(&globalMutex);
|
||
//构建键名(group.name)
|
||
fullKey = group + "." + name;
|
||
|
||
if (map.contains(fullKey)) {
|
||
return map[fullKey];
|
||
}
|
||
map.insert(fullKey, defaultValue);
|
||
}
|
||
|
||
emit _signalHub->saveMissionJson();
|
||
return defaultValue;
|
||
}
|
||
|
||
//编辑/设置分组参数值
|
||
void edit(const QString& group, const QString& name, const QVariant& target) {
|
||
QString fullKey = group + "." + name;
|
||
{
|
||
QMutexLocker locker(&globalMutex);
|
||
if (map.contains(fullKey)) {
|
||
map[fullKey] = target;
|
||
}
|
||
else {
|
||
map.insert(fullKey, target);
|
||
}
|
||
}
|
||
emit _signalHub->saveMissionJson();
|
||
}
|
||
|
||
//检查参数是否存在
|
||
bool contains(const QString& fullKey) const {
|
||
QMutexLocker locker(&globalMutex);
|
||
return map.contains(fullKey);
|
||
}
|
||
|
||
//移除参数
|
||
bool remove(const QString& fullKey) {
|
||
QMutexLocker locker(&globalMutex);
|
||
return map.remove(fullKey) > 0;
|
||
}
|
||
|
||
// 获取所有参数名
|
||
QStringList getParameterNames() const {
|
||
QMutexLocker locker(&globalMutex);
|
||
return map.keys();
|
||
}
|
||
|
||
//获取所有参数
|
||
std::vector<std::pair<QString, QVariant>> getAllParams() {
|
||
QMutexLocker locker(&globalMutex);
|
||
std::vector<std::pair<QString, QVariant>> result;
|
||
updateJsonFromMap();
|
||
for (auto it = map.begin(); it != map.end(); ++it) {
|
||
result.emplace_back(it.key(), it.value());
|
||
}
|
||
return result;
|
||
}
|
||
|
||
// 获取指定分组的所有参数
|
||
std::vector<std::pair<QString, QVariant>> getGroupParams(const QString& group) {
|
||
QMutexLocker locker(&globalMutex);
|
||
std::vector<std::pair<QString, QVariant>> result;
|
||
QString prefix = group + ".";
|
||
|
||
for (auto it = map.begin(); it != map.end(); ++it) {
|
||
if (it.key().startsWith(prefix)) {
|
||
QString paramName = it.key().mid(prefix.length());
|
||
result.emplace_back(paramName, it.value());
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
// 获取分组列表
|
||
std::vector<QString> getGroups() const {
|
||
QMutexLocker locker(&globalMutex);
|
||
return missionKey;
|
||
}
|
||
|
||
// 获取指定索引的分组名
|
||
QString getGroup(int index) const {
|
||
QMutexLocker locker(&globalMutex);
|
||
if (index >= 0 && index < missionKey.size()) {
|
||
return missionKey[index];
|
||
}
|
||
return QString();
|
||
}
|
||
|
||
// 从JSON加载数据
|
||
void loadFromJson(const nlohmann::ordered_json& jsonInput){
|
||
QMutexLocker locker(&globalMutex);
|
||
json = jsonInput;
|
||
map.clear();
|
||
missionKey.clear();
|
||
|
||
if (!jsonInput.is_object()) {
|
||
qDebug() << "Invalid JSON format for paramSyncManager";
|
||
return;
|
||
}
|
||
|
||
for (auto missionIt = jsonInput.begin(); missionIt != jsonInput.end(); ++missionIt) {
|
||
QString groupName = QString::fromStdString(missionIt.key());
|
||
missionKey.push_back(groupName);
|
||
|
||
const auto& innerObject = *missionIt;
|
||
for (auto innerIt = innerObject.begin(); innerIt != innerObject.end(); ++innerIt) {
|
||
QString key = groupName + "." + QString::fromStdString(innerIt.key());
|
||
QVariant value = jsonToQVariant(innerIt.value());
|
||
map.insert(key, value);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 将当前 map 值合并回初始 json 并导出
|
||
// 规则:map 中的键覆盖 json 中的同名键;json 中原有但未出现在 map 中的键保留
|
||
// 将当前 map 值合并回 json 并导出
|
||
nlohmann::ordered_json toJson() {
|
||
QMutexLocker locker(&globalMutex);
|
||
updateJsonFromMap();
|
||
return json;
|
||
}
|
||
|
||
void updateJsonFromMap() {
|
||
//遍历 map,重新构建嵌套的 JSON 结构
|
||
for (auto it = map.begin(); it != map.end(); ++it) {
|
||
QString key = it.key();
|
||
|
||
//解析键名,判断是否包含分组
|
||
QStringList parts = key.split('.');
|
||
if (parts.size() == 2) {
|
||
QString group = parts[0];
|
||
QString paramName = parts.mid(1).join('.');
|
||
|
||
//确保组存在
|
||
if (json.find(group.toStdString()) == json.end()) {
|
||
json[group.toStdString()] = nlohmann::ordered_json::object();
|
||
}
|
||
//添加参数到组
|
||
json[group.toStdString()][paramName.toStdString()] = qVariantToJson(it.value());
|
||
}
|
||
else {
|
||
json[key.toStdString()] = qVariantToJson(it.value());
|
||
}
|
||
}
|
||
missionKey.clear();
|
||
for (auto it = json.begin(); it != json.end(); ++it) {
|
||
missionKey.push_back(QString::fromStdString(it.key()));
|
||
}
|
||
}
|
||
|
||
// 清空所有参数
|
||
void clear() {
|
||
QMutexLocker locker(&globalMutex);
|
||
map.clear();
|
||
json = nlohmann::ordered_json::object();
|
||
missionKey.clear();
|
||
}
|
||
|
||
private:
|
||
bSignalHub* _signalHub;
|
||
QMap<QString, QVariant> map;//存储当前最新参数值
|
||
nlohmann::ordered_json json;
|
||
mutable QMutex globalMutex; // 保护整个map的全局互斥锁
|
||
|
||
// 辅助方法:将JSON值转换为QVariant
|
||
QVariant jsonToQVariant(const nlohmann::json& json) const {
|
||
if (json.is_null()) {
|
||
return QVariant();
|
||
} else if (json.is_boolean()) {
|
||
return QVariant(json.get<bool>());
|
||
} else if (json.is_number_integer()) {
|
||
return QVariant(json.get<int>());
|
||
} else if (json.is_number_unsigned()) {
|
||
return QVariant(static_cast<qulonglong>(json.get<unsigned long long>()));
|
||
} else if (json.is_number_float()) {
|
||
return QVariant(json.get<double>());
|
||
} else if (json.is_string()) {
|
||
return QVariant(QString::fromStdString(json.get<std::string>()));
|
||
} else if (json.is_array()) {
|
||
// 可以根据需要扩展数组支持
|
||
return QVariant(QString::fromStdString(json.dump()));
|
||
} else if (json.is_object()) {
|
||
// 可以根据需要扩展对象支持
|
||
return QVariant(QString::fromStdString(json.dump()));
|
||
}
|
||
return QVariant();
|
||
}
|
||
|
||
// 辅助方法:将QVariant转换为JSON值
|
||
nlohmann::json qVariantToJson(const QVariant& variant) const {
|
||
switch (variant.type()) {
|
||
case QVariant::Bool:
|
||
return variant.toBool();
|
||
case QVariant::Int:
|
||
return variant.toInt();
|
||
case QVariant::UInt:
|
||
return static_cast<unsigned int>(variant.toUInt());
|
||
case QVariant::LongLong:
|
||
return static_cast<long long>(variant.toLongLong());
|
||
case QVariant::ULongLong:
|
||
return static_cast<unsigned long long>(variant.toULongLong());
|
||
case QVariant::Double:
|
||
return variant.toDouble();
|
||
case QVariant::String:
|
||
return variant.toString().toStdString();
|
||
case QVariant::Invalid:
|
||
return nullptr;
|
||
default:
|
||
// 对于其他类型,转换为字符串
|
||
return variant.toString().toStdString();
|
||
}
|
||
}
|
||
};
|
||
|
||
|