Files
ECAP_Server/module/Local_Server/server/Config.h
T
2026-08-24 09:20:04 +08:00

536 lines
26 KiB
C++
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.
#ifndef CONFIG_H_H
#define CONFIG_H_H
#include <array>
#include <fstream>
#include <map>
#include <optional>
#include <vector>
#include "../Build_Version_Api.h"
#include "../DSP/export.h"
#include "../Data_Feed/export.h"
#include "../Data_Source/export.h"
#include "MLAT.h"
#include "Psc_Cpp_Core/spdlog/export.h"
#include "adminive/json.hpp"
#include "adminive/managed.hpp"
inline bool delete_log = false;
extern std::string default_config_directory;
#define ECAP_CONFIG_SECTION_LIST(X) \
X(dsp) \
X(drogon) \
X(http_monitor) \
X(mlat) \
X(web_server) \
X(map_resources) \
X(map_view) \
X(map_models) \
X(mode_acs) \
X(log) \
X(console) \
X(external_database) \
X(cesium_graphics)
enum class Config_Section {
#define ECAP_CONFIG_SECTION_ENUM(name) name,
ECAP_CONFIG_SECTION_LIST(ECAP_CONFIG_SECTION_ENUM)
#undef ECAP_CONFIG_SECTION_ENUM
count
};
inline constexpr std::array config_section_names = {
#define ECAP_CONFIG_SECTION_NAME(name) std::string_view{#name},
ECAP_CONFIG_SECTION_LIST(ECAP_CONFIG_SECTION_NAME)
#undef ECAP_CONFIG_SECTION_NAME
};
#undef ECAP_CONFIG_SECTION_LIST
static_assert(config_section_names.size() == static_cast<std::size_t>(Config_Section::count));
inline constexpr std::string_view config_section_name(Config_Section section) {
return config_section_names[static_cast<std::size_t>(section)];
}
struct Log_Config {
~Log_Config() {
if (delete_log)
std::cout << "~Log_Config()" << std::endl;
}
enum class Open_Mode { Append, Delete, Rename };
Open_Mode open_mode = Open_Mode::Rename;
std::uint16_t piece_num{};
std::uint16_t size_MB{};
PSC_USE_JSON
};
struct Console_Config {
~Console_Config() {
if (delete_log)
std::cout << "~Console_Config()" << std::endl;
}
bool record_playback;
bool mode_s_console;
PSC_USE_JSON
};
struct Http_Monitor_Config {
bool access_log = true;
std::size_t slow_request_threshold_ms = 1000;
std::size_t slow_scope_threshold_ms = 100;
PSC_USE_JSON
};
struct Mode_ACS_Config_Data {
std::size_t timeout_seconds{};
SSR::CPR::D max_speed_m_s{};
SSR::CPR::D air_pos_timeout = 8;
SSR::CPR::D surface_pos_timeout = 32;
bool wait_process_msg{};
bool time_space_filter{};
bool speed_filter{};
std::size_t max_track_point_size{};
std::size_t mode_s_max_num{};
std::size_t mode_other_max_num{};
std::size_t report_data_feed_msg_mum{};
std::size_t default_min_aircraft_list_num{};
std::size_t aircraft_change_list_min_position_points = 2;
bool aircraft_change_list_adsb_range_filter = true;
double aircraft_change_list_adsb_range_factor = 1.2;
double adsb_theoretical_target_altitude_meters = 10000.0;
bool monitor_msg_live{};
PSC_USE_JSON
};
struct Data_Topology_Node_Position {
double x{};
double y{};
};
struct Data_Topology_View_Config {
bool initialized{};
std::uint32_t layout_revision{};
double zoom = 1.0;
double pan_x{};
double pan_y{};
std::map<std::string, Data_Topology_Node_Position> node_positions;
void from_json(const Psc::JSON* that_json);
[[nodiscard]] Psc::JSON to_json() const;
};
namespace adminive {
template <>
struct Type_Descriptor<Data_Topology_Node_Position> {
static auto get() {
using T = Data_Topology_Node_Position;
return object<T>("data_topology_node_position", "拓扑节点位置",
ADMINIVE_FIELD_LABEL(T, x, "X"),
ADMINIVE_FIELD_LABEL(T, y, "Y"));
}
};
template <>
struct Type_Descriptor<Data_Topology_View_Config> {
static auto get() {
using T = Data_Topology_View_Config;
return object<T>("data_topology_view", "数据拓扑视图",
ADMINIVE_FIELD_LABEL(T, initialized, "已初始化"),
ADMINIVE_FIELD_LABEL(T, layout_revision, "布局版本"),
ADMINIVE_FIELD_LABEL(T, zoom, "缩放"),
ADMINIVE_FIELD_LABEL(T, pan_x, "平移 X"),
ADMINIVE_FIELD_LABEL(T, pan_y, "平移 Y"),
ADMINIVE_FIELD_LABEL(T, node_positions, "节点位置"));
}
};
template <>
struct Type_Descriptor<Mode_ACS_Config_Data> {
static auto get() {
using T = Mode_ACS_Config_Data;
return object<T>("mode_acs_config", "Mode ACS 基础配置",
ADMINIVE_FIELD_LABEL(T, timeout_seconds, "目标超时时间(秒)").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, max_speed_m_s, "飞机最大速度(m/s").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, air_pos_timeout, "空中 CPR 超时(秒)").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, surface_pos_timeout, "地面 CPR 超时(秒)").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, wait_process_msg, "等待处理消息").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, time_space_filter, "时空过滤").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, speed_filter, "速度过滤").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, max_track_point_size, "最大航迹点数量").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, mode_s_max_num, "Mode S 最大数量").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, mode_other_max_num, "其他 Mode 最大数量").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, report_data_feed_msg_mum, "数据馈送消息上报数量").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, default_min_aircraft_list_num, "默认最小飞机列表数量").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, aircraft_change_list_min_position_points, "飞机变化列表最少位置点").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, aircraft_change_list_adsb_range_filter, "基站理论范围过滤").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, aircraft_change_list_adsb_range_factor, "范围过滤系数").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, adsb_theoretical_target_altitude_meters, "理论目标高度(米)").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, monitor_msg_live, "监控 Mode ACS 消息").editable().boolean_input());
}
};
}
struct Mode_ACS_Config {
adminive::Managed_Value<Mode_ACS_Config_Data> settings;
Data_feed_Config data_feed_config;
Data_Source_Config data_source_config;
adminive::Managed_Value<Data_Topology_View_Config> data_topology_view;
std::size_t Report_Data_Feed_Message_Num{};
Mode_ACS_Config() = default;
~Mode_ACS_Config() {
if (delete_log)
std::cout << " ~Mode_S_Config()" << std::endl;
}
[[nodiscard]] Psc::JSON to_base_json() const;
void from_json(const Psc::JSON* that_json);
void server(Global* g);
};
struct Web_Server_Config {
[[nodiscard]] std::string get_true_webapp() const {
return Psc::get_abs_path(webapp);
}
std::string webapp;
std::uint16_t listen_port = 9081;
[[nodiscard]] Psc::JSON to_base_json() const;
void from_base_json(const Psc::JSON* that_json);
};
enum class Map_Tile_File_Format { directory, mbtiles, online };
enum class Map_Tile_Path_Layout { z_x_y, z_y_x };
enum class Map_Tile_Y_Axis { xyz, tms };
enum class Map_Tile_Projection { web_mercator };
enum class Map_Tile_Type { imagery, terrain };
enum class Map_Tile_Request_Method { GET };
enum class Map_Tile_Zoom_Mode { native, upscale, both };
enum class Map_Tile_Encoding { terrarium };
enum class Map_Scene_Mode { map_2d, map_2_5d, map_3d };
namespace magic_enum::customize {
template <>
constexpr customize_t enum_name<Map_Tile_Path_Layout>(Map_Tile_Path_Layout value) noexcept {
switch (value) {
case Map_Tile_Path_Layout::z_x_y: return "z/x/y";
case Map_Tile_Path_Layout::z_y_x: return "z/y/x";
}
return invalid_tag;
}
template <>
constexpr customize_t enum_name<Map_Scene_Mode>(Map_Scene_Mode value) noexcept {
switch (value) {
case Map_Scene_Mode::map_2d: return "2d";
case Map_Scene_Mode::map_2_5d: return "2.5d";
case Map_Scene_Mode::map_3d: return "3d";
}
return invalid_tag;
}
}
struct Map_Tile_Config_Data {
Map_Tile_File_Format file_format = Map_Tile_File_Format::directory;
Map_Tile_Path_Layout path_layout = Map_Tile_Path_Layout::z_x_y;
Map_Tile_Y_Axis y_axis = Map_Tile_Y_Axis::xyz;
Map_Tile_Projection projection = Map_Tile_Projection::web_mercator;
std::string extension;
std::uint32_t tile_size{};
std::uint32_t minimum_level{};
std::uint32_t maximum_level{};
PSC_USE_JSON
};
struct Map_Tile_Config : Map_Tile_Config_Data {
std::vector<std::string> directories;
std::vector<std::string> files;
std::optional<Map_Tile_Encoding> encoding;
[[nodiscard]] std::vector<std::string> get_true_directories() const {
std::vector<std::string> ret;
ret.reserve(directories.size());
for (const auto& path : directories) {
ret.emplace_back(Psc::get_abs_path(path));
}
return ret;
}
[[nodiscard]] std::vector<std::string> get_true_files() const {
std::vector<std::string> ret;
ret.reserve(files.size());
for (const auto& path : files) {
ret.emplace_back(Psc::get_abs_path(path));
}
return ret;
}
void from_base_json(const Psc::JSON* that_json);
[[nodiscard]] Psc::JSON to_base_json() const;
[[nodiscard]] Psc::JSON to_public_json(std::string_view url) const;
};
struct Map_Tile_Source_Config_Data {
std::string key;
std::string name;
Map_Tile_Type tile_type = Map_Tile_Type::imagery;
Map_Tile_Request_Method request_method = Map_Tile_Request_Method::GET;
PSC_USE_JSON
};
struct Map_Tile_Source_Config : Map_Tile_Source_Config_Data {
std::string url;
Map_Tile_Config resource;
[[nodiscard]] bool local() const {
return resource.file_format != Map_Tile_File_Format::online;
}
void from_base_json(const Psc::JSON* that_json);
[[nodiscard]] Psc::JSON to_base_json() const;
[[nodiscard]] Psc::JSON to_public_json(std::string_view local_url) const;
};
struct Map_Resources_Config {
std::string current_imagery_key = "imagery";
std::vector<Map_Tile_Source_Config> tile_sources;
void from_base_json(const Psc::JSON* that_json);
[[nodiscard]] Psc::JSON to_base_json() const;
[[nodiscard]] Psc::JSON to_public_json() const;
[[nodiscard]] bool is_imagery_key(std::string_view key) const;
[[nodiscard]] bool is_terrain_key(std::string_view key) const;
};
namespace adminive {
template <>
struct Type_Descriptor<Map_Resources_Config> {
static auto get() {
using T = Map_Resources_Config;
return object<T>("map_resources_config", "地图资源配置",
ADMINIVE_FIELD_LABEL(T, current_imagery_key, "当前影像源").read_write(),
ADMINIVE_FIELD_LABEL(T, tile_sources, "地图瓦片源").read_write());
}
};
}
struct Map_Camera_Config {
double longitude = 121.27;
double latitude = 37.41;
double height = 300000.0;
double heading = 0.0;
double pitch = -90.0;
double roll = 0.0;
PSC_USE_JSON
};
namespace adminive {
template <>
struct Type_Descriptor<Map_Camera_Config> {
static auto get() {
using T = Map_Camera_Config;
return object<T>("map_camera_config", "地图相机",
ADMINIVE_FIELD_LABEL(T, longitude, "经度").editable().number_input(),
ADMINIVE_FIELD_LABEL(T, latitude, "纬度").editable().number_input(),
ADMINIVE_FIELD_LABEL(T, height, "高度").editable().number_input(),
ADMINIVE_FIELD_LABEL(T, heading, "航向角").editable().number_input(),
ADMINIVE_FIELD_LABEL(T, pitch, "俯仰角").editable().number_input(),
ADMINIVE_FIELD_LABEL(T, roll, "横滚角").editable().number_input());
}
};
}
struct Map_Tile_View_Config {
std::string current_imagery_key = "imagery";
std::string current_terrain_key = "terrain";
Map_Tile_Zoom_Mode tile_zoom_mode = Map_Tile_Zoom_Mode::native;
std::uint32_t tile_display_maximum_level = 19;
void from_base_json(const Psc::JSON* that_json);
[[nodiscard]] Psc::JSON to_base_json() const;
};
namespace adminive {
template <>
struct Type_Descriptor<Map_Tile_View_Config> {
static auto get() {
using T = Map_Tile_View_Config;
return object<T>("map_tile_view_config", "地图瓦片视图",
ADMINIVE_FIELD_LABEL(T, current_imagery_key, "影像源").editable().text_input(),
ADMINIVE_FIELD_LABEL(T, current_terrain_key, "地形源").editable().text_input(),
ADMINIVE_FIELD_LABEL(T, tile_zoom_mode, "缩放模式").editable().select_input(),
ADMINIVE_FIELD_LABEL(T, tile_display_maximum_level, "显示最大层级").editable().number_input());
}
};
}
struct Map_View_Config {
Map_Scene_Mode scene_mode = Map_Scene_Mode::map_3d;
Map_Tile_View_Config map2d;
Map_Tile_View_Config map3d;
Map_Camera_Config camera;
double base_station_fly_to_height_offset_meters = 8000.0;
void from_base_json(const Psc::JSON* that_json);
[[nodiscard]] Psc::JSON to_base_json() const;
};
namespace adminive {
template <>
struct Type_Descriptor<Map_View_Config> {
static auto get() {
using T = Map_View_Config;
return object<T>("map_view_config", "地图视图配置",
ADMINIVE_FIELD_LABEL(T, scene_mode, "场景模式").editable().required().select_input(),
ADMINIVE_FIELD_LABEL(T, map2d, "2D 地图").editable(),
ADMINIVE_FIELD_LABEL(T, map3d, "3D 地图").editable(),
ADMINIVE_FIELD_LABEL(T, camera, "相机").editable(),
ADMINIVE_FIELD_LABEL(T, base_station_fly_to_height_offset_meters, "基站飞行高度偏移(米)").editable().number_input());
}
};
}
struct Cesium_Graphics_Config_Data {
bool debug_show_frames_per_second = true;
std::uint32_t target_frame_rate = 30;
bool use_browser_recommended_resolution = true;
double resolution_scale = 0.7;
std::uint32_t msaa_samples = 1;
bool fxaa = false;
bool shadows = false;
bool enable_lighting = false;
bool solar_lighting = false;
double solar_light_intensity = 1.5;
std::uint32_t maximum_screen_space_error = 4;
bool terrain_enabled_in_3d = false;
double terrain_exaggeration = 1.0;
bool terrain_limit_maximum_level = true;
std::uint32_t terrain_maximum_level = 15;
std::uint32_t terrain_cache_tiles = 128;
bool terrain_occlusion_enabled = false;
bool surface_navigation_reference_visible = false;
bool view_axes_visible = false;
double performance_panel_x = 12.0;
double performance_panel_y = 92.0;
double view_axes_panel_x = -1.0;
double view_axes_panel_y = 76.0;
double view_axes_panel_size = 84.0;
double occlusion_sample_spacing_meters = 250.0;
double occlusion_clearance_margin_meters = 10.0;
PSC_USE_JSON
};
namespace adminive {
template <>
struct Type_Descriptor<Cesium_Graphics_Config_Data> {
static auto get() {
using T = Cesium_Graphics_Config_Data;
auto descriptor = object<T>("cesium_graphics_config", "Cesium 图形配置",
ADMINIVE_FIELD_LABEL(T, debug_show_frames_per_second, "显示帧率").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, target_frame_rate, "目标帧率").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, use_browser_recommended_resolution, "使用浏览器推荐分辨率").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, resolution_scale, "分辨率缩放").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, msaa_samples, "MSAA 采样数").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, fxaa, "启用 FXAA").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, shadows, "启用阴影").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, enable_lighting, "启用光照").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, solar_lighting, "启用太阳光照").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, solar_light_intensity, "太阳光强度").editable().required().number_input().visible_on("${$self.solar_lighting}"),
ADMINIVE_FIELD_LABEL(T, maximum_screen_space_error, "最大屏幕空间误差").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, terrain_enabled_in_3d, "3D 启用地形").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, terrain_exaggeration, "地形夸张系数").editable().required().number_input().visible_on("${$self.terrain_enabled_in_3d}"),
ADMINIVE_FIELD_LABEL(T, terrain_limit_maximum_level, "限制地形最大层级").editable().boolean_input().visible_on("${$self.terrain_enabled_in_3d}"),
ADMINIVE_FIELD_LABEL(T, terrain_maximum_level, "地形最大层级").editable().required().number_input().visible_on("${$self.terrain_enabled_in_3d && $self.terrain_limit_maximum_level}"),
ADMINIVE_FIELD_LABEL(T, terrain_cache_tiles, "地形缓存瓦片数").editable().required().number_input().visible_on("${$self.terrain_enabled_in_3d}"),
ADMINIVE_FIELD_LABEL(T, terrain_occlusion_enabled, "启用地形遮挡").editable().boolean_input().visible_on("${$self.terrain_enabled_in_3d}"),
ADMINIVE_FIELD_LABEL(T, surface_navigation_reference_visible, "显示地表导航参考").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, view_axes_visible, "显示视图坐标轴").editable().boolean_input(),
ADMINIVE_FIELD_LABEL(T, performance_panel_x, "性能面板 X").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, performance_panel_y, "性能面板 Y").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, view_axes_panel_x, "坐标轴面板 X").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, view_axes_panel_y, "坐标轴面板 Y").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, view_axes_panel_size, "坐标轴面板尺寸").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, occlusion_sample_spacing_meters, "遮挡采样间距(米)").editable().required().number_input(),
ADMINIVE_FIELD_LABEL(T, occlusion_clearance_margin_meters, "遮挡净空余量(米)").editable().required().number_input());
return descriptor.validator([](const T& value, Validation_Context& validation) {
if (value.target_frame_rate < 1 || value.target_frame_rate > 120)
validation.error("target_frame_rate", "必须在 1 到 120 之间");
if (value.resolution_scale < 0.2 || value.resolution_scale > 1.5)
validation.error("resolution_scale", "必须在 0.2 到 1.5 之间");
if (value.msaa_samples < 1 || value.msaa_samples > 8)
validation.error("msaa_samples", "必须在 1 到 8 之间");
if (value.maximum_screen_space_error < 1 || value.maximum_screen_space_error > 16)
validation.error("maximum_screen_space_error", "必须在 1 到 16 之间");
if (value.terrain_maximum_level > 24)
validation.error("terrain_maximum_level", "不能大于 24");
if (value.terrain_cache_tiles < 16 || value.terrain_cache_tiles > 2048)
validation.error("terrain_cache_tiles", "必须在 16 到 2048 之间");
if (value.performance_panel_x < 0)
validation.error("performance_panel_x", "不能小于 0");
if (value.performance_panel_y < 0)
validation.error("performance_panel_y", "不能小于 0");
if (value.view_axes_panel_y < 0)
validation.error("view_axes_panel_y", "不能小于 0");
if (value.view_axes_panel_size < 48 || value.view_axes_panel_size > 240)
validation.error("view_axes_panel_size", "必须在 48 到 240 之间");
if (value.occlusion_sample_spacing_meters < 10 || value.occlusion_sample_spacing_meters > 5000)
validation.error("occlusion_sample_spacing_meters", "必须在 10 到 5000 之间");
});
}
};
}
struct Cesium_Graphics_Config {
adminive::Managed_Value<Cesium_Graphics_Config_Data> settings;
void from_base_json(const Psc::JSON* that_json);
[[nodiscard]] Psc::JSON to_base_json() const;
};
struct Map_Model_Item_Config {
std::string url;
double built_in_size = 50.0;
double heading_offset_degrees = 0.0;
double pitch_offset_degrees = 0.0;
double roll_offset_degrees = 0.0;
Map_Model_Item_Config() = default;
explicit Map_Model_Item_Config(std::string url);
Map_Model_Item_Config(std::string url, double built_in_size, double heading, double pitch, double roll);
void from_base_json(const Psc::JSON* that_json);
[[nodiscard]] Psc::JSON to_base_json() const;
};
namespace adminive {
template <>
struct Type_Descriptor<Map_Model_Item_Config> {
static auto get() {
using T = Map_Model_Item_Config;
return object<T>("map_model_item_config", "Cesium 模型",
ADMINIVE_FIELD_LABEL(T, url, "模型地址"),
ADMINIVE_FIELD_LABEL(T, built_in_size, "模型原始尺寸").editable().number_input(),
ADMINIVE_FIELD_LABEL(T, heading_offset_degrees, "航向偏移(度)").editable().number_input(),
ADMINIVE_FIELD_LABEL(T, pitch_offset_degrees, "俯仰偏移(度)").editable().number_input(),
ADMINIVE_FIELD_LABEL(T, roll_offset_degrees, "横滚偏移(度)").editable().number_input());
}
};
}
struct Map_Model_Config {
Map_Model_Item_Config aircraft_model{"/ui/model/aircraft.glb", 50.0, -90.0, 0.0, 0.0};
std::map<std::string, Map_Model_Item_Config> aircraft_models;
Map_Model_Item_Config base_station_model{"/ui/model/base-station.glb", 16.635522, 0.0, 0.0, 0.0};
Map_Model_Item_Config device_model{"/ui/model/device.glb", 80.0, 0.0, 0.0, 0.0};
Map_Model_Config();
void from_base_json(const Psc::JSON* that_json);
[[nodiscard]] Psc::JSON to_base_json() const;
};
namespace adminive {
template <>
struct Type_Descriptor<Map_Model_Config> {
static auto get() {
using T = Map_Model_Config;
return object<T>("map_model_config", "Cesium 模型配置",
ADMINIVE_FIELD_LABEL(T, aircraft_model, "默认飞机模型").read_write(),
ADMINIVE_FIELD_LABEL(T, aircraft_models, "机型模型").read_write(),
ADMINIVE_FIELD_LABEL(T, base_station_model, "基站模型").read_write(),
ADMINIVE_FIELD_LABEL(T, device_model, "设备模型").read_write());
}
};
}
class Config {
public:
Config();
DELETE_COPY(Config)
MLAT_Config mlat;
Web_Server_Config web_server_config;
adminive::Managed_Value<Map_Resources_Config> map_resources_config;
adminive::Managed_Value<Map_View_Config> map_view_config;
Cesium_Graphics_Config cesium_graphics_config;
adminive::Managed_Value<Map_Model_Config> map_model_config;
Mode_ACS_Config mode_acs;
Log_Config log_config;
Console_Config console_config{};
DSP_Config dsp_config;
Psc::JSON drogon_config;
Http_Monitor_Config http_monitor_config;
std::string version;
External_Resources_Manager external_resources_manager;
static void create_missing_config_files();
static Psc::JSON load();
void from_log_json(const Psc::JSON* that_json);
void from_base_json(Psc::JSON* that_json);
Psc::JSON toJson() {
auto ret = Psc::JSON::object({
{"version", version},
{"dsp", dsp_config.to_base_json()},
{"drogon", drogon_config},
{"http_monitor", http_monitor_config.to_base_json()},
{"mlat", mlat.to_base_json()},
{"web_server", web_server_config.to_base_json()},
{"map_resources", map_resources_config.read([](const auto& value) { return value.to_base_json(); })},
{"map_view", map_view_config.read([](const auto& value) { return value.to_base_json(); })},
{"map_models", map_model_config.read([](const auto& value) { return value.to_base_json(); })},
{"mode_acs", mode_acs.to_base_json()},
{"log", log_config.to_base_json()},
{"console", console_config.to_base_json()},
{"external_database", external_resources_manager.to_base_json()},
{"cesium_graphics", cesium_graphics_config.to_base_json()},
});
return ret;
}
static void save();
static void save(Config_Section section);
static void save(Config_Section section, const Psc::JSON& value);
static void merge(Config_Section section, const Psc::JSON& value);
};
#endif