快速入门¶
本文档将引导您从零开始使用 ConfigStore 配置管理中心。
安装与初始化¶
包含头文件¶
#include "cfconfig.hpp" // 主接口
#include "cfconfig/cfconfig_path_provider.h" // 自定义路径提供器(可选)
#include <QString> // Qt 字符串类型
using namespace cf::config;
获取单例实例¶
ConfigStore 使用单例模式,首次访问时自动初始化:
自定义路径配置¶
如需自定义配置文件路径,可以实现 IConfigStorePathProvider 接口:
class CustomPathProvider : public IConfigStorePathProvider {
public:
QString system_path() const override {
return "/etc/myapp/system.ini";
}
QString user_dir() const override {
QString home = getenv("HOME") ? getenv("HOME") : "/tmp";
return home + "/.config/myapp";
}
QString user_filename() const override {
return "user.ini";
}
QString app_dir() const override {
return "/var/lib/myapp/config";
}
QString app_filename() const override {
return "app.ini";
}
bool is_layer_enabled(int layer_index) const override {
return true; // 启用所有层
}
};
// 在首次使用前初始化
auto provider = std::make_shared<CustomPathProvider>();
ConfigStore::instance().initialize(provider);
基础操作¶
读取配置¶
使用默认值¶
最常用的方式是提供默认值,当配置不存在时返回默认值:
// 读取整数配置
int window_width = ConfigStore::instance().query<int>(
KeyView{.group = "ui.window", .key = "width"}, // 键名
800 // 默认值
);
// 读取字符串配置
std::string theme = ConfigStore::instance().query<std::string>(
KeyView{.group = "app", .key = "theme"},
"default"
);
// 读取浮点数配置
double scale = ConfigStore::instance().query<double>(
KeyView{.group = "display", .key = "scale"},
1.0
);
// 读取布尔配置
bool auto_save = ConfigStore::instance().query<bool>(
KeyView{.group = "app", .key = "auto_save"},
true
);
Optional 查询¶
使用 std::optional 可以判断配置是否存在:
// 查询可能不存在的配置
auto port = ConfigStore::instance().query<int>(
KeyView{.group = "network", .key = "port"}
);
if (port.has_value()) {
std::cout << "端口: " << port.value() << std::endl;
} else {
std::cout << "端口未配置,使用默认值 8080" << std::endl;
}
// 或者使用结构化绑定(C++17)
if (auto value = ConfigStore::instance().query<int>(
KeyView{.group = "network", .key = "port"})) {
std::cout << "端口: " << *value << std::endl;
}
指定层查询¶
直接查询特定层的配置值,不经过优先级合并:
// 只查询 User 层的配置
auto user_theme = ConfigStore::instance().query<std::string>(
KeyView{.group = "app", .key = "theme"},
Layer::User // 指定层
);
if (user_theme.has_value()) {
std::cout << "用户设置的主题: " << user_theme.value() << std::endl;
}
写入配置¶
基本写入¶
默认写入 App 层:
// 写入整数
ConfigStore::instance().set(
KeyView{.group = "ui.window", .key = "width"},
1024
);
// 写入字符串
ConfigStore::instance().set(
KeyView{.group = "app", .key = "theme"},
std::string("dark")
);
// 写入浮点数
ConfigStore::instance().set(
KeyView{.group = "display", .key = "scale"},
1.5
);
// 写入布尔值
ConfigStore::instance().set(
KeyView{.group = "app", .key = "auto_save"},
false
);
选择目标层¶
将配置写入指定层:
// 写入用户配置
ConfigStore::instance().set(
KeyView{.group = "app", .key = "theme"},
std::string("dark"),
Layer::User // 写入 User 层
);
// 写入临时配置(不持久化)
ConfigStore::instance().set(
KeyView{.group = "session", .key = "id"},
std::string("abc123"),
Layer::Temp // 写入 Temp 层,重启后丢失
);
通知策略¶
控制变更通知的时机:
// 立即通知(默认)
ConfigStore::instance().set(
KeyView{.group = "app", .key = "theme"},
std::string("dark"),
Layer::App,
NotifyPolicy::Immediate // 立即触发 Watcher
);
// 手动通知(批量操作)
ConfigStore::instance().set(
KeyView{.group = "batch", .key = "a"},
1,
Layer::App,
NotifyPolicy::Manual // 不立即触发
);
ConfigStore::instance().set(
KeyView{.group = "batch", .key = "b"},
2,
Layer::App,
NotifyPolicy::Manual
);
// 批量操作完成后,一次性触发所有 Watcher
ConfigStore::instance().notify();
键管理¶
注册键¶
注册键可以显式声明配置项,并设置初始值:
// 定义键
Key theme_key{
.full_key = "app.theme.name",
.full_description = "应用程序主题名称 (default/dark/light)"
};
// 注册键并设置初始值
auto result = ConfigStore::instance().register_key(
theme_key,
std::string("default"), // 初始值
Layer::App,
NotifyPolicy::Immediate
);
if (result == RegisterResult::KeyRegisteredSuccess) {
std::cout << "键注册成功" << std::endl;
} else {
std::cout << "键已存在" << std::endl;
}
注销键¶
删除不再使用的配置项:
Key theme_key{
.full_key = "app.theme.name",
.full_description = "应用程序主题名称"
};
// 注销键
auto result = ConfigStore::instance().unregister_key(
theme_key,
Layer::App
);
if (result == UnRegisterResult::KeyUnRegisteredSuccess) {
std::cout << "键注销成功" << std::endl;
}
检查键存在¶
// 检查键是否存在(递归查询所有层)
bool exists = ConfigStore::instance().has_key(
KeyView{.group = "app", .key = "theme"}
);
// 检查特定层是否存在该键
bool in_user = ConfigStore::instance().has_key(
KeyView{.group = "app", .key = "theme"},
Layer::User
);
监听配置变更¶
基本监听¶
// 监听单个键的变更
auto handle = ConfigStore::instance().watch(
"app.theme.name",
[](const Key& k, const std::any* old_value, const std::any* new_value, Layer layer) {
std::cout << "配置变更: " << k.full_key << std::endl;
if (old_value && new_value) {
auto old = std::any_cast<std::string>(*old_value);
auto new_v = std::any_cast<std::string>(*new_value);
std::cout << " " << old << " -> " << new_v << std::endl;
}
}
);
通配符监听¶
使用通配符 * 监听多个键:
// 监听所有 app.* 的变更
auto handle = ConfigStore::instance().watch(
"app.*",
[](const Key& k, const std::any* old_value, const std::any* new_value, Layer layer) {
std::cout << "应用配置变更: " << k.full_key << std::endl;
}
);
// 监听所有 theme 相关的配置
auto theme_watcher = ConfigStore::instance().watch(
"*.theme.*",
[](const Key& k, const std::any* old_value, const std::any* new_value, Layer layer) {
std::cout << "主题配置变更: " << k.full_key << std::endl;
}
);
取消监听¶
// 保存监听句柄
WatcherHandle handle = ConfigStore::instance().watch("app.*", callback);
// 取消监听
ConfigStore::instance().unwatch(handle);
手动通知模式¶
// 使用 Manual 策略添加 Watcher
auto handle = ConfigStore::instance().watch(
"batch.*",
callback,
NotifyPolicy::Manual // 手动通知模式
);
// 执行批量修改
ConfigStore::instance().set(KeyView{.group = "batch", .key = "a"}, 1,
Layer::App, NotifyPolicy::Manual);
ConfigStore::instance().set(KeyView{.group = "batch", .key = "b"}, 2,
Layer::App, NotifyPolicy::Manual);
// 手动触发通知
ConfigStore::instance().notify();
持久化操作¶
同步到磁盘¶
// 异步同步(默认,不阻塞调用方)
ConfigStore::instance().sync(SyncMethod::Async);
// 同步同步(阻塞直到写入完成)
ConfigStore::instance().sync(SyncMethod::Sync);
重新加载配置¶
查看待写入变更¶
// 获取待同步的变更数量
size_t pending = ConfigStore::instance().pending_changes();
std::cout << "待同步变更数: " << pending << std::endl;
完整示例:应用程序配置管理¶
以下是一个完整的应用程序配置管理示例:
#include "cfconfig.hpp"
#include <iostream>
using namespace cf::config;
class AppConfig {
public:
// 初始化配置
void init() {
auto& config = ConfigStore::instance();
// 注册默认配置
config.register_key(
Key{.full_key = "app.theme", .full_description = "应用主题"},
std::string("default"),
Layer::App
);
config.register_key(
Key{.full_key = "app.language", .full_description = "应用语言"},
std::string("zh_CN"),
Layer::App
);
config.register_key(
Key{.full_key = "ui.window.width", .full_description = "窗口宽度"},
1024,
Layer::App
);
config.register_key(
Key{.full_key = "ui.window.height", .full_description = "窗口高度"},
768,
Layer::App
);
// 监听配置变更
watch_changes();
}
// 加载配置
void load() {
auto& config = ConfigStore::instance();
theme_ = config.query<std::string>(
KeyView{.group = "app", .key = "theme"}, "default");
language_ = config.query<std::string>(
KeyView{.group = "app", .key = "language"}, "zh_CN");
window_width_ = config.query<int>(
KeyView{.group = "ui.window", .key = "width"}, 1024);
window_height_ = config.query<int>(
KeyView{.group = "ui.window", .key = "height"}, 768);
print_config();
}
// 保存配置
void save() {
auto& config = ConfigStore::instance();
config.set(KeyView{.group = "app", .key = "theme"}, theme_);
config.set(KeyView{.group = "app", .key = "language"}, language_);
config.set(KeyView{.group = "ui.window", .key = "width"}, window_width_);
config.set(KeyView{.group = "ui.window", .key = "height"}, window_height_);
// 同步到磁盘
config.sync(SyncMethod::Sync);
}
// 打印当前配置
void print_config() {
std::cout << "当前配置:" << std::endl;
std::cout << " 主题: " << theme_ << std::endl;
std::cout << " 语言: " << language_ << std::endl;
std::cout << " 窗口: " << window_width_ << "x" << window_height_ << std::endl;
}
// 设置主题
void set_theme(const std::string& theme) {
auto& config = ConfigStore::instance();
config.set(KeyView{.group = "app", .key = "theme"}, theme);
theme_ = theme;
}
private:
void watch_changes() {
auto& config = ConfigStore::instance();
// 监听主题变更
theme_watcher_ = config.watch(
"app.theme",
[this](const Key& k, const std::any* old_value, const std::any* new_value, Layer layer) {
if (new_value) {
theme_ = std::any_cast<std::string>(*new_value);
std::cout << "主题已变更为: " << theme_ << std::endl;
apply_theme();
}
}
);
}
void apply_theme() {
std::cout << "应用主题: " << theme_ << std::endl;
// 实际应用主题的逻辑...
}
std::string theme_;
std::string language_;
int window_width_;
int window_height_;
WatcherHandle theme_watcher_;
};
int main() {
AppConfig app_config;
// 初始化配置
app_config.init();
// 加载配置
app_config.load();
// 修改配置
app_config.set_theme("dark");
return 0;
}