improvement on gm windows, ai
This commit is contained in:
44
apps/backend/Universe/Simulation/TelemetryService.cs
Normal file
44
apps/backend/Universe/Simulation/TelemetryService.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SpaceGame.Api.Universe.Simulation;
|
||||
|
||||
public sealed class TelemetryService : IDisposable
|
||||
{
|
||||
private readonly Process _process = Process.GetCurrentProcess();
|
||||
private readonly Timer _timer;
|
||||
private double _cpuPercent;
|
||||
private DateTime _lastSampleTime;
|
||||
private TimeSpan _lastCpuTime;
|
||||
|
||||
public TelemetryService()
|
||||
{
|
||||
_process.Refresh();
|
||||
_lastSampleTime = DateTime.UtcNow;
|
||||
_lastCpuTime = _process.TotalProcessorTime;
|
||||
_timer = new Timer(Sample, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
|
||||
}
|
||||
|
||||
private void Sample(object? _)
|
||||
{
|
||||
_process.Refresh();
|
||||
var now = DateTime.UtcNow;
|
||||
var cpu = _process.TotalProcessorTime;
|
||||
var elapsed = (now - _lastSampleTime).TotalSeconds;
|
||||
var cpuUsed = (cpu - _lastCpuTime).TotalSeconds;
|
||||
Volatile.Write(ref _cpuPercent, elapsed > 0 ? cpuUsed / elapsed / Environment.ProcessorCount * 100.0 : 0);
|
||||
_lastSampleTime = now;
|
||||
_lastCpuTime = cpu;
|
||||
}
|
||||
|
||||
public double CpuPercent => Volatile.Read(ref _cpuPercent);
|
||||
public long WorkingSetBytes => _process.WorkingSet64;
|
||||
public long GcMemoryBytes => GC.GetTotalMemory(false);
|
||||
public int ThreadCount => _process.Threads.Count;
|
||||
public TimeSpan Uptime => DateTime.UtcNow - _process.StartTime.ToUniversalTime();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_timer.Dispose();
|
||||
_process.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ public sealed class WorldService(
|
||||
private readonly Queue<WorldDelta> _history = [];
|
||||
private SimulationWorld _world = new ScenarioLoader(environment.ContentRootPath, worldGenerationOptions.Value).Load();
|
||||
private long _sequence;
|
||||
private BalanceDefinition? _balanceOverride;
|
||||
|
||||
public WorldSnapshot GetSnapshot()
|
||||
{
|
||||
@@ -35,6 +36,44 @@ public sealed class WorldService(
|
||||
}
|
||||
}
|
||||
|
||||
public (int ConnectedClients, int DeltaHistoryCount) GetConnectionStats()
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
return (_subscribers.Count, _history.Count);
|
||||
}
|
||||
}
|
||||
|
||||
public BalanceDefinition GetBalance()
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
var b = _world.Balance;
|
||||
return new BalanceDefinition
|
||||
{
|
||||
SimulationSpeedMultiplier = b.SimulationSpeedMultiplier,
|
||||
YPlane = b.YPlane,
|
||||
ArrivalThreshold = b.ArrivalThreshold,
|
||||
MiningRate = b.MiningRate,
|
||||
MiningCycleSeconds = b.MiningCycleSeconds,
|
||||
TransferRate = b.TransferRate,
|
||||
DockingDuration = b.DockingDuration,
|
||||
UndockingDuration = b.UndockingDuration,
|
||||
UndockDistance = b.UndockDistance,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public BalanceDefinition UpdateBalance(BalanceDefinition balance)
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
_balanceOverride = SanitizeBalance(balance);
|
||||
ApplyBalance(_world, _balanceOverride);
|
||||
return GetBalance();
|
||||
}
|
||||
}
|
||||
|
||||
public ChannelReader<WorldDelta> Subscribe(ObserverScope scope, long afterSequence, CancellationToken cancellationToken)
|
||||
{
|
||||
var channel = Channel.CreateUnbounded<WorldDelta>(new UnboundedChannelOptions
|
||||
@@ -96,6 +135,10 @@ public sealed class WorldService(
|
||||
lock (_sync)
|
||||
{
|
||||
_world = _loader.Load();
|
||||
if (_balanceOverride is not null)
|
||||
{
|
||||
ApplyBalance(_world, _balanceOverride);
|
||||
}
|
||||
_sequence += 1;
|
||||
_history.Clear();
|
||||
|
||||
@@ -127,6 +170,39 @@ public sealed class WorldService(
|
||||
}
|
||||
}
|
||||
|
||||
private static void ApplyBalance(SimulationWorld world, BalanceDefinition balance) =>
|
||||
world.Balance = new BalanceDefinition
|
||||
{
|
||||
SimulationSpeedMultiplier = balance.SimulationSpeedMultiplier,
|
||||
YPlane = balance.YPlane,
|
||||
ArrivalThreshold = balance.ArrivalThreshold,
|
||||
MiningRate = balance.MiningRate,
|
||||
MiningCycleSeconds = balance.MiningCycleSeconds,
|
||||
TransferRate = balance.TransferRate,
|
||||
DockingDuration = balance.DockingDuration,
|
||||
UndockingDuration = balance.UndockingDuration,
|
||||
UndockDistance = balance.UndockDistance,
|
||||
};
|
||||
|
||||
private static BalanceDefinition SanitizeBalance(BalanceDefinition candidate)
|
||||
{
|
||||
static float finiteOr(float value, float fallback) =>
|
||||
float.IsFinite(value) ? value : fallback;
|
||||
|
||||
return new BalanceDefinition
|
||||
{
|
||||
SimulationSpeedMultiplier = MathF.Max(0.01f, finiteOr(candidate.SimulationSpeedMultiplier, 1f)),
|
||||
YPlane = MathF.Max(0f, finiteOr(candidate.YPlane, 0f)),
|
||||
ArrivalThreshold = MathF.Max(0.1f, finiteOr(candidate.ArrivalThreshold, 16f)),
|
||||
MiningRate = MathF.Max(0f, finiteOr(candidate.MiningRate, 10f)),
|
||||
MiningCycleSeconds = MathF.Max(0.1f, finiteOr(candidate.MiningCycleSeconds, 10f)),
|
||||
TransferRate = MathF.Max(0f, finiteOr(candidate.TransferRate, 56f)),
|
||||
DockingDuration = MathF.Max(0.1f, finiteOr(candidate.DockingDuration, 1.2f)),
|
||||
UndockingDuration = MathF.Max(0.1f, finiteOr(candidate.UndockingDuration, 1.2f)),
|
||||
UndockDistance = MathF.Max(0f, finiteOr(candidate.UndockDistance, 42f)),
|
||||
};
|
||||
}
|
||||
|
||||
private static bool HasMeaningfulDelta(WorldDelta delta) =>
|
||||
delta.RequiresSnapshotRefresh
|
||||
|| delta.Events.Count > 0
|
||||
|
||||
Reference in New Issue
Block a user