Files
GSS2Rework/GSS2.UI.Core/ViewModels/ResourcesViewModel.cs
T
amkovkov 821144a691 fix: typos
TOO many typos
2026-03-11 12:46:21 +03:00

229 lines
10 KiB
C#

using System.Collections.ObjectModel;
using Microsoft.Extensions.Logging;
using CommunityToolkit.Mvvm.ComponentModel;
using Avalonia;
using Avalonia.Threading;
using SkiaSharp;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using LiveChartsCore.Defaults;
using GSS2.Core.Hardware;
namespace GSS2.UI.Core.ViewModels;
public partial class ResourcesViewModel : ViewModelBase, IDisposable
{
private bool _disposedValue;
private readonly ComputeResourcesService _computeResourcesService;
private readonly ILogger<ResourcesViewModel> _logger;
private readonly int _intervalMs = 500;
private readonly int _chartsHistorySize = 120;
private readonly System.Timers.Timer _updateTimer;
[ObservableProperty] private Rect _bounds;
[ObservableProperty] private bool _isChartsColumnVisible;
[ObservableProperty] private bool _isBarsColumnVisible;
[ObservableProperty] private ResourceChartViewModel _cpuUsageChartViewModel;
[ObservableProperty] private ResourceChartViewModel _cpuTemperatureChartViewModel;
[ObservableProperty] private ResourceChartViewModel _memoryUsageChartViewModel;
[ObservableProperty] private ResourceCpuUsageBarsViewModel _cpuUsageBarsViewModel;
[ObservableProperty] private ResourceBarViewModel _cpuTemperatureBarViewModel;
[ObservableProperty] private ResourceBarViewModel _memoryUsageBarViewModel;
public ResourcesViewModel(
ILogger<ResourcesViewModel> logger,
ILogger<ResourceCpuUsageBarsViewModel> resourceCpuUsageBarsViewModelLogger,
ILogger<ResourceChartViewModel> resourceChartViewModelCpuUsageLogger,
ILogger<ResourceChartViewModel> resourceChartViewModelCpuTemperatureLogger,
ILogger<ResourceChartViewModel> resourceChartViewModelMemoryUsageLogger,
ILogger<ResourceBarViewModel> resourceBarViewModelCpuUsageLogger,
ILogger<ResourceBarViewModel> resourceBarViewModelCpu0UsageLogger,
ILogger<ResourceBarViewModel> resourceBarViewModelCpu1UsageLogger,
ILogger<ResourceBarViewModel> resourceBarViewModelCpu2UsageLogger,
ILogger<ResourceBarViewModel> resourceBarViewModelCpu3UsageLogger,
ILogger<ResourceBarViewModel> resourceBarViewModelCpuTemperatureLogger,
ILogger<ResourceBarViewModel> resourceBarViewModelMemoryUsageLogger,
ComputeResourcesService computeResourcesService
)
{
_logger = logger;
_logger.LogInformation("Initialization");
_computeResourcesService = computeResourcesService;
ResourceChartViewModel CreateChartViewModel(ILogger<ResourceChartViewModel> logger, string name, double minLimit, double maxLimit, double minStep)
{
return new ResourceChartViewModel(
logger: logger,
series:
[
new LineSeries<double>
{
Name = name,
Values = new ObservableCollection<double>(Enumerable.Repeat(0.0, _chartsHistorySize)),
Fill = new SolidColorPaint(SKColors.DeepSkyBlue.WithAlpha(127), 0),
GeometrySize = 0,
ShowDataLabels = false,
Stroke = new SolidColorPaint(SKColors.DeepSkyBlue, 1),
GeometryFill = new SolidColorPaint(SKColors.Transparent, 0),
GeometryStroke = new SolidColorPaint(SKColors.Transparent, 0),
IsHoverable = false,
DataPadding = new LiveChartsCore.Drawing.LvcPoint(0.1f, 0.1f)
}
],
yAxes:
[
new Axis
{
MinLimit = minLimit,
MaxLimit = maxLimit,
MinStep = minStep,
Name = name
}
],
xAxes:
[
new Axis
{
IsVisible = false,
Padding = new LiveChartsCore.Drawing.Padding(0)
}
]
);
}
ResourceBarViewModel CreateBarViewModel(ILogger<ResourceBarViewModel> logger, Func<LiveChartsCore.Kernel.ChartPoint<ObservableValue, LiveChartsCore.SkiaSharpView.Drawing.Geometries.DoughnutGeometry, LiveChartsCore.SkiaSharpView.Drawing.Geometries.LabelGeometry>, string> formatter)
{
return new ResourceBarViewModel(
logger: logger,
series:
[
new PieSeries<ObservableValue>
{
Values = new ObservableCollection<ObservableValue> { new ObservableValue(1) },
Fill = new SolidColorPaint(SKColors.DeepSkyBlue, 0),
ShowDataLabels = true,
IsHoverable = false,
HoverPushout = 0,
DataLabelsFormatter = formatter,
DataLabelsPosition = LiveChartsCore.Measure.PolarLabelsPosition.ChartCenter,
DataLabelsPaint = new SolidColorPaint(SKColors.White)
},
new PieSeries<ObservableValue>
{
Values = new ObservableCollection<ObservableValue> { new ObservableValue(1) },
Fill = new SolidColorPaint(SKColors.DeepSkyBlue.WithAlpha(64), 0),
ShowDataLabels = false,
IsHoverable = false,
HoverPushout = 0
}
]
);
}
CpuUsageChartViewModel = CreateChartViewModel(resourceChartViewModelCpuUsageLogger, "Нагрузка ЦПУ, %", 0, 100, 10);
CpuTemperatureChartViewModel = CreateChartViewModel(resourceChartViewModelCpuTemperatureLogger, "Температура ЦПУ, ℃", 0, 100, 10);
MemoryUsageChartViewModel = CreateChartViewModel(resourceChartViewModelMemoryUsageLogger, "Нагрузка ОЗУ, МБ", 0, 8000, 1000);
CpuUsageBarsViewModel = new ResourceCpuUsageBarsViewModel(
resourceCpuUsageBarsViewModelLogger,
CreateBarViewModel(resourceBarViewModelCpuUsageLogger, value => $"{value.Model?.Value?.ToString("00.00")} %"),
CreateBarViewModel(resourceBarViewModelCpu0UsageLogger, value => $"{value.Model?.Value?.ToString("00.00")} %"),
CreateBarViewModel(resourceBarViewModelCpu1UsageLogger, value => $"{value.Model?.Value?.ToString("00.00")} %"),
CreateBarViewModel(resourceBarViewModelCpu2UsageLogger, value => $"{value.Model?.Value?.ToString("00.00")} %"),
CreateBarViewModel(resourceBarViewModelCpu3UsageLogger, value => $"{value.Model?.Value?.ToString("00.00")} %")
);
CpuTemperatureBarViewModel = CreateBarViewModel(resourceBarViewModelCpuTemperatureLogger, value => $"{value.Model?.Value?.ToString("00.00")} ℃");
MemoryUsageBarViewModel = CreateBarViewModel(resourceBarViewModelMemoryUsageLogger, value => $"{value.Model?.Value?.ToString("000.00")} МБ");
Update();
_updateTimer = new System.Timers.Timer(_intervalMs);
_updateTimer.Elapsed += UpdateTimerElapsed;
_updateTimer.AutoReset = true;
_updateTimer.Start();
_logger.LogInformation("Initialized");
}
partial void OnBoundsChanged(Rect value)
{
if (value.Width < 300)
{
IsChartsColumnVisible = false;
IsBarsColumnVisible = true;
}
else if (value.Width < 400)
{
IsChartsColumnVisible = true;
IsBarsColumnVisible = false;
}
else
{
IsChartsColumnVisible = true;
IsBarsColumnVisible = true;
}
}
private void UpdateTimerElapsed(object? sender, System.Timers.ElapsedEventArgs ea) => Update();
private void Update()
{
try
{
var snapshot = _computeResourcesService.GetSnapshot();
Dispatcher.UIThread.Post(() =>
{
if (CpuTemperatureChartViewModel.YAxes.Count() == 1)
CpuTemperatureChartViewModel.YAxes.First().MaxLimit = snapshot.CpuTemperature.Critical;
if (MemoryUsageChartViewModel.YAxes.Count() == 1)
MemoryUsageChartViewModel.YAxes.First().MaxLimit = snapshot.MemoryUsage.TotalMB;
CpuUsageChartViewModel.AppendValue(Math.Round(snapshot.CpuUsage.AllUsagePercent, 2), _chartsHistorySize);
CpuTemperatureChartViewModel.AppendValue(Math.Round(snapshot.CpuTemperature.Current, 2), _chartsHistorySize);
MemoryUsageChartViewModel.AppendValue(Math.Round(snapshot.MemoryUsage.UsedMB, 2), _chartsHistorySize);
CpuUsageBarsViewModel.Cpu.UpdateValue(Math.Round(snapshot.CpuUsage.AllUsagePercent, 2), 100);
CpuUsageBarsViewModel.Cpu0.UpdateValue(Math.Round(snapshot.CpuUsage.CoreUsagePercents.Skip(0).First(), 2), 100);
CpuUsageBarsViewModel.Cpu1.UpdateValue(Math.Round(snapshot.CpuUsage.CoreUsagePercents.Skip(1).First(), 2), 100);
CpuUsageBarsViewModel.Cpu2.UpdateValue(Math.Round(snapshot.CpuUsage.CoreUsagePercents.Skip(2).First(), 2), 100);
CpuUsageBarsViewModel.Cpu3.UpdateValue(Math.Round(snapshot.CpuUsage.CoreUsagePercents.Skip(3).First(), 2), 100);
CpuTemperatureBarViewModel.UpdateValue(Math.Round(snapshot.CpuTemperature.Current, 2), snapshot.CpuTemperature.Critical);
MemoryUsageBarViewModel.UpdateValue(Math.Round(snapshot.MemoryUsage.UsedMB, 2), snapshot.MemoryUsage.TotalMB);
});
}
catch (Exception e)
{
_logger.LogWarning(e, "Exception while update");
}
}
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
try
{
_updateTimer.Stop();
_updateTimer.Dispose();
}
catch
{ }
}
_disposedValue = true;
}
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}