Fixes for progress bars starting at 100%

This commit is contained in:
Justin Swanson
2019-12-17 21:10:38 -06:00
parent 4fc9f58d88
commit e0a91036d0
6 changed files with 58 additions and 51 deletions

View File

@ -44,6 +44,15 @@ namespace Wabbajack
.Unit(); .Unit();
} }
public static IObservable<Unit> EndingExecution(this IReactiveCommand cmd)
{
return cmd.IsExecuting
.DistinctUntilChanged()
.Pairwise()
.Where(x => x.Previous && !x.Current)
.Unit();
}
/// These snippets were provided by RolandPheasant (author of DynamicData) /// These snippets were provided by RolandPheasant (author of DynamicData)
/// They'll be going into the official library at some point, but are here for now. /// They'll be going into the official library at some point, but are here for now.
#region Dynamic Data EnsureUniqueChanges #region Dynamic Data EnsureUniqueChanges

View File

@ -52,14 +52,11 @@ namespace Wabbajack
private readonly ObservableAsPropertyHelper<IUserIntervention> _ActiveGlobalUserIntervention; private readonly ObservableAsPropertyHelper<IUserIntervention> _ActiveGlobalUserIntervention;
public IUserIntervention ActiveGlobalUserIntervention => _ActiveGlobalUserIntervention.Value; public IUserIntervention ActiveGlobalUserIntervention => _ActiveGlobalUserIntervention.Value;
private readonly ObservableAsPropertyHelper<bool> _Completed;
public bool Completed => _Completed.Value;
/// <summary>
/// Tracks whether compilation has begun
/// </summary>
[Reactive] [Reactive]
public bool CompilationMode { get; set; } public bool StartedCompilation { get; set; }
[Reactive]
public bool Completed { get; set; }
public CompilerVM(MainWindowVM mainWindowVM) public CompilerVM(MainWindowVM mainWindowVM)
{ {
@ -137,7 +134,8 @@ namespace Wabbajack
execute: () => execute: () =>
{ {
mainWindowVM.ActivePane = mainWindowVM.ModeSelectionVM; mainWindowVM.ActivePane = mainWindowVM.ModeSelectionVM;
CompilationMode = false; StartedCompilation = false;
Completed = false;
}, },
canExecute: this.WhenAny(x => x.Compiling) canExecute: this.WhenAny(x => x.Compiling)
.Select(x => !x)); .Select(x => !x));
@ -166,15 +164,6 @@ namespace Wabbajack
.Subscribe() .Subscribe()
.DisposeWith(CompositeDisposable); .DisposeWith(CompositeDisposable);
_Completed = Observable.CombineLatest(
this.WhenAny(x => x.Compiling),
this.WhenAny(x => x.CompilationMode),
resultSelector: (installing, installingMode) =>
{
return installingMode && !installing;
})
.ToProperty(this, nameof(Completed));
_percentCompleted = this.WhenAny(x => x.Compiler.ActiveCompilation) _percentCompleted = this.WhenAny(x => x.Compiler.ActiveCompilation)
.StartWith(default(ACompiler)) .StartWith(default(ACompiler))
.CombineLatest( .CombineLatest(
@ -185,19 +174,29 @@ namespace Wabbajack
{ {
return Observable.Return<float>(completed ? 1f : 0f); return Observable.Return<float>(completed ? 1f : 0f);
} }
return compiler.PercentCompleted; return compiler.PercentCompleted.StartWith(0);
}) })
.Switch() .Switch()
.Debounce(TimeSpan.FromMilliseconds(25)) .Debounce(TimeSpan.FromMilliseconds(25))
.ToProperty(this, nameof(PercentCompleted)); .ToProperty(this, nameof(PercentCompleted));
// When sub compiler begins an install, mark state variable // When sub compiler begins a compile, mark state variable
this.WhenAny(x => x.Compiler.BeginCommand) this.WhenAny(x => x.Compiler.BeginCommand)
.Select(x => x?.StartingExecution() ?? Observable.Empty<Unit>()) .Select(x => x?.StartingExecution() ?? Observable.Empty<Unit>())
.Switch() .Switch()
.Subscribe(_ => .Subscribe(_ =>
{ {
CompilationMode = true; StartedCompilation = true;
})
.DisposeWith(CompositeDisposable);
// When sub compiler finishes a compile, mark state variable
this.WhenAny(x => x.Compiler.BeginCommand)
.Select(x => x?.EndingExecution() ?? Observable.Empty<Unit>())
.Switch()
.Subscribe(_ =>
{
Completed = true;
}) })
.DisposeWith(CompositeDisposable); .DisposeWith(CompositeDisposable);

View File

