///|
/// latency_chart:把 8 条典型链路跑一遍,输出一张可以直接贴进文档的表格。
///
/// moon run examples/latency_chart
///
/// 关心的不是「能不能连上」,而是:延迟变差时回滚次数怎么涨、两端会不会分叉。
const FRAMES : Int32 = 300
///|
struct Case {
name : String
spec : @scene.LinkSpec
}
///|
fn main {
let cases : Array[Case] = [
{ name: "局域网 16ms", spec: @scene.LinkSpec::new(0, 0, 0, 0), },
{ name: "同城 33ms", spec: @scene.LinkSpec::new(2, 0, 0, 0), },
{ name: "跨城 100ms", spec: @scene.LinkSpec::new(6, 0, 0, 0), },
{ name: "跨城 100ms ±50ms", spec: @scene.LinkSpec::new(6, 3, 0, 0), },
{
name: "跨城 100ms +10% 乱序",
spec: @scene.LinkSpec::new(6, 3, 0, 10),
},
{ name: "跨城 100ms +5% 丢包", spec: @scene.LinkSpec::new(6, 3, 5, 0), },
{ name: "跨洋 200ms ±50ms", spec: @scene.LinkSpec::new(12, 3, 0, 0), },
{
name: "跨洋 200ms ±50ms +25% 乱序",
spec: @scene.LinkSpec::new(12, 3, 0, 25),
},
]
println("")
println(
"| 场景 | 延迟 | 抖动 | 丢包 | 乱序 | 回滚次数 | 重放帧数 | 最大深度 | 确认帧 | 分叉帧 | 一致 |",
)
println("| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |")
let mut all_synced = true
for c in cases {
let stats = @scene.run_link(c.spec, FRAMES, 0)
if !stats.synced {
all_synced = false
}
println(row(c, stats))
}
println("")
println(
"说明:延迟 / 抖动单位是逻辑帧(60fps → 1 帧 ≈ 16.7ms),丢包 / 乱序是百分比。",
)
println(
"「分叉帧」显示首个「两端都已确认但状态不同」的帧号,`-` 表示没有发现分叉。",
)
println("")
println(
if all_synced {
"结论:8 条链路全部收敛。回滚次数恒等于帧数(每帧都会收到一帧更早的输入)," +
"真正随延迟增长的是「重放帧数」与「最大深度」——那就是 CPU 成本。"
} else {
"警告:存在未收敛的链路,说明同步逻辑有 bug。"
},
)
}
///|
fn row(c : Case, stats : @scene.LinkStats) -> String {
let divergence = if stats.first_divergence == 0 {
"-"
} else {
stats.first_divergence.to_string()
}
let ok = if stats.synced { "yes" } else { "NO" }
"| " +
c.name +
" | " +
c.spec.delay.to_string() +
" | " +
c.spec.jitter.to_string() +
" | " +
c.spec.loss.to_string() +
"% | " +
c.spec.reorder.to_string() +
"% | " +
stats.p0_rollbacks.to_string() +
" | " +
stats.replayed_p0.to_string() +
" | " +
stats.max_depth.to_string() +
" | " +
stats.p0_confirmed.to_string() +
"/" +
stats.p1_confirmed.to_string() +
" | " +
divergence +
" | " +
ok +
" |"
}