Wireup some remaining buttons and CPU displays

This commit is contained in:
Timothy Baldridge 2022-01-01 09:18:08 -07:00
parent 3e8fbf0540
commit d52ede4611
10 changed files with 97 additions and 43 deletions

View File

@ -1,8 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Subjects; using System.Reactive.Subjects;
using System.Timers; using System.Timers;
using DynamicData;
using DynamicData.Kernel;
using Wabbajack.RateLimiter; using Wabbajack.RateLimiter;
namespace Wabbajack.Models; namespace Wabbajack.Models;
@ -17,14 +21,31 @@ public class ResourceMonitor : IDisposable
public IObservable<(string Name, long Throughput)[]> Updates => _updates; public IObservable<(string Name, long Throughput)[]> Updates => _updates;
private readonly SourceCache<CPUDisplayVM, ulong> _tasks = new(x => x.ID);
public readonly ReadOnlyObservableCollection<CPUDisplayVM> _tasksFiltered;
private readonly CompositeDisposable _compositeDisposable;
public ReadOnlyObservableCollection<CPUDisplayVM> Tasks => _tasksFiltered;
public ResourceMonitor(IEnumerable<IResource> resources) public ResourceMonitor(IEnumerable<IResource> resources)
{ {
_compositeDisposable = new CompositeDisposable();
_resources = resources.ToArray(); _resources = resources.ToArray();
_timer = new Timer(); _timer = new Timer();
_timer.Interval = 1000; _timer.Interval = 1000;
_timer.Elapsed += Elapsed; _timer.Elapsed += Elapsed;
_timer.Enabled = true; _timer.Enabled = true;
_timer.DisposeWith(_compositeDisposable);
_prev = _resources.Select(x => (x.Name, (long)0)).ToArray(); _prev = _resources.Select(x => (x.Name, (long)0)).ToArray();
_tasks.Connect()
.Bind(out _tasksFiltered)
.Subscribe()
.DisposeWith(_compositeDisposable);
} }
private void Elapsed(object? sender, ElapsedEventArgs e) private void Elapsed(object? sender, ElapsedEventArgs e)
@ -35,10 +56,47 @@ public class ResourceMonitor : IDisposable
.ToArray(); .ToArray();
_prev = current; _prev = current;
_updates.OnNext(diff); _updates.OnNext(diff);
_tasks.Edit(l =>
{
var used = new HashSet<ulong>();
foreach (var resource in _resources)
{
foreach (var job in resource.Jobs)
{
used.Add(job.ID);
var tsk = l.Lookup(job.ID);
// Update
if (tsk != Optional<CPUDisplayVM>.None)
{
var t = tsk.Value;
t.Msg = job.Description;
t.ProgressPercent = Percent.FactoryPutInRange(job.Current, (long)job.Size);
}
// Create
else
{
var vm = new CPUDisplayVM
{
ID = job.ID,
StartTime = DateTime.Now,
Msg = job.Description,
ProgressPercent = Percent.FactoryPutInRange(job.Current, (long) job.Size)
};
l.AddOrUpdate(vm);
}
}
}
// Delete
foreach (var itm in l.Items.Where(v => !used.Contains(v.ID)))
l.Remove(itm);
});
} }
public void Dispose() public void Dispose()
{ {
_timer?.Dispose(); _compositeDisposable.Dispose();
} }
} }

View File

