diff --git a/SPEC.md b/SPEC.md index 9af038d..668db2c 100644 --- a/SPEC.md +++ b/SPEC.md @@ -399,58 +399,362 @@ comm_send → 投递到对应 fd ## 11. libdatacenter 自研模块详细功能 -### 功能点(来自 RTU 原工程 myDatacenter.h + datacenter/*.cpp 分析) +> 基于 RTU 原工程 libdatacenter v1 与 libdatacenter_2 完整源码分析。 +> 新工程采用纯 C 接口(`extern "C"`) + C++ 内部实现,参数文件读写通过钩子解耦。 -#### 11.1 信号注册(5 种信号类型) -| 序号 | 函数 | 说明 | -|------|------|------| -| D01 | `dc_signal_out(saddr, desc, data_type, p_data)` | 注册输出信号(遥测/遥信) | -| D02 | `dc_signal_out_with_callback(...)` | 输出信号+变化回调 | -| D03 | `dc_signal_in(saddr, desc, link_saddr, p_data)` | 注册输入信号(关联输出信号) | -| D04 | `dc_signal_in_with_callback(...)` | 输入信号+变化回调 | -| D05 | `dc_signal_ao(saddr, desc, data_type, ctrl_type, p_data, cb, mod)` | 注册模拟输出(遥控) | -| D06 | `dc_signal_param(saddr, desc, data_type, ctrl_type, p_data, num, cb, mod)` | 注册参数(定值) | -| D07 | `dc_signal_yk(saddr, desc, data_type, ctrl_type, p_data, cb, mod)` | 注册遥控信号 | +### 11.0 模块架构与设计思想 -#### 11.2 信号控制 -| 序号 | 函数 | 说明 | -|------|------|------| -| D08 | `dc_signal_ao_set_val(saddr, step, ctrl, p_data, mod)` | 设置 AO 值(SBO/直接) | -| D09 | `dc_signal_param_set_val(saddr, step, ctrl, zone, p_data, mod)` | 设置定值(带区号) | -| D10 | `dc_signal_yk_set_status(saddr, step, ctrl, p_data, mod)` | 设置遥控状态 | +``` +┌──────────────────────────────────────────────────────────────┐ +│ 应用层(协议栈/Web/主程序) │ +│ 调用 dc_xxx_register / dc_xxx_set_val / dc_run_100ms 等 │ +├──────────────────────────────────────────────────────────────┤ +│ libdatacenter(纯 C 接口层) │ +│ ┌──────────┬──────────┬──────────┬──────────┬────────────┐ │ +│ │ out 信号 │ in 信号 │ yk 信号 │ ao 信号 │ param 信号 │ │ +│ │ (遥测/ │ (关联 │ (遥控) │ (模拟 │ (定值/ │ │ +│ │ 遥信) │ 输出) │ │ 输出) │ 参数) │ │ +│ └──────────┴──────────┴──────────┴──────────┴────────────┘ │ +│ ┌──────────────────────────────────────────────────────────┐ │ +│ │ 内部引擎:hash查找 / 值校验 / 脏标记 / 变化检测 / 回路阻断│ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ ┌──────────────┬──────────────┬────────────────────────────┐ │ +│ │ 事件队列 │ 扰动队列 │ 故障队列 │ │ +│ │ (SOE) │ (Disturb) │ (Fault) │ │ +│ └──────────────┴──────────────┴────────────────────────────┘ │ +│ ┌──────────────────────────────────────────────────────────┐ │ +│ │ 参数配置钩子(解析/保存/变更通知) │ │ +│ │ 异步执行钩子(发起/结果/超时/取消) │ │ +│ └──────────────────────────────────────────────────────────┘ │ +├──────────────────────────────────────────────────────────────┤ +│ 实现层(C++: unordered_map + XXH3_128bits 哈希 + mutex)│ +└──────────────────────────────────────────────────────────────┘ +``` -#### 11.3 信号查询 -| 序号 | 函数 | 说明 | -|------|------|------| -| D11 | `dc_get_out_signal_info(saddr, desc, data_type, p_data)` | 查询输出信号信息 | -| D12 | `dc_get_in_signal_info(...)` | 查询输入信号 | -| D13 | `dc_get_ao_signal_info(...)` | 查询 AO 信号 | -| D14 | `dc_get_param_signal_info(...)` | 查询参数信号 | -| D15 | `dc_get_yk_signal_info(...)` | 查询遥控信号 | -| D16 | `dc_get_signal_val(p_data, data_type)` | 信号值转字符串 | -| D17 | `dc_set_out_signal_val(saddr, set_data, mod)` | 设置输出信号值 | -| D18 | `dc_get_signal_count(type)` | 按类型统计信号数 | +**核心约束**: +- 信号唯一标识用 `saddr`(字符串,如 `"RPC:1:YC:1:val"`) +- 每个信号注册时绑定 `module_id`(模块标识字符串),用于回路阻断 +- out 信号值变更不是同步回调,而是**脏标记 + 100ms 延迟批量检测**(避免频繁回调) +- yk/ao/param 控制值变更才是**同步回调**(控制场景需要即时响应) +- 参数定值支持多区(如运行区/检修区),每区独立存储 -#### 11.4 事件/扰动/故障队列 -| 序号 | 函数 | 说明 | -|------|------|------| -| D19 | `dc_event_queue_push(soe)` | SOE 事件入队 | -| D20 | `dc_event_register_queue_pop(cb)` | 注册事件消费回调 | -| D21 | `dc_disturb_dd_queue_push(dd)` | 扰动数据入队 | -| D22 | `dc_disturb_dd_register_queue_pop(cb)` | 注册扰动消费回调 | -| D23 | `dc_fault_queue_push(fault)` | 故障数据入队 | -| D24 | `dc_fault_register_queue_pop(cb)` | 注册故障消费回调 | +### 11.1 数据结构 -#### 11.5 控制步骤枚举 +#### 11.1.1 控制枚举 ```c -SIGNAL_CTRL_STEP { READY, SELECT, DIRECT, CANCEL } // SBO 控制步骤 -SIGNAL_CTRL_TYPE { NONE, DIRECT_NORMAL, SBO_NORMAL } // 控制类型 +enum SIGNAL_CTRL_TYPE +{ + NONE = 0, /* 无控制 */ + DIRECT_NORMAL = 1, /* 直控(直接执行,无需选择-确认) */ + SBO_NORMAL = 2, /* 选控(选择-确认两阶段,SBO: Select Before Operate) */ +}; + +enum SIGNAL_CTRL_STEP +{ + READY = 0, /* 就绪/空闲 */ + SELECT = 1, /* 选择(SBO 第一步:锁住信号,暂存选择值) */ + DIRECT = 2, /* 执行(SBO 第二步:确认后写入,或直控直接执行) */ + CANCEL = 3, /* 取消(回退到 READY) */ +}; ``` -### 源文件组成(15 个 .cpp 文件) +#### 11.1.2 控制上下文 +```c +typedef struct +{ + uint8_t step : 2; /* 当前控制步骤 SIGNAL_CTRL_STEP */ + uint8_t type : 2; /* 控制类型 SIGNAL_CTRL_TYPE */ + uint8_t backup : 4; /* 备用 */ + uint8_t data_type; /* 数据类型 */ + void *p_data; /* 暂存数据指针(SELECT时保存选择值,DIRECT时用于校验) */ +} stru_signal_ctrl; ``` -datacenter.cpp dc_cfg_check.cpp dc_event.cpp -dc_param.cpp dc_signal.cpp dc_signal_compare.cpp -dc_signal_core.cpp dc_signal_ctrl.cpp dc_signal_find.cpp -dc_signal_query.cpp dc_signal_show.cpp dc_signal_util.cpp + +#### 11.1.3 信号参数元数据 +```c +typedef struct +{ + float min; /* 最小值 */ + float max; /* 最大值 */ + float step; /* 步长 */ + char unit[32]; /* 单位(如 "kV", "A", "Hz") */ +} stru_signal_param; ``` + +#### 11.1.4 内部信号节点 +```c +typedef struct stru_signal +{ + uint32_t id; /* 全局唯一ID(递增分配,用于 id_index 数组索引) */ + XXH128_hash_t hash; /* 128位哈希(saddr 的 XXH3_128bits) */ + char saddr[128]; /* 短地址 */ + char desc[256]; /* 描述 */ + uint8_t data_type; /* 数据类型 */ + + /* 数据指针列表(out/in/yk/ao 为单元素,param 为多区数组) */ + void **vec_p_data; /* 动态数组:当前数据指针 */ + int vec_p_data_count; /* 数据指针个数 */ + void *p_last_data; /* 上一次数据快照(out信号变更检测用) */ + void **vec_p_default_data; /* 默认值指针(param 恢复出厂用) */ + + /* 链接关系 */ + char link_saddr[128]; /* in 信号:链接的 out saddr */ + char **link_saddrs; /* out 被哪些 in 链接 */ + int link_count; + + uint8_t ctrl_type; /* 控制类型 SIGNAL_CTRL_TYPE */ + stru_signal_param param; /* 参数元数据(min/max/step/unit) */ + + /* 回调列表(每个 cb 绑定 module_id 用于回路阻断) */ + struct + { + char *module_id; + out_signal_change_cb out_cb; /* out 信号专用 */ + signal_change_cb ctrl_cb; /* yk/ao/param 专用 */ + } cb_list[16]; + int cb_count; + + char last_caller_module[64]; /* 最后修改本信号的模块ID(回路阻断) */ +} stru_signal; +``` + +#### 11.1.5 信号存储架构 +```c +/* 每种信号类型一个独立的 map(saddr→signal*)+ id数组 */ +typedef struct +{ + pthread_mutex_t mtx; + uint32_t signal_id; /* 自增ID分配器 */ + void *map_signals; /* C++ unordered_multimap */ + stru_signal **id_index; /* id→指针 数组(支持按ID遍历) */ + int id_index_cap; +} stru_signal_map; + +typedef struct +{ + stru_signal_map signal_out; + stru_signal_map signal_in; + stru_signal_map signal_yk; + stru_signal_map signal_ao; + stru_signal_map signal_param; +} stru_datacenter; +``` + +### 11.2 模块生命周期与周期性函数 + +| 序号 | 函数 | 说明 | +|------|------|------| +| D00a | `dc_init(path)` | 初始化:解析参数配置文件(param.xml→self_param.xml),注册配置中的信号 | +| D00b | `dc_run_100ms()` | 每100ms:① out信号变化检测+批量触发回调 ② 事件/扰动/故障队列弹出消费 | +| D00c | `dc_run_1000ms()` | 每1000ms:检测参数变更标志,有变更则写 self_param.xml | + +### 11.3 信号注册(5 种类型,均带 module_id) + +**关键设计**:所有注册函数必须传入 `module_id` 字符串,用于回路阻断——当模块 A 修改信号值时,A 自身的回调不会被触发,只通知其他模块。 + +| 序号 | 函数 | 说明 | +|------|------|------| +| D01 | `dc_signal_out(saddr, desc, data_type, p_data, module_id)` | 注册输出信号(遥测/遥信) | +| D02 | `dc_signal_out_with_callback(saddr, desc, data_type, p_data, cb, module_id)` | 注册输出信号+变化回调(延迟触发,非同步) | +| D03 | `dc_signal_out_link_with_callback(saddr, pp_data, cb, module_id)` | 链接已有 out 信号,获取数据指针并注册回调 | +| D04 | `dc_signal_in(saddr, desc, link_saddr, pp_data, module_id)` | 注册输入信号,自动关联输出信号的数据指针 | +| D05 | `dc_signal_in_with_callback(saddr, desc, link_saddr, pp_data, cb, module_id)` | 输入信号+回调(回调挂在被链接的out上) | +| D06 | `dc_signal_ao(saddr, desc, data_type, ctrl_type, p_data, cb, module_id)` | 注册模拟输出信号 | +| D07 | `dc_signal_ao_link_with_callback(saddr, pp_data, cb, module_id)` | 链接已有 ao 信号 | +| D08 | `dc_signal_param(saddr, desc, data_type, ctrl_type, pp_data, num, cb, module_id)` | 注册定值参数信号,num为定值区数 | +| D09 | `dc_signal_param_link_with_callback(saddr, pp_data, num, cb, module_id)` | 链接已有 param 信号 | +| D10 | `dc_signal_yk(saddr, desc, data_type, ctrl_type, p_data, cb, module_id)` | 注册遥控信号 | +| D11 | `dc_signal_yk_link_with_callback(saddr, pp_data, cb, module_id)` | 链接已有 yk 信号 | + +**注册流程**(以 out 为例): +``` +dc_signal_out(saddr, desc, data_type, p_data, module_id) + → 检查 saddr 是否已存在(重复注册报错) + → 计算 XXH3_128bits(saddr) + → 分配 p_last_data(保存旧值快照,用于变更检测) + → 插入 g_datacenter.signal_out + → dc_set_param_cfg_change(true) /* ao/param 注册需标记配置变更 */ +``` + +**in 信号关联逻辑**: +``` +dc_signal_in(saddr, desc, link_saddr, pp_data) + → 查找 link_saddr 对应的 out 信号 + → (*pp_data) = out信号的 vec_p_data[0](共享同一数据指针) + → 在 out 信号的 link_saddrs 中追加 in 的 saddr + → signal.data_type = out.data_type(数据类型跟随 out) +``` + +### 11.4 信号控制(含 SBO 流程 + 值校验 + 回路阻断) + +| 序号 | 函数 | 说明 | +|------|------|------| +| D12 | `dc_signal_ao_set_val(saddr, step, ctrl, p_data, module_id)` | 设置 AO 值(带 SBO 流程控制+值校验) | +| D13 | `dc_signal_ao_set_val_without_check(saddr, data_type, p_data, module_id)` | 设置 AO 值(跳过校验,用于初始化恢复) | +| D14 | `dc_signal_param_set_val(saddr, step, ctrl, zone, p_data, module_id)` | 设置定值(指定区号,带校验) | +| D15 | `dc_signal_param_set_val_without_check(saddr, data_type, zone, p_data, module_id)` | 设置定值(跳过校验) | +| D16 | `dc_signal_yk_set_status(saddr, step, ctrl, p_data, module_id)` | 设置遥控状态 | + +**SBO 控制流程**: +``` +─── READY ──→ SELECT(锁住信号,暂存选择值到 ctrl.p_data) + │ │ + │ ├──→ CANCEL(回退 READY,ctrl.step = READY) + │ │ + │ └──→ DIRECT(校验值==选择值 → 写入 vec_p_data → ctrl.step=READY) + │ + └──→ DIRECT(直控模式:直接写入,无需 SELECT) +``` + +**值校验链**(以 `dc_check_val_valid` 为例): +1. 检查 zone 是否越界 +2. 检查新旧值是否变化(无变化→拒绝) +3. 根据 data_type 检查值是否在 param.min/max范围内 +4. 所有类型(bool/int/float/double/IP/MAC/str)全覆盖 + +**回路阻断机制**(核心设计): +```cpp +// 回调通知时,跳过发起修改的模块自身 +for(auto &entry : p_signal->cb_list) +{ + if (entry.first == module_id) continue; // 回路阻断:不发给自己 + entry.second(saddr, step, data_type, zone, p_data); +} +``` + +**out 信号变化的延迟回调**(与 ao/yk/param 不同): +``` +dc_set_out_signal_val(saddr, set_data, module_id) + → p_signal->last_caller_module = module_id /* 记录调用方 */ + → dc_mark_signal_dirty(p_signal) /* 标记脏,不立即回调 */ + → 写入新值到 vec_p_data[0] + +dc_run_100ms() + → dc_signal_out_change_check() + → 遍历 g_dirty_out_signals + → 比较 vec_p_data[0] vs p_last_data + → 有变化→通知cb_list(跳过 last_caller_module) + → 更新 p_last_data +``` + +### 11.5 信号查询 + +| 序号 | 函数 | 说明 | +|------|------|------| +| D17 | `dc_get_out_signal_info(saddr, desc, desc_len, data_type, pp_data)` | 查询 out 信号 | +| D18 | `dc_get_in_signal_info(saddr, desc, desc_len, data_type, pp_data)` | 查询 in 信号 | +| D19 | `dc_get_ao_signal_info(saddr, desc, desc_len, data_type, p_param, ctrl_type, pp_data)` | 查询 ao 信号(含参数元数据) | +| D20 | `dc_get_param_signal_info(saddr, desc, desc_len, data_type, p_param, ctrl_type, pp_vec_data, p_count)` | 查询 param 信号(多区数据指针列表) | +| D21 | `dc_get_yk_signal_info(saddr, desc, desc_len, data_type, ctrl_type, pp_data)` | 查询 yk 信号 | +| D22 | `dc_get_signal_val(p_data, data_type, buf, buf_len)` | 信号值→字符串(纯 C 接口) | +| D23 | `dc_set_out_signal_val(saddr, set_data, module_id)` | 设置 out 信号值(脏标记+延迟回调) | +| D24 | `dc_get_signal_count(type_str)` | 按类型统计信号数("out"/"in"/"yk"/"ao"/"param") | +| D25 | `dc_get_signal_info_by_id(type_str, id, saddr, saddr_len, desc, desc_len, data_type_str, type_str_len, ctrl_type, link_str, link_len)` | 按ID查询信号基本信息(供前端遍历) | + +### 11.6 事件/扰动/故障队列 + +| 序号 | 类型 | 入队函数 | 注册消费回调 | 数据内容 | +|------|------|----------|-------------|----------| +| D26 | SOE 事件 | `dc_event_queue_push(p_soe)` | `dc_event_register_queue_pop(cb)` | saddr + status + 时间戳(sec,ms) | +| D27 | 扰动数据 | `dc_disturb_dd_queue_push(p_dd)` | `dc_disturb_dd_register_queue_pop(cb)` | saddr + fVal + 时间戳(sec,ms) | +| D28 | 故障录波 | `dc_fault_queue_push(p_fault)` | `dc_fault_register_queue_pop(cb)` | vec_soe + vec_disturb_yc | + +**队列消费机制**: +- 支持多个消费者(`vector`) +- `dc_run_100ms()` 中批量弹出消费,加锁 swap 减少锁持有时间 +- push 时自动补时间戳(sec==0 && ms==0 时自动获取当前时间) + +### 11.7 参数配置文件解析与保存(解耦钩子设计) + +**设计原则**:参数文件读写通过钩子函数注册,datacenter 不直接依赖 tinyxml2。 + +```c +/** + * @brief 参数配置文件提供者(由应用层注册) + * @param path 输出:返回配置文件的路径 + * @param len 路径缓冲区大小 + * @param buf 输出:返回配置文件的内容缓冲区 + * @param size 输出:返回内容大小 + * @return 0 成功,-1 没找到/不支持 + */ +typedef int (*dc_param_cfg_read_cb)(char *path, int len, char **buf, int *size); + +/** + * @brief 参数配置保存回调(由应用层注册) + * @param path 文件路径 + * @param buf 要保存的内容 + * @param size 内容大小 + * @return 0 成功,-1 失败 + */ +typedef int (*dc_param_cfg_save_cb)(const char *path, const char *buf, int size); +``` + +| 序号 | 函数 | 说明 | +|------|------|------| +| D29 | `dc_param_cfg_register_read_cb(cb)` | 注册参数配置读取回调 | +| D30 | `dc_param_cfg_register_save_cb(cb)` | 注册参数配置保存回调 | +| D31 | `dc_param_cfg_changed()` | 查询配置是否有未保存变更(返回 0/1) | + +**配置文件语义**(由钩子实现方保证,datacenter 不解析格式): +- `param.xml`:参数模板(元数据:saddr, desc, type, min, max, step, unit, default, value) +- `self_param.xml`:用户运行时值(仅 saddr + value,持久化动态修改) +- 初始化时:先读 param.xml 的元数据注册信号 → 再读 self_param.xml 覆盖运行时值 +- 配置变更时:dc_param_cfg_check() 检测到变更标志 → 调 save_cb 写入 self_param.xml + +### 11.8 类型系统工具函数 + +| 序号 | 函数 | 说明 | +|------|------|------| +| D32 | `dc_get_data_type_str_by_id(data_type)` | DATA_TYPE_U8→"uint8_t" | +| D33 | `dc_get_data_type_id_by_str("float")` | "float"→DATA_TYPE_F32 | +| D34 | `dc_get_data_type_len(data_type)` | 获取字节长度 | +| D35 | `dc_create_data_ptr_by_type(data_type)` | 根据类型 new 并清零 | +| D36 | `dc_delete_signal_data(p_data, data_type)` | 根据类型 delete | +| D37 | `dc_set_signal_val_from_str(p_data, data_type, str)` | 字符串→值("3.14"→3.14f) | +| D38 | `dc_set_signal_val(p_data, data_type, set_data)` | 内存拷贝赋值 | +| D39 | `dc_data_compare(data_type, p_data1, p_data2)` | 类型感知的值比较 | + +### 11.9 调试与导出 + +| 序号 | 函数 | 说明 | +|------|------|------| +| D40 | `dc_save_out_signals_xml(path)` | 导出所有已注册 out 信号到 XML(供前端 PLC 配置读取) | + +### 11.10 源文件对照表 + +| RTU原工程文件 | 新工程文件 | 说明 | +|---------------|-----------|------| +| `inc/dc_signal.h` | `inc/myDatacenter.h` | 合并为单头文件(纯C接口) | +| `inc/dc_event.h` | ↑ | 合并 | +| `inc/dc_param.h` | ↑ | 合并 | +| `src/dc_signal.cpp` | `src/myDatacenter.cpp` | 信号注册主体 | +| `src/dc_signal_core.cpp` | ↑ | map操作+脏标记 | +| `src/dc_signal_ctrl.cpp` | ↑ | 值校验+控制流程 | +| `src/dc_signal_query.cpp` | ↑ | 信号查询+out变化检测 | +| `src/dc_signal_compare.cpp` | ↑ | 值比较+元数据应用 | +| `src/dc_signal_find.cpp` | ↑ | hash查找 | +| `src/dc_signal_util.cpp` | ↑ | 类型工具函数 | +| `src/dc_signal_show.cpp` | ↑ | 信号展示+cmd命令(可选) | +| `src/datacenter.cpp` | ↑ | 初始化+生命周期 | +| `src/dc_param.cpp` | `src/dc_param_hook.cpp` | 参数配置文件钩子注册 | +| `src/dc_cfg_check.cpp` | ↑ | self_param.xml变更检测+保存 | +| `src/dc_event.cpp` | `src/dc_event.cpp` | 事件队列 | +| `src/dc_signal_internal.h` | `src/dc_signal_internal.h` | 内部共享声明 | + +### 11.11 新旧工程差异对比 + +| 维度 | RTU 原工程 v1 | RTU 原工程 v2 | 新工程 libdatacenter | +|------|-------------|-------------|-------------------| +| 接口语言 | C++ (std::string) | 纯C (const char*) | 纯C (extern "C") | +| 哈希查找 | XXH128 multimap | XXH128 multimap | unordered_map + XXH3_128bits hasher(O(1),复用 libmy_xxhash CBB) | +| 参数文件 | tinyxml2 直接解析 | 同上 | 回调钩子解耦 | +| 异步执行 | 无 | 有(_exec_async) | 预留接口+钩子 | +| 回路阻断 | ✓ | ✓ | ✓ | +| module_id | std::string | const char* | const char* | +| 控制校验 | ✓ | ✓ | ✓ | +| SBO流程 | ✓ | ✓ | ✓ | +| 多区定值 | ✓ | ✓ | ✓ | +| 变更检测 | 脏标记+100ms | 同v1 | 同v1 | +| 调试命令 | cmd_dc | 无 | 预留 | +| 错误码 | -1/0 | enum dc_error_t | enum dc_error_t | +| 未实现 | — | — | 异步执行模型(预留)、tinyxml2绑定(钩子替代) | diff --git a/docs/README.md b/docs/README.md index 452b905..c322b60 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,36 +17,50 @@ | libfunc | [API-libfunc.md](public/libfunc/API-libfunc.md) | 纯 C | 65 个基础工具函数 | | libmd5 | [API-libmd5.md](public/libmd5/API-libmd5.md) | 纯 C | MD5 消息摘要 (RFC 1321) | | libtask | [API-libtask.md](public/libtask/API-libtask.md) | 纯 C | 定时器 + 事件 + 消息队列 | +| libdatacenter | [API-libdatacenter.md](public/libdatacenter/API-libdatacenter.md) | C 接口+C++ 内部 | 信号数据中心(5种信号+事件队列) | | libcJSON | [API-libcJSON.md](public/libcJSON/API-libcJSON.md) | 纯 C (开源库) | JSON 解析/生成 | | libmy_xxhash | [API-libmy_xxhash.md](public/libmy_xxhash/API-libmy_xxhash.md) | 纯 C (开源库) | xxHash 快速哈希 | +| libxml | [API-libxml.md](public/libxml/API-libxml.md) | C 接口+C++ 内部 | XML 解析(C接口包裹 tinyxml2) | +| libcmd | [API-libcmd.md](public/libcmd/API-libcmd.md) | C 接口+C++ 内部 | 命令注册/补全 + 内置 linenoise | ### 模块依赖关系图 ``` - ┌──────────┐ - │ myBase.h │ (颜色/大小端/类型常量) - └────┬─────┘ - ┌──────────────┼──────────────┐ - ▼ ▼ ▼ - ┌─────────┐ ┌─────────┐ ┌──────────┐ - │ liblist │ │ libfunc │ │ libmd5 │ - │ (链表) │ │ (65函数)│ │ (MD5) │ - └────┬────┘ └────┬────┘ └──────────┘ - │ │ - ▼ ▼ - ┌─────────────────────────┐ - │ liblog │ (异步日志,依赖 - │ (消息池+批量+文件轮转) │ liblist + libfunc) - └─────────────────────────┘ + ┌──────────┐ + │ myBase.h │ (颜色/大小端/类型常量) + └────┬─────┘ + ┌──────────────┼──────────────┐ + ▼ ▼ ▼ + ┌─────────┐ ┌─────────┐ ┌──────────┐ + │ liblist │ │ libfunc │ │ libmd5 │ + │ (链表) │ │ (65函数)│ │ (MD5) │ + └────┬────┘ └────┬────┘ └──────────┘ + │ │ + ▼ ▼ + ┌─────────────────────────┐ + │ liblog │ (异步日志) + │ (消息池+批量+文件轮转) │ + └─────────────────────────┘ - ┌──────────┐ ┌──────────────┐ - │ libcJSON │ │ libmy_xxhash │ (开源库,直接使用) - └──────────┘ └──────────────┘ - - ┌────────────────────────────────┐ - │ libtask │ (事件/定时器/消息队列) - │ (timerfd + epoll + pthread) │ - └────────────────────────────────┘ + ┌──────────┐ ┌──────────────┐ + │ libcJSON │ │ libmy_xxhash │ (开源库) + └──────────┘ └──────┬───────┘ + │ + ┌─────────────────────┼─────────────────────┐ + │ ▼ │ + │ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ + │ │ libtask │ │ libxml │ │ libcmd │ │ (P2库提前实现 + │ │ (事件/ │ │ (C接口+ │ │ (命令 │ │ 供datacenter + │ │ 定时器) │ │ tinyxml2)│ │ 框架) │ │ 依赖) + │ └──────────┘ └────┬─────┘ └────┬────┘ │ + │ │ │ │ + │ ▼ ▼ │ + │ ┌─────────────────────────────┐ │ + │ │ libdatacenter │ │ + │ │ (信号数据中心 5种信号类型) │ │ + │ │ 依赖: libxml + libcmd │ │ + │ │ + libmy_xxhash │ │ + └──────────┴─────────────────────────────┘ ``` ### 构建与编译 diff --git a/release/src/public/makefile b/release/src/public/makefile index 41daf40..bb4d03a 100644 --- a/release/src/public/makefile +++ b/release/src/public/makefile @@ -1,4 +1,4 @@ -SUBDIRS := ./liblist ./libfunc ./liblog ./libmd5 ./libcJSON ./libmy_xxhash ./libtask +SUBDIRS := ./liblist ./libfunc ./liblog ./libmd5 ./libcJSON ./libmy_xxhash ./libtask ./libxml ./libcmd ./libdatacenter define make_subdir @for d in $(SUBDIRS); do [ -f "$$d/makefile" ] && (cd "$$d" && make -f makefile $1) || true; done endef