91 lines
2.9 KiB
C#
91 lines
2.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AnotherReplayReader.Utils
|
|
{
|
|
internal static class AIAnalyzeUI
|
|
{
|
|
public static List<StringBuilder> Debug { get; } = [];
|
|
|
|
public record AIAnalyzeProgressData(AIAnalyze.AIChunk Delta, DateTimeOffset? TimeStamp, bool IsExtra);
|
|
|
|
public class EmaSpeed
|
|
{
|
|
const double Tau = 2;
|
|
|
|
private DateTimeOffset lastEventTime = DateTimeOffset.UtcNow;
|
|
private DateTimeOffset timeSinceLastSpeedMeasure = DateTimeOffset.UtcNow;
|
|
private int bufferedCharactersSinceLastSpeedMeasure = 0;
|
|
private double emaSpeed = double.NaN;
|
|
|
|
public void ProcessEvent(int textLength, DateTimeOffset? eventTime)
|
|
{
|
|
if (eventTime is { } value)
|
|
{
|
|
lastEventTime = value;
|
|
}
|
|
bufferedCharactersSinceLastSpeedMeasure += textLength;
|
|
}
|
|
|
|
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)
|
|
{
|
|
var sb = new StringBuilder();
|
|
Debug.Add(sb);
|
|
void OnAIChunk(AIAnalyze.AIChunk c)
|
|
{
|
|
if (c.Type == AIAnalyze.AIChunkType.Json)
|
|
{
|
|
sb.AppendLine(c.Text);
|
|
return;
|
|
}
|
|
newContent(new(Delta: c, TimeStamp: DateTimeOffset.UtcNow, IsExtra: false));
|
|
}
|
|
|
|
return OnAIChunk;
|
|
}
|
|
}
|
|
}
|