完成 StellarX 核心重构、缺陷修复与测试收口
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
# 新增功能模块 / 模块重构
|
||||
|
||||
> 适用场景:新增模块、重大模块重构、核心架构能力演进。
|
||||
> 不适用场景:小接口或轻量功能变更,请使用“功能变更”模板。
|
||||
|
||||
## 基本信息
|
||||
|
||||
- 模块 ID:Module-20260109-0001
|
||||
- 模块名称: SxLog 轻量日志系统
|
||||
- 状态:已完成(历史记录;本次仅归档,未重新验证)
|
||||
- 类型:新增模块
|
||||
- 所属系统 / 子系统: StellarX / Logging / Diagnostics
|
||||
- 版本 / 分支: v3.0.0 / master
|
||||
- 环境: Windows x64 / Visual Studio 2022 / Debug、Release / 控制台模式
|
||||
- 负责人: Ysm-04(历史实现)
|
||||
|
||||
## 背景与目标
|
||||
|
||||
- 背景: Canvas、TabControl、Table 以及快照重绘链路逐渐复杂,仅依靠断点难以还原事件、重绘和状态变化顺序。
|
||||
- 当前痛点:
|
||||
- 缺少统一的日志级别、Tag 过滤和输出渠道。
|
||||
- 分散日志难以控制噪声,也难以保存为可回放证据。
|
||||
- 协作和对外输出需要中英文文本选择能力。
|
||||
- 目标:
|
||||
- 提供统一日志入口和宏封装。
|
||||
- 支持级别控制、Tag 白名单/黑名单、控制台输出、文件输出和按大小滚动。
|
||||
- 提供 `SX_T` / `SxT` 双语文本选择以及作用域耗时记录。
|
||||
- 非目标:[可选]
|
||||
- 不负责字符编码转换。
|
||||
- 不依赖 WinAPI 调试输出通道,不引入第三方日志库。
|
||||
- 不保证高频同步 I/O 场景下无性能影响。
|
||||
|
||||
## 模块边界
|
||||
|
||||
- 职责:
|
||||
- `SxLogger` 负责配置、过滤、格式化与 Sink 分发。
|
||||
- `ConsoleSink`、`FileSink` 负责具体输出。
|
||||
- `SxLogLine` 通过 RAII 完成流式拼接和行提交。
|
||||
- `SxLogScope` 记录作用域耗时。
|
||||
- 不负责什么:
|
||||
- 不负责日志采集服务、网络上报、结构化查询或跨进程聚合。
|
||||
- 不对业务敏感信息进行脱敏。
|
||||
- 外部依赖:
|
||||
- C++ 标准库的流、文件、互斥量、原子变量和时间工具。
|
||||
- `setGBK()` 面向 Windows 控制台环境。
|
||||
- 对外能力 / API:
|
||||
- `SxLogger::Get()`、`setMinLevel()`、`setTagFilter()`、`clearTagFilter()`。
|
||||
- `enableConsole()`、`enableFile()`、`disableFile()`。
|
||||
- `setLanguage()`、`setGBK()`。
|
||||
- `SX_LOG_TRACE`、`SX_LOGD/I/W/E/F`、`SX_TRACE_SCOPE`、`SX_T` / `SxT`。
|
||||
- 关键数据 / 状态:
|
||||
- `SxLogConfig` 保存级别、格式、Tag 策略以及文件配置。
|
||||
- Logger 单例持有配置和 Sink;语言选择使用原子状态。
|
||||
|
||||
## 设计说明
|
||||
|
||||
- 核心流程:
|
||||
1. 日志宏先调用 `shouldLog()` 判断级别、Tag 和可用 Sink。
|
||||
2. 命中条件时构造 `SxLogLine` 并进行流式拼接。
|
||||
3. `SxLogLine` 析构时提交完整日志行。
|
||||
4. `SxLogger::logLine()` 在互斥保护下格式化并分发给控制台和文件 Sink。
|
||||
- 关键对象 / 类关系:
|
||||
- `SxLogger`:中心配置与分发器。
|
||||
- `ILogSink`:输出目标抽象。
|
||||
- `ConsoleSink` / `FileSink`:具体输出实现。
|
||||
- `SxLogLine` / `SxLogScope`:调用端 RAII 辅助对象。
|
||||
- 生命周期:
|
||||
- Logger 为进程内单例;Sink 随配置启用或关闭。
|
||||
- 日志行对象只在命中过滤条件时短暂存在,并在析构时提交。
|
||||
- 事件 / 渲染 / 数据流:[按模块类型填写]
|
||||
- 调用点 -> 宏短路 -> 日志行拼接 -> Logger 过滤/格式化 -> Sink 输出。
|
||||
- 关键不变量:
|
||||
- `shouldLog()` 返回 false 时不应构造日志行或执行字符串拼接。
|
||||
- 单条日志必须作为整体写出,不能被其他线程插入破坏。
|
||||
- 语言切换只选择文本,不进行编码转换。
|
||||
- 未启用任何 Sink 时应直接短路。
|
||||
- 降级 / 回退策略:[可选]
|
||||
- 将最低级别设为 Off,或关闭控制台和文件 Sink。
|
||||
- 必要时通过编译期开关关闭日志宏。
|
||||
|
||||
## 实现与影响
|
||||
|
||||
- 关键实现点:
|
||||
- Tag 过滤使用适合少量 Tag 的线性查找。
|
||||
- 文件输出支持追加和按字节阈值滚动。
|
||||
- 输出阶段使用互斥量保证行级串行;语言状态使用原子变量。
|
||||
- 涉及文件 / 类 / 函数:
|
||||
- 历史路径:`include/StellarX/SxLog.h`
|
||||
- 历史路径:`src/SxLog.cpp`
|
||||
- `SxLogger`、`SxLogConfig`、`ILogSink`、`ConsoleSink`、`FileSink`、`SxLogLine`、`SxLogScope`
|
||||
- 兼容性影响:
|
||||
- 新增独立模块,不改变既有控件公共 API;调用方可选择是否接入。
|
||||
- 性能影响:
|
||||
- 未命中过滤条件时由宏短路降低开销。
|
||||
- 命中时存在格式化、互斥和 I/O 成本;高频 Trace 输出可能成为瓶颈并快速增大日志文件。
|
||||
- 风险点:
|
||||
- 文件权限、文件占用或滚动重命名失败可能影响持续写入。
|
||||
- 控制台代码页差异可能导致中文显示不一致。
|
||||
- 日志内容如果包含敏感数据,需要由调用方自行控制。
|
||||
|
||||
## 测试与验证
|
||||
|
||||
- 测试范围:
|
||||
- 日志级别、Tag 白名单/黑名单、控制台和文件输出、文件滚动、语言切换、不可写路径。
|
||||
- 验证步骤:
|
||||
|
||||
1. 启用控制台并依次输出不同级别,检查格式、级别和语言文本。
|
||||
2. 启用文件输出,验证追加写、Tag 过滤以及不可写路径的返回值。
|
||||
3. 使用较小的滚动阈值持续输出,检查旧文件重命名和新文件续写。
|
||||
|
||||
- 验证结果:
|
||||
- PDF 给出了上述测试方案,但“验证证据”仍是待填占位内容,没有附带日志、截图或性能数据。
|
||||
- 本次只确认模块源码、公共接口、提交和发布记录存在,未重新执行运行时测试。
|
||||
- 已知限制 / 遗留问题:[可选]
|
||||
- 同步互斥和文件 I/O 不适合无约束的高频热路径。
|
||||
- `setGBK()` 只调整终端解释输出的方式,不进行字符串编码转换。
|
||||
|
||||
## 落地信息
|
||||
|
||||
- 关联功能变更 ID:[可选]
|
||||
- 关联 BUG / Fix:[可选]
|
||||
- Commit: `5cb59b36525cde93de83313551296c6458694110`
|
||||
- PR:[可选]
|
||||
- 发布版本:[可选] v3.0.0
|
||||
- 相关文档:[可选]
|
||||
- `StellarX功能_模块变更.pdf` 第 24-28 页。
|
||||
- 历史 `CHANGELOG.md` 的 v3.0.0 条目。
|
||||
@@ -69,11 +69,11 @@
|
||||
- 再将局部矩形映射为世界坐标矩形
|
||||
- 由控件内部受控路径应用运行态矩形
|
||||
- 关键对象 / 类关系:
|
||||
- [`Control`](D:/programming/imGUI-easyX/imGui-easyX/Control.h) 作为统一布局规格与基础解算入口
|
||||
- [`Window`](D:/programming/imGUI-easyX/imGui-easyX/Window.cpp) 负责顶层控件统一收口
|
||||
- [`Canvas`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.cpp) 负责容器子控件重映射
|
||||
- [`TabControl`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.cpp) 外层接入统一解算,内部页签栏 / 页面区仍自管
|
||||
- [`Table`](D:/programming/imGUI-easyX/imGui-easyX/Table.cpp) 通过 `LayoutCapability` 显式禁止 `Y` 轴 Stretch
|
||||
- [`Control`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Control.h) 作为统一布局规格与基础解算入口
|
||||
- [`Window`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Window.cpp) 负责顶层控件统一收口
|
||||
- [`Canvas`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Canvas.cpp) 负责容器子控件重映射
|
||||
- [`TabControl`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/TabControl.cpp) 外层接入统一解算,内部页签栏 / 页面区仍自管
|
||||
- [`Table`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Table.cpp) 通过 `LayoutCapability` 显式禁止 `Y` 轴 Stretch
|
||||
- 生命周期:
|
||||
- 设计态矩形 `local*` 在普通 resize / 重排过程中不自动回写
|
||||
- 运行态矩形由统一解算器产出,再通过内部路径应用
|
||||
@@ -102,17 +102,17 @@
|
||||
- 将 `Table` 的 `Y` 轴固定能力边界收回控件自身
|
||||
- 在 `z-testDome.cpp` 增加 `KEY == 5` 布局专项回归
|
||||
- 涉及文件 / 类 / 函数:
|
||||
- [`CoreTypes.h`](D:/programming/imGUI-easyX/imGui-easyX/CoreTypes.h)
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/Control.h)
|
||||
- [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Control.cpp)
|
||||
- [`Canvas.h`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.h)
|
||||
- [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.cpp)
|
||||
- [`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Window.cpp)
|
||||
- [`TabControl.h`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.h)
|
||||
- [`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.cpp)
|
||||
- [`Table.h`](D:/programming/imGUI-easyX/imGui-easyX/Table.h)
|
||||
- [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Table.cpp)
|
||||
- [`z-testDome.cpp`](D:/programming/imGUI-easyX/imGui-easyX/z-testDome.cpp)
|
||||
- [`CoreTypes.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/CoreTypes.h)
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Control.h)
|
||||
- [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Control.cpp)
|
||||
- [`Canvas.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Canvas.h)
|
||||
- [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Canvas.cpp)
|
||||
- [`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Window.cpp)
|
||||
- [`TabControl.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/TabControl.h)
|
||||
- [`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/TabControl.cpp)
|
||||
- [`Table.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Table.h)
|
||||
- [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Table.cpp)
|
||||
- [`z-testDome.cpp`](D:/programming/imGUI-easyX/imGui-easyX/app/z-testDome.cpp)
|
||||
- 兼容性影响:
|
||||
- 向后兼容旧锚点 API
|
||||
- 当前阶段未删除旧 getter / setter
|
||||
|
||||
@@ -67,12 +67,12 @@
|
||||
- 内容驱动控件在自己的受控路径里刷新运行态尺寸。
|
||||
- 局部重绘提交后,由父容器按实际绘制顺序补画 coverage 上方的 overlay 兄弟。
|
||||
- 关键对象 / 类关系:
|
||||
- [`Control`](D:/programming/imGUI-easyX/imGui-easyX/Control.h):几何语义、解算入口、设计基线提交入口。
|
||||
- [`Label`](D:/programming/imGUI-easyX/imGui-easyX/Label.cpp):内容驱动尺寸,`draw()` 只消费运行态矩形。
|
||||
- [`Canvas`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.cpp):管理直接子控件的世界坐标映射与局部 overlay 补画。
|
||||
- [`TabControl`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.cpp):外层接统一解算,内部页签栏 / 页面区继续自管。
|
||||
- [`Table`](D:/programming/imGUI-easyX/imGui-easyX/Table.cpp):当前版本 `X Stretch / Y Fixed`,并保留内部受控结构尺寸基线刷新。
|
||||
- [`Window`](D:/programming/imGUI-easyX/imGui-easyX/Window.cpp):顶层托管重绘收口与 overlay 兄弟补画。
|
||||
- [`Control`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Control.h):几何语义、解算入口、设计基线提交入口。
|
||||
- [`Label`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Label.cpp):内容驱动尺寸,`draw()` 只消费运行态矩形。
|
||||
- [`Canvas`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Canvas.cpp):管理直接子控件的世界坐标映射与局部 overlay 补画。
|
||||
- [`TabControl`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/TabControl.cpp):外层接统一解算,内部页签栏 / 页面区继续自管。
|
||||
- [`Table`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Table.cpp):当前版本 `X Stretch / Y Fixed`,并保留内部受控结构尺寸基线刷新。
|
||||
- [`Window`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Window.cpp):顶层托管重绘收口与 overlay 兄弟补画。
|
||||
- 生命周期:
|
||||
- 普通 resize / 父容器重排不自动回写 `local*`。
|
||||
- 显式设计基线提交只通过 `commitCurrentGeometryAsDesignRect()` 或控件内部受控结构刷新点发生。
|
||||
@@ -93,21 +93,21 @@
|
||||
## 实现与影响
|
||||
|
||||
- 关键实现点:
|
||||
- 在 [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Control.cpp) 增加布局降级日志、能力边界拦截日志、显式设计基线提交日志。
|
||||
- 在 [`Label.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Label.cpp) 收口内容驱动尺寸刷新,并显式关闭双轴 Stretch。
|
||||
- 在 [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.cpp)、[`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.cpp)、[`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Window.cpp) 收口 overlay 补画。
|
||||
- 在 [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Table.cpp) 收口 `Y Fixed`、分页按钮视觉链与页码重绘。
|
||||
- 在 [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Control.cpp) 增加布局降级日志、能力边界拦截日志、显式设计基线提交日志。
|
||||
- 在 [`Label.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Label.cpp) 收口内容驱动尺寸刷新,并显式关闭双轴 Stretch。
|
||||
- 在 [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Canvas.cpp)、[`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/TabControl.cpp)、[`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Window.cpp) 收口 overlay 补画。
|
||||
- 在 [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Table.cpp) 收口 `Y Fixed`、分页按钮视觉链与页码重绘。
|
||||
- 涉及文件 / 类 / 函数:
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/Control.h)
|
||||
- [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Control.cpp)
|
||||
- [`Label.h`](D:/programming/imGUI-easyX/imGui-easyX/Label.h)
|
||||
- [`Label.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Label.cpp)
|
||||
- [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.cpp)
|
||||
- [`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.cpp)
|
||||
- [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Table.cpp)
|
||||
- [`TextBox.cpp`](D:/programming/imGUI-easyX/imGui-easyX/TextBox.cpp)
|
||||
- [`Dialog.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Dialog.cpp)
|
||||
- [`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Window.cpp)
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Control.h)
|
||||
- [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Control.cpp)
|
||||
- [`Label.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Label.h)
|
||||
- [`Label.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Label.cpp)
|
||||
- [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Canvas.cpp)
|
||||
- [`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/TabControl.cpp)
|
||||
- [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Table.cpp)
|
||||
- [`TextBox.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/TextBox.cpp)
|
||||
- [`Dialog.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Dialog.cpp)
|
||||
- [`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Window.cpp)
|
||||
- 兼容性影响:
|
||||
- 对旧锚点 API 保持兼容。
|
||||
- `Label::textStyle` 仍为公开字段,但使用约定更严格。
|
||||
|
||||
@@ -61,12 +61,12 @@
|
||||
- 内容驱动控件在自身受控路径中刷新运行态尺寸;设计基线不得在普通布局过程中自动漂移。
|
||||
- 托管局部重绘按“脏子树提交 -> 直接分支 coverage -> 传递式 overlay 补画”收口,确保嵌套容器、Tooltip、上层兄弟遮挡链闭合。
|
||||
- 关键对象 / 类关系:
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/Control.h):统一布局解算、设计基线提交、托管重绘底座
|
||||
- [`Label.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Label.cpp):内容驱动尺寸刷新前移,`draw()` 只消费运行态矩形
|
||||
- [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.cpp):直接子树映射、脏子树提交、局部 overlay 补画
|
||||
- [`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.cpp):外层统一布局,内部页签栏/页面区自管,绘制顺序与局部提交顺序统一
|
||||
- [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Table.cpp):当前版本 `X Stretch / Y Fixed`、分页按钮视觉与页码重绘修复
|
||||
- [`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Window.cpp):顶层托管重绘、传递式 overlay 补画、顶层 coverage 收口
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Control.h):统一布局解算、设计基线提交、托管重绘底座
|
||||
- [`Label.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Label.cpp):内容驱动尺寸刷新前移,`draw()` 只消费运行态矩形
|
||||
- [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Canvas.cpp):直接子树映射、脏子树提交、局部 overlay 补画
|
||||
- [`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/TabControl.cpp):外层统一布局,内部页签栏/页面区自管,绘制顺序与局部提交顺序统一
|
||||
- [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Table.cpp):当前版本 `X Stretch / Y Fixed`、分页按钮视觉与页码重绘修复
|
||||
- [`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Window.cpp):顶层托管重绘、传递式 overlay 补画、顶层 coverage 收口
|
||||
- 生命周期:
|
||||
- 普通 resize / 重排不自动回写 `local*`
|
||||
- 公开 setter 只写运行态,不隐式提交设计基线
|
||||
@@ -94,26 +94,26 @@
|
||||
- 修复 Tab 页签按钮与页面绘制顺序不一致导致 Tooltip 被页面覆盖的问题
|
||||
- 修复重复激活已激活页签时的残影 / 快照链扰动问题
|
||||
- 涉及文件 / 类 / 函数:
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/Control.h)
|
||||
- [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Control.cpp)
|
||||
- [`Label.h`](D:/programming/imGUI-easyX/imGui-easyX/Label.h)
|
||||
- [`Label.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Label.cpp)
|
||||
- [`Button.h`](D:/programming/imGUI-easyX/imGui-easyX/Button.h)
|
||||
- [`Button.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Button.cpp)
|
||||
- [`Canvas.h`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.h)
|
||||
- [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.cpp)
|
||||
- [`TabControl.h`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.h)
|
||||
- [`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.cpp)
|
||||
- [`Table.h`](D:/programming/imGUI-easyX/imGui-easyX/Table.h)
|
||||
- [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Table.cpp)
|
||||
- [`TextBox.h`](D:/programming/imGUI-easyX/imGui-easyX/TextBox.h)
|
||||
- [`TextBox.cpp`](D:/programming/imGUI-easyX/imGui-easyX/TextBox.cpp)
|
||||
- [`Dialog.h`](D:/programming/imGUI-easyX/imGui-easyX/Dialog.h)
|
||||
- [`Dialog.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Dialog.cpp)
|
||||
- [`Window.h`](D:/programming/imGUI-easyX/imGui-easyX/Window.h)
|
||||
- [`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Window.cpp)
|
||||
- [`MessageBox.h`](D:/programming/imGUI-easyX/imGui-easyX/MessageBox.h)
|
||||
- [`z-testDome.cpp`](D:/programming/imGUI-easyX/imGui-easyX/z-testDome.cpp)
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Control.h)
|
||||
- [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Control.cpp)
|
||||
- [`Label.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Label.h)
|
||||
- [`Label.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Label.cpp)
|
||||
- [`Button.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Button.h)
|
||||
- [`Button.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Button.cpp)
|
||||
- [`Canvas.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Canvas.h)
|
||||
- [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Canvas.cpp)
|
||||
- [`TabControl.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/TabControl.h)
|
||||
- [`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/TabControl.cpp)
|
||||
- [`Table.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Table.h)
|
||||
- [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Table.cpp)
|
||||
- [`TextBox.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/TextBox.h)
|
||||
- [`TextBox.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/TextBox.cpp)
|
||||
- [`Dialog.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Dialog.h)
|
||||
- [`Dialog.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Dialog.cpp)
|
||||
- [`Window.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Window.h)
|
||||
- [`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Window.cpp)
|
||||
- [`MessageBox.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/MessageBox.h)
|
||||
- [`z-testDome.cpp`](D:/programming/imGUI-easyX/imGui-easyX/app/z-testDome.cpp)
|
||||
- 兼容性影响:
|
||||
- 旧锚点 API 仍可用,内部实现已完全转到新布局模型
|
||||
- `Label::textStyle` 仍为公开字段,但要求样式修改后显式 `setDirty(true)`
|
||||
|
||||
@@ -72,9 +72,9 @@
|
||||
- 新 API 被调用后,控件自动切到 `AnchorToEdges` 布局模式。
|
||||
- 运行时统一解算继续以 `layoutSpec` 为唯一依据。
|
||||
- 关键对象 / 类关系:
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/Control.h):公开布局策略 API 的对外入口。
|
||||
- [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Control.cpp):新 API 的实现、新旧 API 映射共存规则。
|
||||
- [`z-testDome.cpp`](D:/programming/imGUI-easyX/imGui-easyX/z-testDome.cpp):`KEY2` 迁移示例与验证入口。
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Control.h):公开布局策略 API 的对外入口。
|
||||
- [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Control.cpp):新 API 的实现、新旧 API 映射共存规则。
|
||||
- [`z-testDome.cpp`](D:/programming/imGUI-easyX/imGui-easyX/app/z-testDome.cpp):`KEY2` 迁移示例与验证入口。
|
||||
- 生命周期:
|
||||
- 新 API 只影响运行态布局策略,不自动提交设计基线。
|
||||
- 设计基线仍由显式提交路径或控件内部受控路径维护。
|
||||
@@ -97,9 +97,9 @@
|
||||
- 保留 `setAnchor(...)` 与旧 getter,不破坏兼容路径。
|
||||
- 以 `KEY2` 位选择区、功能区、显示区和配置区作为迁移样例,验证新 API 的可用性。
|
||||
- 涉及文件 / 类 / 函数:
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/Control.h)
|
||||
- [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Control.cpp)
|
||||
- [`z-testDome.cpp`](D:/programming/imGUI-easyX/imGui-easyX/z-testDome.cpp)
|
||||
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/include/StellarX/Control.h)
|
||||
- [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/src/StellarX/Control.cpp)
|
||||
- [`z-testDome.cpp`](D:/programming/imGUI-easyX/imGui-easyX/app/z-testDome.cpp)
|
||||
- 兼容性影响:
|
||||
- 兼容旧 `setAnchor(...)` 调用。
|
||||
- 新 API 为新增能力,不影响现有二进制接口使用方式。
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
# 新增功能模块 / 模块重构
|
||||
|
||||
> 适用场景:新增模块、重大模块重构、核心架构能力演进。
|
||||
> 不适用场景:小接口或轻量功能变更,请使用“功能变更”模板。
|
||||
|
||||
## 基本信息
|
||||
|
||||
- 模块 ID:Module-20260915-0001
|
||||
- 模块名称:StellarX 核心库与自动化测试基础设施
|
||||
- 状态:非 UI 与人工 UI 已验证,待提交
|
||||
- 类型:模块重构 / 架构演进
|
||||
- 所属系统 / 子系统:StellarX Core / Unit Test / UI Regression
|
||||
- 版本 / 分支:当前工作区
|
||||
- 环境:Windows + Visual Studio 2022 + MSVC v143 + EasyX
|
||||
- 负责人:Codex 协作修改
|
||||
|
||||
## 背景与目标
|
||||
|
||||
- 背景:
|
||||
- 原应用工程同时承担框架实现、示例入口和回归验证职责,框架代码与测试代码之间缺少明确边界。
|
||||
- 本次全量缺陷修复涉及控件生命周期、重绘、事件循环、MBCS 文本和日志等多个核心模块,需要让应用、单元测试和真实 UI Fixture 复用完全相同的实现。
|
||||
- 当前痛点:
|
||||
- 核心框架源文件分散在应用工程中,难以单独复用和验证。
|
||||
- 仅依赖手工启动窗口,无法稳定覆盖回调期间所有权变化、ASan 内存安全和多配置构建。
|
||||
- UI 控件基于 EasyX 绘制,不是原生子窗口,UIA/WinAppDriver 无法直接按控件语义定位。
|
||||
- 目标:
|
||||
- 将框架实现集中编译为 `StellarX.Core` 静态库。
|
||||
- 建立纯逻辑单元测试、真实 EasyX Fixture 和外部 Win32 UI 驱动三层验证。
|
||||
- 让 Debug、Release、Win32、x64 和 x64 ASan 使用统一的核心实现。
|
||||
- 非目标:[可选]
|
||||
- 不在本次工作中将静态库改为 DLL。
|
||||
- 不迁移到 Unicode,不改变 GUI 只能在主线程使用的约束。
|
||||
- 不将 UI 测试改造成依赖 DPI 或字体的全图 golden image 测试。
|
||||
|
||||
## 模块边界
|
||||
|
||||
- 职责:
|
||||
- `StellarX.Core.vcxproj` 编译 `Window`、`Control`、`Canvas`、各类控件、Dialog、TabControl 和日志实现。
|
||||
- 主应用、Native Unit Test 和 UI Fixture 通过 `ProjectReference` 使用同一份核心实现。
|
||||
- `scripts/test.ps1` 统一组织 Unit、Render、UI、All 和 CI 测试入口。
|
||||
- `scripts/run-ui-tests.ps1` 负责启动 Fixture、注入鼠标输入、等待结果并保存诊断文件。
|
||||
- 不负责什么:
|
||||
- 不负责最终应用资源、业务示例和安装包制作。
|
||||
- 不把 `StellarX.Core.lib` 作为普通 GUI 应用用户的运行时 DLL。
|
||||
- 不替代 EasyX、Visual C++ Runtime 等外部依赖的发布判断。
|
||||
- 外部依赖:
|
||||
- Visual Studio 2022、MSVC v143、Windows SDK。
|
||||
- EasyX 图形库。
|
||||
- Visual Studio Native Unit Test Framework。
|
||||
- UI 套件需要可交互的 Windows 桌面,并会短暂切换前台窗口和移动鼠标。
|
||||
- 对外能力 / API:
|
||||
- 核心库对外 API 通过 `StellarX.h` 汇总。
|
||||
- `StellarX.Core` 本身是构建期静态库,不新增运行时动态加载接口。
|
||||
- 测试入口通过 PowerShell 参数和 Fixture 场景提供,不属于框架公共 API。
|
||||
- 关键数据 / 状态:
|
||||
- `StellarX.Core.lib`:框架实现的静态链接产物。
|
||||
- `StellarX.Tests.dll`:Native Unit Test 产物。
|
||||
- `StellarX.UiFixture.exe`:真实 EasyX UI 场景进程。
|
||||
- `TestResults/`:TRX、JSON、PNG 和日志诊断产物。
|
||||
|
||||
## 设计说明
|
||||
|
||||
- 核心流程:
|
||||
1. `StellarX.Core.vcxproj` 编译框架头文件和源文件。
|
||||
2. `imGui-easyX.vcxproj` 通过 `ProjectReference` 链接核心静态库,应用入口保留在 `z-testDome.cpp`。
|
||||
3. `StellarX.Tests` 和 `StellarX.UiFixture` 同样引用核心工程,避免测试复制另一份框架代码。
|
||||
4. Release 构建将核心代码静态链接进目标可执行文件;运行时不要求单独加载 `StellarX.Core.dll`。
|
||||
- 关键对象 / 类关系:
|
||||
- `StellarX.Core.vcxproj`:核心实现的构建边界。
|
||||
- `Window / Canvas / Control`:窗口托管、控件所有权、事件和重绘基础。
|
||||
- `SxEventLoopInternal.h`:批量事件处理测试辅助。
|
||||
- `SxTextInternal.h`:MBCS 字符边界和密码掩码测试辅助。
|
||||
- `StellarX.Tests`:不创建窗口的逻辑测试。
|
||||
- `StellarX.UiFixture`:创建确定性 EasyX 窗口并导出状态和像素证据。
|
||||
- 生命周期:
|
||||
- 核心库在构建阶段生成,静态链接进应用或测试可执行文件。
|
||||
- Unit 测试进程独立运行;涉及 UAF 的回归可在 ASan 配置中隔离执行。
|
||||
- UI Fixture 按场景创建和关闭图形上下文,失败时由脚本保存证据并发送 `WM_CLOSE`。
|
||||
- 事件 / 渲染 / 数据流:
|
||||
- 逻辑测试使用 FakeControl、假时钟、假消息源和临时目录验证状态转移。
|
||||
- UI 驱动程序通过 `SendInput` 注入鼠标事件,通过 `SetWindowPos` 驱动窗口变化。
|
||||
- Fixture 导出 JSON 状态和 EasyX 后备缓冲像素,脚本按关键像素不变量判断结果。
|
||||
- 关键不变量:
|
||||
- 应用、逻辑测试和 UI Fixture 必须链接同一份核心实现。
|
||||
- ASan 产物与普通 Debug 产物使用独立目录。
|
||||
- UI 场景串行执行,避免多个 EasyX 图形上下文争用桌面。
|
||||
- UI 断言不依赖 DPI、字体抗锯齿和完整截图的像素一致性。
|
||||
- 降级 / 回退策略:[可选]
|
||||
- 没有交互桌面时,CI 只运行逻辑测试;设置 `STELLARX_UI_TESTS=1` 且环境满足条件时才执行 UI。
|
||||
- 全局 resize、Dialog 开关等场景保留整场景重绘兜底。
|
||||
|
||||
## 实现与影响
|
||||
|
||||
- 关键实现点:
|
||||
- 新增 `StellarX.Core` 静态库工程和解决方案项目引用。
|
||||
- 新增 `StellarX.Tests`、`StellarX.UiFixture`、PowerShell 测试脚本和诊断输出约定。
|
||||
- 新增 `SxEventLoopInternal.h`、`SxTextInternal.h` 两个仅供内部实现和测试使用的头文件。
|
||||
- 核心控件采用稳定句柄、延迟变更事务和统一 geometry/coverage 处理。
|
||||
- 涉及文件 / 类 / 函数:
|
||||
- 工程:`StellarX.Core.vcxproj`、`imGui-easyX.vcxproj`、`imGui-easyX.sln`。
|
||||
- 核心:`Control`、`Window`、`Canvas`、`Button`、`Label`、`TextBox`、`Table`、`Dialog`、`TabControl`、`SxLogger`。
|
||||
- 测试:`tests/StellarXTests.cpp`、`tests/UiFixture.cpp`、`scripts/test.ps1`、`scripts/run-ui-tests.ps1`。
|
||||
- 兼容性影响:
|
||||
- 工程内部从直接编译框架源文件调整为引用 `StellarX.Core`。
|
||||
- 本阶段同时包含破坏性公共 API 调整,迁移方式见 [`MIGRATION.md`](D:/programming/imGUI-easyX/imGui-easyX/开发记录/MIGRATION.md)。
|
||||
- 性能影响:
|
||||
- 事件循环单轮最多处理 128 条消息,活动轮不固定休眠,空闲轮短暂休眠。
|
||||
- 静态库不引入运行时动态分发开销;托管重绘仍按覆盖范围选择性提交并保留全局兜底。
|
||||
- 风险点:
|
||||
- EasyX UI 测试依赖前台交互桌面,不能作为无桌面 CI 的默认测试。
|
||||
- 当前 `Render` 入口复用 UI Fixture,尚未形成完全独立的进程内 Native Render 测试类别。
|
||||
- 编译仍存在 EasyX `C4201`、未使用变量和名称遮蔽等非阻断警告。
|
||||
|
||||
## 测试与验证
|
||||
|
||||
- 测试范围:
|
||||
- 所有权事务、空 TabControl、Tab 索引、字体拥有权、MBCS 掩码、Tooltip tick、事件批处理和日志配置。
|
||||
- Button、Label、TextBox、Canvas、Table、Dialog、TabControl 的真实 EasyX 重绘和 coverage 不变量。
|
||||
- Debug x64、Debug x64 ASan、Release x64、Debug Win32,以及 KEY1 至 KEY6 编译。
|
||||
- 验证步骤:
|
||||
|
||||
1. 使用 `scripts/test.ps1 -Suite NonUI` 验证四套逻辑配置、ASan 和 KEY1 至 KEY6 编译。
|
||||
2. 按 `TESTING.md` 的人工 UI 清单验证 KEY1、KEY2、KEY4、KEY5、KEY6。
|
||||
3. 检查 TRX 和人工验收记录;只有明确允许自动 UI 时才使用 `scripts/test.ps1 -Suite All`。
|
||||
|
||||
- 验证结果:
|
||||
- 2026-09-29 的 Debug x64、Debug x64 ASan、Release x64、Debug Win32 均为 15/15 通过。
|
||||
- x64 ASan 未报告内存错误;KEY1 至 KEY6 均编译、链接通过。
|
||||
- 2026-09-30 为 `scripts/test.ps1` 补充 UTF-8 BOM 后,Windows PowerShell 5.1 下的 `NonUI` 全矩阵复验通过。
|
||||
- 本轮未启动自动 UI Fixture;用户于 2026-09-30 手工完成 KEY1 至 KEY6,暂未发现明显问题。
|
||||
- 2026-07-22 的 UI 六类场景三轮通过记录保留为历史证据;当前快照以 2026-09-30 的人工验收结果为准。
|
||||
- 已知限制 / 遗留问题:[可选]
|
||||
- `Render` 当前复用单轮真实 UI Fixture;后续可单独建立进程内渲染测试类别。
|
||||
- UI 自动化仍需要已解锁的交互式桌面。
|
||||
- 本次未清理已有非阻断编译警告。
|
||||
|
||||
## 落地信息
|
||||
|
||||
- 关联功能变更 ID:[可选]
|
||||
- `Feature-20260915-0001`
|
||||
- 关联 BUG / Fix:[可选]
|
||||
- 本次以全量缺陷修复矩阵统一记录,未为每个历史问题重新创建重复 BUG/Fix 文档。
|
||||
- Commit:
|
||||
- 当前工作区未提交
|
||||
- PR:[可选]
|
||||
- 发布版本:[可选]
|
||||
- 相关文档:[可选]
|
||||
- [`TESTING.md`](D:/programming/imGUI-easyX/imGui-easyX/开发记录/TESTING.md)
|
||||
- [`MIGRATION.md`](D:/programming/imGUI-easyX/imGui-easyX/开发记录/MIGRATION.md)
|
||||
Reference in New Issue
Block a user