@ -46,11 +46,11 @@ namespace Wabbajack
private readonly ObservableAsPropertyHelper<bool> _installing; private readonly ObservableAsPropertyHelper<bool> _installing;
public bool Installing => _installing.Value; public bool Installing => _installing.Value;
/// <summary>
/// Tracks whether installation has begun
/// </summary>
[Reactive] [Reactive]
public bool InstallingMode { get; set; } public bool StartedInstallation { get; set; }
[Reactive]
public bool Completed { get; set; }
private readonly ObservableAsPropertyHelper<ImageSource> _image; private readonly ObservableAsPropertyHelper<ImageSource> _image;
public ImageSource Image => _image.Value; public ImageSource Image => _image.Value;
@ -82,9 +82,6 @@ namespace Wabbajack
private readonly ObservableAsPropertyHelper<IUserIntervention> _ActiveGlobalUserIntervention; private readonly ObservableAsPropertyHelper<IUserIntervention> _ActiveGlobalUserIntervention;
public IUserIntervention ActiveGlobalUserIntervention => _ActiveGlobalUserIntervention.Value; public IUserIntervention ActiveGlobalUserIntervention => _ActiveGlobalUserIntervention.Value;
private readonly ObservableAsPropertyHelper<bool> _Completed;
public bool Completed => _Completed.Value;
// Command properties // Command properties
public IReactiveCommand ShowReportCommand { get; } public IReactiveCommand ShowReportCommand { get; }
public IReactiveCommand OpenReadmeCommand { get; } public IReactiveCommand OpenReadmeCommand { get; }
@ -163,7 +160,7 @@ namespace Wabbajack
.Select(modList => modList?.ReportHTML) .Select(modList => modList?.ReportHTML)
.ToProperty(this, nameof(HTMLReport)); .ToProperty(this, nameof(HTMLReport));
_installing = this.WhenAny(x => x.Installer.ActiveInstallation) _installing = this.WhenAny(x => x.Installer.ActiveInstallation)
.Select(compilation => compilation != null) .Select(i => i != null)
.ObserveOnGuiThread() .ObserveOnGuiThread()
.ToProperty(this, nameof(Installing)); .ToProperty(this, nameof(Installing));
_TargetManager = this.WhenAny(x => x.ModList) _TargetManager = this.WhenAny(x => x.ModList)
@ -182,21 +179,13 @@ namespace Wabbajack
BackCommand = ReactiveCommand.Create( BackCommand = ReactiveCommand.Create(
execute: () => execute: () =>
{ {
InstallingMode = false; StartedInstallation = false;
Completed = false;
mainWindowVM.ActivePane = mainWindowVM.ModeSelectionVM; mainWindowVM.ActivePane = mainWindowVM.ModeSelectionVM;
}, },
canExecute: this.WhenAny(x => x.Installing) canExecute: this.WhenAny(x => x.Installing)
.Select(x => !x)); .Select(x => !x));
_Completed = Observable.CombineLatest(
this.WhenAny(x => x.Installing),
this.WhenAny(x => x.InstallingMode),
resultSelector: (installing, installingMode) =>
{
return installingMode && !installing;
})
.ToProperty(this, nameof(Completed));
_percentCompleted = this.WhenAny(x => x.Installer.ActiveInstallation) _percentCompleted = this.WhenAny(x => x.Installer.ActiveInstallation)
.StartWith(default(AInstaller)) .StartWith(default(AInstaller))
.CombineLatest( .CombineLatest(
@ -207,7 +196,7 @@ namespace Wabbajack
{ {
return Observable.Return<float>(completed ? 1f : 0f); return Observable.Return<float>(completed ? 1f : 0f);
} }
return installer.PercentCompleted; return installer.PercentCompleted.StartWith(0f);
}) })
.Switch() .Switch()
.Debounce(TimeSpan.FromMilliseconds(25)) .Debounce(TimeSpan.FromMilliseconds(25))
@ -285,11 +274,11 @@ namespace Wabbajack
_progressTitle = Observable.CombineLatest( _progressTitle = Observable.CombineLatest(
this.WhenAny(x => x.Installing), this.WhenAny(x => x.Installing),
this.WhenAny(x => x.InstallingMode), this.WhenAny(x => x.StartedInstallation),
resultSelector: (installing, mode) => resultSelector: (installing, started) =>
{ {
if (!installing) return "Configuring"; if (!installing) return "Configuring";
return mode ? "Installing" : "Installed"; return started ? "Installing" : "Installed";
}) })
.ToProperty(this, nameof(ProgressTitle)); .ToProperty(this, nameof(ProgressTitle));
@ -323,7 +312,17 @@ namespace Wabbajack
.Switch() .Switch()
.Subscribe(_ => .Subscribe(_ =>
{ {
InstallingMode = true; StartedInstallation = true;
})
.DisposeWith(CompositeDisposable);
// When sub installer ends an install, mark state variable
this.WhenAny(x => x.Installer.BeginCommand)
.Select(x => x?.EndingExecution() ?? Observable.Empty<Unit>())
.Switch()
.Subscribe(_ =>
{
Completed = true;
}) })
.DisposeWith(CompositeDisposable); .DisposeWith(CompositeDisposable);

