kunlang_tbox/include/config/TboxConfigManager.h

159 lines
5.3 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.

#pragma once
#include <chrono>
#include <memory>
#include <mutex>
#include <string>
#include <string_view>
#include "TboxConfigClient.h"
#include "TboxConfigSemantic.h"
// =======================================================
// TboxConfigManager
// - 表驱动生成 getter / setter
// - 支持多项修改 + commit
// - 自动 version 检测 + reload
// =======================================================
class TboxConfigManager
{
public:
static TboxConfigManager& instance()
{
static TboxConfigManager inst;
return inst;
}
// ================= 初始化 =================
bool init(const std::string& server = "127.0.0.1", int port = 18080)
{
std::lock_guard<std::mutex> lock(mtx_);
client_ = std::make_unique<TboxConfigClient>(server, port);
bool ok = client_->fetch();
last_check_ = std::chrono::steady_clock::now();
return ok;
}
uint64_t version()
{
ensure();
return client_ ? client_->version() : 0;
}
// ===================================================
// 🔑 配置字段定义表(唯一维护点)
// type, Name, semantic, default
// ===================================================
#define TBOX_CONFIG_FIELDS(X) \
/* -------- 基础身份 -------- */ \
X(std::string, DeviceNo, tbox::semantic::DEVICE_NO, "KL001") \
X(std::string, VehicleId, tbox::semantic::VEHICLE_ID, "V010001") \
X(std::string, Vin, tbox::semantic::VIN, "") \
\
/* -------- 云平台 -------- */ \
X(std::string, PlatformIp, tbox::semantic::PLATFORM_IP, "") \
X(int, PlatformPort, tbox::semantic::PLATFORM_PORT, 0) \
X(std::string, MqttIp, tbox::semantic::MQTT_IP, "") \
X(int, MqttPort, tbox::semantic::MQTT_PORT, 1883) \
X(std::string, MqttUsername, tbox::semantic::MQTT_USERNAME, "") \
X(std::string, MqttPassword, tbox::semantic::MQTT_PASSWORD, "") \
\
/* -------- 驾驶舱 -------- */ \
X(std::string, CockpitMqttIp, tbox::semantic::COCKPIT_MQTT_IP, "") \
X(int, CockpitMqttPort, tbox::semantic::COCKPIT_MQTT_PORT, 1883) \
\
/* -------- 协议相关 -------- */ \
X(int, LoginSeq, tbox::semantic::LOGIN_SEQ, 1) \
X(std::string, LoginSeqDate, tbox::semantic::LOGIN_SEQ_DATE, "000000") \
X(int, HeartbeatInterval, tbox::semantic::HEARTBEAT_INTERVAL, 60)
// ================= Getter 自动生成 =================
#define GEN_GET(type, name, semantic, def) \
type get##name() { return getValue<type>(semantic, def); }
TBOX_CONFIG_FIELDS(GEN_GET)
#undef GEN_GET
// ================= Setter写入缓存不立即提交 =================
#define GEN_SET(type, name, semantic, def) \
void set##name(const type& v) { setValue<type>(semantic, v); }
TBOX_CONFIG_FIELDS(GEN_SET)
#undef GEN_SET
// ================= 统一提交 =================
bool commit()
{
ensure();
return client_->commitAndFetch();
}
private:
TboxConfigManager() = default;
~TboxConfigManager() = default;
TboxConfigManager(const TboxConfigManager&) = delete;
TboxConfigManager& operator=(const TboxConfigManager&) = delete;
// ================= 自动刷新机制 =================
void ensureFresh()
{
auto now = std::chrono::steady_clock::now();
if (now - last_check_ < check_interval_) return;
last_check_ = now;
// 简单粗暴,但稳定:直接 fetch
client_->fetch();
}
void ensure()
{
if (!client_)
{
client_ = std::make_unique<TboxConfigClient>();
client_->fetch();
}
ensureFresh();
}
// ================= 泛型访问 =================
template <typename T>
T getValue(std::string_view semantic, const T& def)
{
ensure();
if constexpr (std::is_same_v<T, int>)
{
auto v = client_->getInt(semantic);
return v ? *v : def;
}
else if constexpr (std::is_same_v<T, bool>)
{
auto v = client_->getBool(semantic);
return v ? *v : def;
}
else
{
auto v = client_->getString(semantic);
return v ? *v : def;
}
}
template <typename T>
void setValue(std::string_view semantic, const T& v)
{
ensure();
if constexpr (std::is_same_v<T, int>)
client_->setInt(semantic, v);
else if constexpr (std::is_same_v<T, bool>)
client_->setBool(semantic, v);
else
client_->setString(semantic, v);
}
private:
std::mutex mtx_;
std::unique_ptr<TboxConfigClient> client_;
std::chrono::steady_clock::time_point last_check_{};
const std::chrono::seconds check_interval_{30};
};