This commit is contained in:
2026-07-26 03:44:27 +08:00
parent 86351dbd2a
commit add675e45d
223 changed files with 1960 additions and 10735 deletions
@@ -525,6 +525,57 @@ public class HoldNote : BaseNote
bool keyUp = !keyHeld && prevTrackHeld;
prevTrackHeld = keyHeld;
// 池化泄漏兜底:不依赖 hasEnteredLine / 几何进入离开事件。
// 正常情况下 middle/start/end 由 HandleZoneEnter/Exit(几何驱动)或第 556 行的
// in-zone auto-miss 负责回收;但当几何阈值未就绪、或帧尖峰导致音符 Y 未被采样到判定区内时,
// 上述事件可能永不触发,音符会一直下落不回池,严重拖累性能(尤其 useMultiSegmentFill 使
// 中段数量随速度倍增)。此兜底在"正常判定窗口 + backstopBuffer"之后才触发,严格晚于所有正常
// 路径,因此对正常音符零行为改变——仅回收那些几何事件从未触发、否则永远泄漏的段。
{
float missRangeBackstop = (judgeConfig?.missRange ?? 0.5f) * holdWindowMultiplier;
const float backstopBuffer = 0.5f;
bool startJudgedBs = jm != null && jm.IsStartJudged(noteID);
if (segment == NoteSegment.End)
{
if (scheduledEndTime > 0f && now > scheduledEndTime + missRangeBackstop + backstopBuffer)
{
// 兜底触发时音符早已越过判定线,几何仅是漏采样。置 hasEnteredLine 让 ReturnToPool
// 的 Start 守卫(第 1519 行,拒收未入线 Start)不再阻挡回收。
hasEnteredLine = true;
// 已按住到尾部的 End 早已在第 677 行按 Perfect 自动完成并 return;
// 走到这里说明几何事件从未触发。按原 HandleZoneExit(End) 的收尾语义处理。
bool releasedBs = jm != null && jm.HasNoteReleased(noteID);
if (!startJudgedBs)
{
if (!releasedBs) HandleEnd(true); // 头段未判定 → End 记 Miss
}
else
{
HandleEnd(); // 头段已判定:按松手时间正常评估收尾
}
isJudged = true;
ScheduleReturnToPool(0.2f);
return;
}
}
else if (hitTime > 0f && now > hitTime + missRangeBackstop + backstopBuffer)
{
// 兜底触发时音符早已越过判定线,几何仅是漏采样。置 hasEnteredLine 让 ReturnToPool
// 的 Start 守卫(第 1519 行,拒收未入线 Start)不再阻挡回收。
hasEnteredLine = true;
// Start 未判定 → 走正常 Miss(与第 569 行一致);已判定的 start / middle → 静默回收
// (与第 579-581 行、第 883 行一致,绝不 StopHoldParticles 杀掉长按持续特效)。
if (segment == NoteSegment.Start && !startJudgedBs)
{
EvaluateHoldEnd(now, true);
}
isJudged = true;
ScheduleReturnToPool(0.2f);
return;
}
}
// Optimization: Early exit if the note is far from judgment line and hasn't entered yet
if (!hasEnteredLine)
{