View File

@ -65,7 +65,7 @@
x:Name="LargeProgressBar" x:Name="LargeProgressBar"
Grid.Column="0" Grid.Column="0"
Grid.ColumnSpan="4" Grid.ColumnSpan="4"
Background="#88121212" Background="#AA121212"
BorderThickness="0" BorderThickness="0"
Maximum="1" Maximum="1"
Opacity="{Binding ProgressOpacityPercent, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" Opacity="{Binding ProgressOpacityPercent, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"

View File

@ -174,7 +174,7 @@
Margin="35,0,35,0" Margin="35,0,35,0"
VerticalAlignment="Center" VerticalAlignment="Center"
ClipToBounds="False" ClipToBounds="False"
Visibility="{Binding CompilationMode, Converter={StaticResource bool2VisibilityConverter}, ConverterParameter=False}"> Visibility="{Binding StartedCompilation, Converter={StaticResource bool2VisibilityConverter}, ConverterParameter=False}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
@ -240,7 +240,7 @@
Grid.Column="0" Grid.Column="0"
Grid.ColumnSpan="5" Grid.ColumnSpan="5"
Margin="5" Margin="5"
Visibility="{Binding CompilationMode, Converter={StaticResource bool2VisibilityConverter}, FallbackValue=Hidden}"> Visibility="{Binding StartedCompilation, Converter={StaticResource bool2VisibilityConverter}, FallbackValue=Hidden}">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" /> <ColumnDefinition Width="4*" />
<ColumnDefinition Width="5" /> <ColumnDefinition Width="5" />

View File

@ -206,7 +206,7 @@
ToolTip="Pause Installation" ToolTip="Pause Installation"
Margin="0,0,0,5" Margin="0,0,0,5"
Width="50" Width="50"
Visibility="{Binding InstallingMode, Converter={StaticResource bool2VisibilityConverter}}"> Visibility="{Binding StartedInstallation, Converter={StaticResource bool2VisibilityConverter}}">
<icon:PackIconMaterial <icon:PackIconMaterial
Kind="Pause" /> Kind="Pause" />
</Button> </Button>
@ -214,7 +214,7 @@
ToolTip="Stop Installation" ToolTip="Stop Installation"
Margin="0,0,0,5" Margin="0,0,0,5"
Width="50" Width="50"
Visibility="{Binding InstallingMode, Converter={StaticResource bool2VisibilityConverter}}" > Visibility="{Binding StartedInstallation, Converter={StaticResource bool2VisibilityConverter}}" >
<icon:PackIconFontAwesome <icon:PackIconFontAwesome
Width="25" Width="25"
Height="25" Height="25"
@ -240,7 +240,7 @@
Grid.Row="2" Grid.Row="2"
Margin="5,0,5,5" Margin="5,0,5,5"
ClipToBounds="True" ClipToBounds="True"
Visibility="{Binding InstallingMode, Converter={StaticResource bool2VisibilityConverter}, ConverterParameter=False}"> Visibility="{Binding StartedInstallation, Converter={StaticResource bool2VisibilityConverter}, ConverterParameter=False}">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="4" /> <ColumnDefinition Width="4" />
@ -339,7 +339,7 @@
Margin="5" Margin="5"
VerticalAlignment="Center" VerticalAlignment="Center"
Background="Transparent" Background="Transparent"
Visibility="{Binding InstallingMode, Converter={StaticResource bool2VisibilityConverter}, ConverterParameter=False}"> Visibility="{Binding StartedInstallation, Converter={StaticResource bool2VisibilityConverter}, ConverterParameter=False}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
@ -394,7 +394,7 @@
<Grid <Grid
Grid.Row="2" Grid.Row="2"
Margin="5,0,5,5" Margin="5,0,5,5"
Visibility="{Binding InstallingMode, Converter={StaticResource bool2VisibilityConverter}, FallbackValue=Hidden}"> Visibility="{Binding StartedInstallation, Converter={StaticResource bool2VisibilityConverter}, FallbackValue=Hidden}">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" /> <ColumnDefinition Width="4*" />
<ColumnDefinition Width="5" /> <ColumnDefinition Width="5" />