@ -8,7 +8,7 @@ namespace Wabbajack
public class CPUDisplayVM : ViewModel public class CPUDisplayVM : ViewModel
{ {
[Reactive] [Reactive]
public int ID { get; set; } public ulong ID { get; set; }
[Reactive] [Reactive]
public DateTime StartTime { get; set; } public DateTime StartTime { get; set; }
[Reactive] [Reactive]
@ -21,26 +21,5 @@ namespace Wabbajack
public CPUDisplayVM() public CPUDisplayVM()
{ {
} }
public CPUDisplayVM(IJob cpu)
{
AbsorbStatus(cpu);
}
public void AbsorbStatus(IJob cpu)
{
/* TODO
bool starting = cpu.IsWorking && !IsWorking;
if (starting)
{
StartTime = DateTime.Now;
}
ID = cpu.;
Msg = cpu.Msg;
ProgressPercent = cpu.ProgressPercent;
IsWorking = cpu.IsWorking;
*/
}
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.ObjectModel;
using System.Reactive; using System.Reactive;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -36,7 +37,7 @@ namespace Wabbajack
private readonly ObservableAsPropertyHelper<Percent> _percentCompleted; private readonly ObservableAsPropertyHelper<Percent> _percentCompleted;
public Percent PercentCompleted => _percentCompleted.Value; public Percent PercentCompleted => _percentCompleted.Value;
public ObservableCollectionExtended<CPUDisplayVM> StatusList { get; } = new ObservableCollectionExtended<CPUDisplayVM>(); public ReadOnlyObservableCollection<CPUDisplayVM> StatusList { get; }
public ObservableCollectionExtended<IStatusMessage> Log => MWVM.Log; public ObservableCollectionExtended<IStatusMessage> Log => MWVM.Log;

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.ObjectModel;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Reactive.Linq; using System.Reactive.Linq;
@ -32,6 +33,7 @@ using Wabbajack.View_Models;
using Wabbajack.Paths.IO; using Wabbajack.Paths.IO;
using Wabbajack.Services.OSIntegrated; using Wabbajack.Services.OSIntegrated;
using Wabbajack.Util; using Wabbajack.Util;
using Configuration = Wabbajack.Networking.WabbajackClientApi.Configuration;
using Consts = Wabbajack.Consts; using Consts = Wabbajack.Consts;
using KnownFolders = Wabbajack.Paths.IO.KnownFolders; using KnownFolders = Wabbajack.Paths.IO.KnownFolders;
@ -50,7 +52,7 @@ public enum InstallState
Failure Failure
} }
public class InstallerVM : BackNavigatingVM, IBackNavigatingVM public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM
{ {
private const string LastLoadedModlist = "last-loaded-modlist"; private const string LastLoadedModlist = "last-loaded-modlist";
private const string InstallSettingsPrefix = "install-settings-"; private const string InstallSettingsPrefix = "install-settings-";
@ -109,6 +111,9 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM
private readonly SystemParametersConstructor _parametersConstructor; private readonly SystemParametersConstructor _parametersConstructor;
private readonly IGameLocator _gameLocator; private readonly IGameLocator _gameLocator;
private readonly LoggerProvider _loggerProvider; private readonly LoggerProvider _loggerProvider;
private readonly ResourceMonitor _resourceMonitor;
private readonly Services.OSIntegrated.Configuration _configuration;
public ReadOnlyObservableCollection<CPUDisplayVM> StatusList => _resourceMonitor.Tasks;
[Reactive] [Reactive]
public bool Installing { get; set; } public bool Installing { get; set; }
@ -130,15 +135,18 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM
public ReactiveCommand<Unit, Unit> BackCommand { get; } public ReactiveCommand<Unit, Unit> BackCommand { get; }
public InstallerVM(ILogger<InstallerVM> logger, DTOSerializer dtos, SettingsManager settingsManager, IServiceProvider serviceProvider, public InstallerVM(ILogger<InstallerVM> logger, DTOSerializer dtos, SettingsManager settingsManager, IServiceProvider serviceProvider,
SystemParametersConstructor parametersConstructor, IGameLocator gameLocator, LoggerProvider loggerProvider) : base(logger) SystemParametersConstructor parametersConstructor, IGameLocator gameLocator, LoggerProvider loggerProvider, ResourceMonitor resourceMonitor,
Wabbajack.Services.OSIntegrated.Configuration configuration) : base(logger)
{ {
_logger = logger; _logger = logger;
_configuration = configuration;
LoggerProvider = loggerProvider; LoggerProvider = loggerProvider;
_settingsManager = settingsManager; _settingsManager = settingsManager;
_dtos = dtos; _dtos = dtos;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_parametersConstructor = parametersConstructor; _parametersConstructor = parametersConstructor;
_gameLocator = gameLocator; _gameLocator = gameLocator;
_resourceMonitor = resourceMonitor;
Installer = new MO2InstallerVM(this); Installer = new MO2InstallerVM(this);
@ -164,6 +172,16 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM
}; };
ModListLocation.Filters.Add(new CommonFileDialogFilter("Wabbajack Modlist", "*.wabbajack")); ModListLocation.Filters.Add(new CommonFileDialogFilter("Wabbajack Modlist", "*.wabbajack"));
OpenLogsCommand = ReactiveCommand.Create(() =>
{
UIUtils.OpenFolder(_configuration.LogLocation);
});
GoToInstallCommand = ReactiveCommand.Create(() =>
{
UIUtils.OpenFolder(Installer.Location.TargetPath);
});
MessageBus.Current.Listen<LoadModlistForInstalling>() MessageBus.Current.Listen<LoadModlistForInstalling>()
.Subscribe(msg => LoadModlist(msg.Path, msg.Metadata).FireAndForget()) .Subscribe(msg => LoadModlist(msg.Path, msg.Metadata).FireAndForget())
.DisposeWith(CompositeDisposable); .DisposeWith(CompositeDisposable);

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -10,8 +11,6 @@ namespace Wabbajack
{ {
public interface ICpuStatusVM : IReactiveObject public interface ICpuStatusVM : IReactiveObject
{ {
ObservableCollectionExtended<CPUDisplayVM> StatusList { get; } ReadOnlyObservableCollection<CPUDisplayVM> StatusList { get; }
MainWindowVM MWVM { get; }
(int CurrentCPUs, int DesiredCPUs) CurrentCpuCount { get; }
} }
} }

View File

@ -28,16 +28,13 @@ namespace Wabbajack
InitializeComponent(); InitializeComponent();
this.WhenActivated(dispose => this.WhenActivated(dispose =>
{ {
this.WhenAny(x => x.ViewModel.Completed) this.WhenAny(x => x.ViewModel.InstallState)
.Select(x => x?.Failed ?? false) .Select(x => x == InstallState.Failure)
.BindToStrict(this, x => x.AttentionBorder.Failure) .BindToStrict(this, x => x.AttentionBorder.Failure)
.DisposeWith(dispose); .DisposeWith(dispose);
this.WhenAny(x => x.ViewModel.Completed) this.WhenAny(x => x.ViewModel.InstallState)
.Select(x => x?.Failed ?? false) .Select(x => x == InstallState.Failure)
.Select(failed => .Select(failed => $"Installation {(failed ? "Failed" : "Complete")}")
{
return $"Installation {(failed ? "Failed" : "Complete")}";
})
.BindToStrict(this, x => x.TitleText.Text) .BindToStrict(this, x => x.TitleText.Text)
.DisposeWith(dispose); .DisposeWith(dispose);
this.WhenAny(x => x.ViewModel.BackCommand) this.WhenAny(x => x.ViewModel.BackCommand)

View File

@ -35,9 +35,6 @@ namespace Wabbajack
.BindToStrict(this, view => view.InstallComplete.Visibility) .BindToStrict(this, view => view.InstallComplete.Visibility)
.DisposeWith(disposables); .DisposeWith(disposables);
//ViewModel.WhenAnyValue(vm => vm.ModList.Name)
// .BindToStrict(this, view => view.Name)
ViewModel.WhenAnyValue(vm => vm.BackCommand) ViewModel.WhenAnyValue(vm => vm.BackCommand)
.BindToStrict(this, view => view.BackButton.Command) .BindToStrict(this, view => view.BackButton.Command)
.DisposeWith(disposables); .DisposeWith(disposables);

View File

@ -5,7 +5,9 @@ namespace Wabbajack.RateLimiter;
public interface IJob public interface IJob
{ {
public ulong ID { get; }
public long? Size { get; set; } public long? Size { get; set; }
public long Current { get; } public long Current { get; }
public string Description { get; }
public ValueTask Report(int processedSize, CancellationToken token); public ValueTask Report(int processedSize, CancellationToken token);
} }

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,6 +10,7 @@ public interface IResource
string Name { get; } string Name { get; }
int MaxTasks { get; set; } int MaxTasks { get; set; }
long MaxThroughput { get; set; } long MaxThroughput { get; set; }
IEnumerable<IJob> Jobs { get; }
} }
public interface IResource<T> : IResource public interface IResource<T> : IResource

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Runtime.Versioning; using System.Runtime.Versioning;
@ -13,10 +14,10 @@ public class Resource<T> : IResource<T>
{ {
private Channel<PendingReport> _channel; private Channel<PendingReport> _channel;
private SemaphoreSlim _semaphore; private SemaphoreSlim _semaphore;
private ConcurrentDictionary<ulong, Job<T>> _tasks; private readonly ConcurrentDictionary<ulong, Job<T>> _tasks;
private ulong _nextId; private ulong _nextId;
private long _totalUsed; private long _totalUsed;
public IEnumerable<IJob> Jobs => _tasks.Values;
public Resource(string? humanName = null, int? maxTasks = null, long maxThroughput = long.MaxValue) public Resource(string? humanName = null, int? maxTasks = null, long maxThroughput = long.MaxValue)
{ {