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.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Subjects;
using System.Timers;
using DynamicData;
using DynamicData.Kernel;
using Wabbajack.RateLimiter;
namespace Wabbajack.Models;
@ -17,14 +21,31 @@ public class ResourceMonitor : IDisposable
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)
{
_compositeDisposable = new CompositeDisposable();
_resources = resources.ToArray();
_timer = new Timer();
_timer.Interval = 1000;
_timer.Elapsed += Elapsed;
_timer.Enabled = true;
_timer.DisposeWith(_compositeDisposable);
_prev = _resources.Select(x => (x.Name, (long)0)).ToArray();
_tasks.Connect()
.Bind(out _tasksFiltered)
.Subscribe()
.DisposeWith(_compositeDisposable);
}
private void Elapsed(object? sender, ElapsedEventArgs e)
@ -35,10 +56,47 @@ public class ResourceMonitor : IDisposable
.ToArray();
_prev = current;
_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()
{
_timer?.Dispose();
_compositeDisposable.Dispose();
}
}

View File

@ -8,7 +8,7 @@ namespace Wabbajack
public class CPUDisplayVM : ViewModel
{
[Reactive]
public int ID { get; set; }
public ulong ID { get; set; }
[Reactive]
public DateTime StartTime { get; set; }
[Reactive]
@ -21,26 +21,5 @@ namespace Wabbajack
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.Collections.ObjectModel;
using System.Reactive;
using System.Windows.Media.Imaging;
using Microsoft.Extensions.Logging;
@ -36,7 +37,7 @@ namespace Wabbajack
private readonly ObservableAsPropertyHelper<Percent> _percentCompleted;
public Percent PercentCompleted => _percentCompleted.Value;
public ObservableCollectionExtended<CPUDisplayVM> StatusList { get; } = new ObservableCollectionExtended<CPUDisplayVM>();
public ReadOnlyObservableCollection<CPUDisplayVM> StatusList { get; }
public ObservableCollectionExtended<IStatusMessage> Log => MWVM.Log;

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.ObjectModel;
using ReactiveUI;
using System.Reactive.Disposables;
using System.Reactive.Linq;
@ -32,6 +33,7 @@ using Wabbajack.View_Models;
using Wabbajack.Paths.IO;
using Wabbajack.Services.OSIntegrated;
using Wabbajack.Util;
using Configuration = Wabbajack.Networking.WabbajackClientApi.Configuration;
using Consts = Wabbajack.Consts;
using KnownFolders = Wabbajack.Paths.IO.KnownFolders;
@ -50,7 +52,7 @@ public enum InstallState
Failure
}
public class InstallerVM : BackNavigatingVM, IBackNavigatingVM
public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM
{
private const string LastLoadedModlist = "last-loaded-modlist";
private const string InstallSettingsPrefix = "install-settings-";
@ -109,6 +111,9 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM
private readonly SystemParametersConstructor _parametersConstructor;
private readonly IGameLocator _gameLocator;
private readonly LoggerProvider _loggerProvider;
private readonly ResourceMonitor _resourceMonitor;
private readonly Services.OSIntegrated.Configuration _configuration;
public ReadOnlyObservableCollection<CPUDisplayVM> StatusList => _resourceMonitor.Tasks;
[Reactive]
public bool Installing { get; set; }
@ -130,16 +135,19 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM
public ReactiveCommand<Unit, Unit> BackCommand { get; }
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;
_configuration = configuration;
LoggerProvider = loggerProvider;
_settingsManager = settingsManager;
_dtos = dtos;
_serviceProvider = serviceProvider;
_parametersConstructor = parametersConstructor;
_gameLocator = gameLocator;
_resourceMonitor = resourceMonitor;
Installer = new MO2InstallerVM(this);
BackCommand = ReactiveCommand.Create(() => NavigateToGlobal.Send(NavigateToGlobal.ScreenType.ModeSelectionView));
@ -164,6 +172,16 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM
};
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>()
.Subscribe(msg => LoadModlist(msg.Path, msg.Metadata).FireAndForget())
.DisposeWith(CompositeDisposable);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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