#pragma once #pragma execution_character_set("utf-8") #include #include #include #include #include #include struct viewerStruct { std::string name; int xPos, yPos, width, height; std::vectorviewers; }; struct cameraPixelPrecision { double x_precision_mm_Pix; ///< 水平像素精度,单位:毫米/像素 double y_precision_mm_Pix; ///< 垂直像素精度,单位:毫米/像素 double z_precision_mm_Pix; ///< Z方向像素精度,单位:毫米/像素 }; struct SubUiWidgetConfig { SubUiWidgetConfig() = default; SubUiWidgetConfig(const SubUiWidgetConfig&) = default; SubUiWidgetConfig& operator=(const SubUiWidgetConfig&) = default; SubUiWidgetConfig(SubUiWidgetConfig&&) = default; SubUiWidgetConfig& operator=(SubUiWidgetConfig&&) = default; int height = 0; std::string key; double limitHigh = 0.0; double limitLow = 0.0; int maxPoints = 100; std::string widgetType; int width = 0; int x = 0; int y = 0; nlohmann::ordered_json extra = nlohmann::ordered_json::object(); }; using SubUiPageConfig = std::map>; class MissionConfig { public: MissionConfig() = default; explicit MissionConfig(const std::string& jsonPath) { loadFromFile(jsonPath); } MissionConfig(const MissionConfig&) = delete; MissionConfig& operator=(const MissionConfig&) = delete; MissionConfig(MissionConfig&&) = default; MissionConfig& operator=(MissionConfig&&) = default; void loadFromFile(const std::string& jsonPath) { _jsonPath = jsonPath; parseFromJson(readOrderedJsonFromPath(jsonPath)); } void parseFromJson(const nlohmann::ordered_json& json) { _lastSavedJson = nlohmann::ordered_json::object(); _lastSavedJsonPath.clear(); _hasLastSavedJson = false; _rawJson = json.is_object() ? json : nlohmann::ordered_json::object(); if (!json.is_object()) { softwareTile.clear(); backend = nlohmann::ordered_json::object(); imageViews.clear(); sublUiSetting.clear(); return; } softwareTile = json.value("softwareTile", ""); if (softwareTile.empty()) { std::cout << "[Warning] softwareTile is empty" << std::endl; } backend = json.value("backend", nlohmann::ordered_json::object()); if (!json.contains("backend")) { std::cout << "[Warning] 'backend' node missing from mission config" << std::endl; } imageViews.clear(); if (!json.contains("ImageView")) { std::cout << "[Warning] 'ImageView' node missing" << std::endl; } else if (json["ImageView"].empty()) { std::cout << "[Warning] 'ImageView' node is empty" << std::endl; } else { for (auto it = json["ImageView"].begin(); it != json["ImageView"].end(); ++it) { viewerStruct v{}; v.name = it.key(); auto& val = it.value(); if (!val.contains("xPos")) { std::cout << "[Warning] ImageView[" << v.name << "] missing 'xPos'" << std::endl; } if (!val.contains("yPos")) { std::cout << "[Warning] ImageView[" << v.name << "] missing 'yPos'" << std::endl; } if (!val.contains("viewer")) { std::cout << "[Warning] ImageView[" << v.name << "] missing 'viewer' array" << std::endl; } v.xPos = val.value("xPos", 0); v.yPos = val.value("yPos", 0); v.width = val.value("width", 0); v.height = val.value("height", 0); if (val.contains("viewer")) { v.viewers.assign(val["viewer"].begin(), val["viewer"].end()); } imageViews.push_back(std::move(v)); } } sublUiSetting.clear(); if (!json.contains("sublUiSetting")) { std::cout << "[Warning] 'sublUiSetting' node missing" << std::endl; } else { for (auto it = json["sublUiSetting"].begin(); it != json["sublUiSetting"].end(); ++it) { std::string pageName = it.key(); std::vector widgets; for (auto& w : it.value()) { SubUiWidgetConfig cfg; if (w.is_object()) { cfg.extra = w; } cfg.height = w.value("height", 0); cfg.key = w.value("key", ""); cfg.limitHigh = w.value("limitHigh", 0.0); cfg.limitLow = w.value("limitLow", 0.0); cfg.maxPoints = w.value("maxPoints", 100); cfg.widgetType = w.value("widgetType", ""); cfg.width = w.value("width", 0); cfg.x = w.value("x", 0); cfg.y = w.value("y", 0); if (cfg.key.empty()) { std::cout << "[Warning] sublUiSetting[" << pageName << "] entry missing 'key'" << std::endl; } if (cfg.widgetType.empty()) { std::cout << "[Warning] sublUiSetting[" << pageName << "][" << cfg.key << "] missing 'widgetType'" << std::endl; } widgets.push_back(std::move(cfg)); } sublUiSetting.emplace(pageName, std::move(widgets)); } } } nlohmann::ordered_json toJson() const { nlohmann::ordered_json json = _rawJson.is_object() ? _rawJson : nlohmann::ordered_json::object(); json["softwareTile"] = softwareTile; json["backend"] = backend; auto rawImageView = json.value("ImageView", nlohmann::ordered_json::object()); auto& iv = json["ImageView"] = nlohmann::ordered_json::object(); for (const auto& v : imageViews) { nlohmann::ordered_json item = rawImageView.contains(v.name) && rawImageView[v.name].is_object() ? rawImageView[v.name] : nlohmann::ordered_json::object(); item["xPos"] = v.xPos; item["yPos"] = v.yPos; item["width"] = v.width; item["height"] = v.height; item["viewer"] = nlohmann::ordered_json::array(); for (const auto& viewer : v.viewers) { item["viewer"].push_back(viewer); } iv[v.name] = std::move(item); } auto rawSublUiSetting = json.value("sublUiSetting", nlohmann::ordered_json::object()); auto& subl = json["sublUiSetting"] = nlohmann::ordered_json::object(); for (const auto& page : sublUiSetting) { auto rawPage = rawSublUiSetting.contains(page.first) && rawSublUiSetting[page.first].is_array() ? rawSublUiSetting[page.first] : nlohmann::ordered_json::array(); auto& pageArr = subl[page.first] = nlohmann::ordered_json::array(); for (size_t idx = 0; idx < page.second.size(); ++idx) { const auto& w = page.second[idx]; nlohmann::ordered_json item = idx < rawPage.size() && rawPage[idx].is_object() ? rawPage[idx] : (w.extra.is_object() ? w.extra : nlohmann::ordered_json::object()); item["height"] = w.height; item["key"] = w.key; item["limitHigh"] = w.limitHigh; item["limitLow"] = w.limitLow; item["maxPoints"] = w.maxPoints; item["widgetType"] = w.widgetType; item["width"] = w.width; item["x"] = w.x; item["y"] = w.y; pageArr.push_back(std::move(item)); } } return json; } void saveAsJson(const std::string& jsonPath = "", bool forceSave = true) const { auto path = jsonPath.empty() ? _jsonPath : jsonPath; if (path.empty()) { return; } const auto currentJson = toJson(); if (!forceSave && _hasLastSavedJson && path == _lastSavedJsonPath && currentJson == _lastSavedJson) { return; } if (!saveOrderedJsonFromPath(path, currentJson)) { return; } _lastSavedJson = currentJson; _lastSavedJsonPath = path; _hasLastSavedJson = true; } std::vector imageViews; std::string softwareTile; nlohmann::ordered_json backend = nlohmann::ordered_json::object(); SubUiPageConfig sublUiSetting; private: std::string _jsonPath; nlohmann::ordered_json _rawJson = nlohmann::ordered_json::object(); mutable nlohmann::ordered_json _lastSavedJson = nlohmann::ordered_json::object(); mutable std::string _lastSavedJsonPath; mutable bool _hasLastSavedJson = false; };