ChartExtensionParser
谱面扩展段解析器。谱面 JSON 的 extensions 对象中,每个 key 对应一个已注册解析器;模组在 onPreInit 用 ctx.registries().chartExtensions().register(key, parser) 注册,注册键的 namespace:path 就是 extensions 里的 key(如 mymod:effects),因此本接口不自带 key()。宿主在谱面加载时按 key 分发,未注册或 key 格式非法的段直接忽略(第三方谱面可携带任意扩展段,不视为错误)。相关类型:ChartParseContext、ChartRuntimeContext。
方法速览
| 方法 | 用途 |
|---|---|
parse(JsonObject, ChartParseContext) | 解析该扩展段并返回结果对象 |
apply(Object, ChartRuntimeContext) | 解析结果已自动入库后调用,用于注入运行时状态/触发效果 |
parse(JsonObject extensionData, ChartParseContext ctx)
签名:
Object parse(JsonObject extensionData, ChartParseContext ctx);行为:extensionData 是该 key 对应的 JSON 对象;若该段不是 JSON 对象(数组、标量、null),宿主传入一个空 JsonObject。返回值可以是任意对象(也可以为 null),宿主随后会以该段 key 写入运行时上下文并调用 apply。解析失败(抛异常)时宿主捕获并跳过该段,限频告警(5 秒),不影响谱面主流程与其他扩展段。
示例:
@Override
public Object parse(JsonObject extensionData, ChartParseContext ctx) {
MyEffects fx = new MyEffects();
if (extensionData.has("bloom")) {
fx.bloom = extensionData.get("bloom").getAsFloat();
}
fx.lanes = ctx.totalLanes();
return fx;
}apply(Object parsed, ChartRuntimeContext ctx)
签名:
default void apply(Object parsed, ChartRuntimeContext ctx);行为:在 parse 返回后立即调用,parsed 是同一个返回对象。宿主已先把该对象以扩展段 key 写入运行时上下文,因此通常无需再 put(需要额外键名时才写)。游玩上下文加载时,可经 ctx.extraContent() 取得 ExtraContentApi 并立即触发演出原语;非游玩上下文(列表扫描、编辑器)该值为 null,必须判空。宿主在运行时重建(扩展数据为空时的重放)会再次走 parse → apply,实现应保持幂等。异常同样被捕获并跳过该段。
示例:
@Override
public void apply(Object parsed, ChartRuntimeContext ctx) {
ExtraContentApi api = ctx.extraContent(); // 非游玩上下文为 null
if (api != null) {
api.setLaneAlpha(0, 0.3f);
}
}完整签名
public interface ChartExtensionParser {
Object parse(JsonObject extensionData, ChartParseContext ctx);
default void apply(Object parsed, ChartRuntimeContext ctx);
}线程:源码未声明额外线程约束;宿主在谱面加载(游玩场景 loading 阶段)的 GL 主线程同步调用 parse 与 apply。
生命周期阶段:运行期谱面加载时由宿主按 key 分发调用;运行时重建时可能再次调用。
稳定性:2.0 起冻结:2.x 内只增不破(禁止删签名/改签名/改语义)。