# 系统架构 ## 1. 技术基线 | 项目 | 选择 | |---|---| | 语言 | C++20(第三方 Runtime target 可使用其原生标准) | | UI | Qt 6 Widgets | | 预览画布 | `QOpenGLWidget` + 自研批次渲染器 | | 构建 | CMake 3.25+、CMake Presets | | Windows 编译器 | Visual Studio 2022 / MSVC v143 | | macOS 编译器 | Apple Clang | | 进程管理 | `QProcess` | | 设置存储 | `QSettings` | | JSON | Qt JSON | | 图片加载 | Qt Image plugins,随程序离线部署 | | 测试 | Qt Test 或 Catch2,原型结束时二选一 | CMake 只用于开发构建,不是最终用户的运行依赖。Windows 可以使用 Visual Studio Generator 或 Ninja + MSVC。 ## 2. 分层结构 ```text UI ├─ 资源组表格 ├─ 预览与播放控制 ├─ Editor 管理 └─ 任务、日志与报告 ↓ Application Services ├─ ScanService ├─ PreviewService ├─ EditorRegistry ├─ RecoveryCoordinator └─ ReportService ↓ Domain ├─ AssetGroup ├─ SpineVersion ├─ EditorInstallation ├─ RecoveryJob └─ RecoveryResult ↓ Infrastructure ├─ Filesystem / Process ├─ Runtime Plugin Host ├─ Spine CLI Adapter ├─ Atlas Unpackers └─ Output Publisher ``` UI 只表达状态和用户意图,不能直接调用 Spine CLI 或解析 Atlas。 ## 3. 建议目录 ```text DateToSpine/ CMakeLists.txt CMakePresets.json cmake/ docs/ licenses/ resources/ icons/ shaders/ translations/ src/ app/ domain/ scan/ atlas/ editor/ preview/ recovery/ report/ platform/ macos/ windows/ ui/ util/ runtime-api/ runtime-plugins/ spine38/ spine40/ spine41/ spine42/ spine43/ third_party/ spine-runtimes/ licenses/ tests/ unit/ integration/ compatibility/ manifests/ fixtures/ generated/ external/ packaging/ macos/ windows/ ``` `tests/fixtures/external/` 用于本地准备的官方测试资源,不进入发行包。 ## 4. 多版本 Runtime 隔离 五套 Runtime 不能直接链接进同一个主程序命名空间。每个版本编译成独立动态模块,并隐藏所有上游 C++ 符号,只导出稳定的 DateToSpine C ABI。 ```text dts-runtime-3_8 dts-runtime-4_0 dts-runtime-4_1 dts-runtime-4_2 dts-runtime-4_3 ``` 公共 ABI 只允许: - 固定宽度整数 - POD 结构体 - UTF-8 字节串 - 不透明句柄 - 显式长度的数组 - 函数指针回调 禁止跨模块传递 Qt 对象、STL 容器、异常或 Spine Runtime 类。 每个适配模块承担: - 对应版本 JSON/SKEL 读取 - Atlas 绑定 - 动画状态推进 - Skin/Animation 查询和切换 - 把绘制结果转换为统一顶点、索引和 draw command - 把上游错误转换为统一错误码 ## 5. 预览渲染边界 Runtime 插件负责骨骼计算和裁剪;主程序渲染器负责: - 纹理创建和缓存 - 顶点/索引上传 - Shader - Blend mode - 相机、背景和调试覆盖层 - DPI 和窗口生命周期 Runtime 不直接创建 Qt 或 OpenGL 对象。这使 Runtime 适配可独立测试,也避免上下文所有权问题。 ## 6. Spine CLI 边界 所有 Editor 调用必须经过 `ISpineCli`: ```text probe installation probe version import data export normalized json unpack atlas inspect project ``` 实现要求: - 使用 `QProcess::setProgram` 和 `setArguments`。 - 不经过 shell。 - 每次调用有超时、取消令牌、工作目录和独立日志。 - 只终止本软件启动的子进程。 - 对 Windows 优先选择 `Spine.com`。 - 对 macOS 把 `.app` 规范化为内部可执行文件。 ## 7. 任务并发 - 扫描、哈希、图片头校验可以在线程池执行。 - OpenGL 资源操作只在所属渲染线程执行。 - Spine Editor 调用默认全局串行。 - Spine 官方 Atlas 解包与工程导入全局串行,并受任务取消状态约束。 - 每个恢复任务有独立临时目录和取消状态。 ## 8. 文件长度和复杂度约束 自研代码执行以下软上限,超过时必须在评审中说明或拆分: | 文件类型 | 建议上限 | |---|---:| | 头文件 | 200 行 | | 普通 `.cpp` | 350 行 | | UI `.cpp` | 450 行 | | 单元测试文件 | 500 行 | 同时执行: - 一个类只有一个主要职责。 - `MainWindow` 不包含解析、转换和进程逻辑。 - 禁止无边界的 `Utils` 类。 - 平台代码不得散落到业务模块。 - 版本差异留在 Runtime adapter 和 version policy 中。 - 第三方上游源码保持原样,位于 `third_party/`,不纳入自研文件行数限制。 CI 将检查自研源文件行数、循环依赖和禁止目录引用。 ## 9. 可测试性 核心依赖使用小接口注入: ```text IFileSystem IProcessRunner ISpineCli IRuntimePlugin IAtlasUnpacker IClock IReportSink ``` 单元测试不启动真实 Editor;集成和兼容测试才调用本地 Spine Editor。