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 个共享数据类

类名

说明

SyncDocumentChart

谱面根文档

SyncTrack

轨道节点

SyncNote

音符

SyncBeat

音乐时间

SyncBpmAxis

可变 BPM 时间轴

SyncTimeSignatureMap

拍号映射

SyncFloatAxis

浮点动画轴

SyncVector2Axis

Vector2 动画轴

SyncVector3Axis

Vector3 动画轴

SyncVector4Axis

Vector4 动画轴

SyncSpeedAxis

速度轴

SyncTrans

过渡类型枚举

SyncEase

缓动类型枚举

2.5.2. 3 个编辑器组件

类名

说明

SyncProgressManager

谱面伴生播放引擎

SyncTimeline

归一化坐标映射

SyncBeatGrid

节拍线数据

2.5.3. 2 个运行时类

类名

说明

SyncChart

编译后只读谱面

SyncChartPlayer

墙钟驱动播放引擎

2.5.4. 1 个通用组件

类名

说明

SyncNodePool

绑定 PackedScene 的对象池

备注

Sync 不内置判定引擎:判定由你在自己的 GDScript 里写——引擎 暴露的全部数据(SyncChart.get_note_info()kind/ hit_time_ms/end_time_ms/is_hold/metadataSyncChartPlayer.get_chart_progress_ms() 等)足够写任何判定。 详见 Sync 包概览 的"No judgement engine — by design"。

2.6. 两种构建产物

Sync/ 产出两种形式:

  1. 核心静态库scons,产物在 build/)— 数据层核心

  2. GDExtensionscons -f SConstruct.extension,产物在 addons/sync/bin/)— 在 Godot 中注册全部 19 个类

两者同源:静态库是核心本体的可独立构建形式,GDExtension 在它之上 附加 Godot 包装层与 DocData。