2. 架构总览
Sync 采用**单一 GDExtension 架构**:0.5.0 起,由原来的三个插件
合并为 Sync/ 一个包,数据层、编辑器组件与运行时全部由同一个
扩展注册,没有跨扩展桥接、没有加载顺序约束、没有导入库链接。
2.1. 整体架构图
┌──────────────────────────────────────────────────────────┐
│ Sync(单一 GDExtension,入口 sync_library_init) │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ src/godot — Godot 包装层(godot:: 命名空间) │ │
│ │ · register_types.cpp 注册全部 19 个类 │ │
│ │ · SyncProgressManager / SyncTimeline / │ │
│ │ SyncBeatGrid / SyncChart / SyncChartPlayer / │ │
│ │ SyncNodePool │ │
│ └───────────────────────┬────────────────────────────┘ │
│ │ 包装类直接用 Ref<T> 调用 │
│ ┌───────────────────────┴────────────────────────────┐ │
│ │ src/core — 核心层(sync::core 命名空间) │ │
│ │ · 谱面数据模型 / BPM 轴 / 动画轴 / JSON │ │
│ │ · 静态库(build/)供测试与纯 C++ 调用方使用 │ │
│ └────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
2.2. 分层设计
2.2.1. 核心层(sync::core)
核心位于 include/sync/ + src/core/,以 C++17 实现,作为
整个引擎的数据层基础:
谱面数据模型(DocumentChart / PlayChart / Note / Track / 动画轴)
时间系统(Beat / BpmAxis / TimeSignatureMap)
谱面 JSON 序列化
核心同时产出**静态库** (scons,产物在 build/),供测试与
纯 C++ 调用方直接使用;run_tests.py 直接编译并运行核心逻辑测试。
2.2.2. Godot 包装层(godot::)
包装层位于 include/sync_godot/ + src/godot/,把核心类包装为
Godot 可反射的类(属性、方法、信号绑定)。全部 19 个类在
src/godot/register_types.cpp 中一次性注册(唯一的注册处),
扩展入口为 sync_library_init。19 个类的 API 参考 XML 位于
doc_classes/,经 SConstruct.extension 编译进 DocData。
0.5.0 合并后,包装类的公开接口直接使用具体 C++ 类型(如
Ref<T>):GDScript 侧所有 Sync* 类都来自同一个 DLL,
不再存在跨扩展实例解析问题。
2.3. 无桥接 / 无加载顺序
三包时代为跨扩展共享类引入的机制已全部移除:
跨扩展桥接(实例解析)— 已删除
SYNC_GODOT_API导出宏 / 导入库链接 — 已删除加载顺序约束(核心扩展必须先加载)— 不存在了
单个 GDExtension 注册全部类,Godot 只需加载一个 DLL。
2.4. 目录结构
OpenSource/Sync/
├── include/sync/ # 核心头(sync::core 命名空间)
├── include/sync_godot/ # Godot 包装层头(godot:: 命名空间,19 个类)
├── src/core/ # 核心实现(静态库 build/)
├── src/godot/ # 包装层实现 + register_types.cpp(19 类唯一注册处)
├── doc_classes/ # 19 个类参考 XML(SConstruct.extension 编译进 DocData)
├── addons/sync/ # sync.gdextension + bin/(运行时分发物)
├── project/ # demo Godot 项目
├── godot-cpp/ # 4.3 分支绑定(不入库)
├── test/ # 纯 C++ 逻辑测试 + 基准
├── run_tests.py # 纯 C++ 测试运行器(g++ 直编)
├── SConstruct # 核心静态库构建
└── SConstruct.extension # GDExtension 构建(编译 src/core + src/godot + DocData)
2.5. 命名约定
19 个类全部由 addons/sync 注册,按类别分组:
2.5.1. 13 个共享数据类
类名 |
说明 |
|---|---|
|
谱面根文档 |
|
轨道节点 |
|
音符 |
|
音乐时间 |
|
可变 BPM 时间轴 |
|
拍号映射 |
|
浮点动画轴 |
|
Vector2 动画轴 |
|
Vector3 动画轴 |
|
Vector4 动画轴 |
|
速度轴 |
|
过渡类型枚举 |
|
缓动类型枚举 |
2.5.2. 3 个编辑器组件
类名 |
说明 |
|---|---|
|
谱面伴生播放引擎 |
|
归一化坐标映射 |
|
节拍线数据 |
2.5.3. 2 个运行时类
类名 |
说明 |
|---|---|
|
编译后只读谱面 |
|
墙钟驱动播放引擎 |
2.5.4. 1 个通用组件
类名 |
说明 |
|---|---|
|
绑定 PackedScene 的对象池 |
备注
Sync 不内置判定引擎:判定由你在自己的 GDScript 里写——引擎
暴露的全部数据(SyncChart.get_note_info() 的 kind/
hit_time_ms/end_time_ms/is_hold/metadata,
SyncChartPlayer.get_chart_progress_ms() 等)足够写任何判定。
详见 Sync 包概览 的"No judgement engine — by design"。
2.6. 两种构建产物
Sync/ 产出两种形式:
核心静态库 (
scons,产物在build/)— 数据层核心GDExtension (
scons -f SConstruct.extension,产物在addons/sync/bin/)— 在 Godot 中注册全部 19 个类
两者同源:静态库是核心本体的可独立构建形式,GDExtension 在它之上 附加 Godot 包装层与 DocData。