This commit is contained in:
2026-06-21 14:42:04 +02:00
parent 22cfb1f0a9
commit a3b4cc530d
15 changed files with 2437 additions and 403 deletions

89
Utils/AIAnalyzeUI.cs Normal file
View File

@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AnotherReplayReader.Utils
{
internal static class AIAnalyzeUI
{
public record AIAnalyzeProgressData(AIAnalyze.AIChunk Delta, DateTimeOffset? TimeStamp, bool IsExtra);
public class EmaSpeed
{
const double Tau = 5;
private DateTimeOffset lastEventTime = DateTimeOffset.UtcNow;
private DateTimeOffset timeSinceLastSpeedMeasure = DateTimeOffset.UtcNow;
private int bufferedCharactersSinceLastSpeedMeasure = 0;
private double emaSpeed = double.NaN;
public void ProcessEvent(AIAnalyzeProgressData data)
{
if (data.IsExtra)
{
return;
}
if (data.TimeStamp is { } timestamp)
{
lastEventTime = timestamp;
}
bufferedCharactersSinceLastSpeedMeasure += data.Delta.Text.Length;
}
public double GetDisplaySpeed(DateTimeOffset now)
{
// =========================
// 2. 计算 instant speed真实时间
// =========================
double instant = 0;
double dt = (now - timeSinceLastSpeedMeasure).TotalSeconds;
if (bufferedCharactersSinceLastSpeedMeasure > 0 && dt > 0.05)
{
instant = bufferedCharactersSinceLastSpeedMeasure / dt;
// reset window
bufferedCharactersSinceLastSpeedMeasure = 0;
timeSinceLastSpeedMeasure = now;
}
double alpha = 1 - Math.Exp(-dt / Tau);
if (double.IsNaN(emaSpeed))
{
emaSpeed = instant;
}
else
{
emaSpeed += alpha * (instant - emaSpeed);
}
double idle = (now - lastEventTime).TotalSeconds;
double display = emaSpeed;
if (idle > 0.5)
{
double decay = Math.Exp(-(idle - 0.5) / Tau);
display *= decay;
}
return display;
}
}
public static Action<AIAnalyze.AIChunk> BuildAIChunkReader(Action<AIAnalyzeProgressData> newContent)
{
void OnAIChunk(AIAnalyze.AIChunk c)
{
if (c.Type == AIAnalyze.AIChunkType.Json)
{
return;
}
newContent(new(Delta: c, TimeStamp: DateTimeOffset.UtcNow, IsExtra: false));
}
return OnAIChunk;
}
}
}