diff --git a/Wabbajack.Common/Extensions/RxExt.cs b/Wabbajack.Common/Extensions/RxExt.cs
index 25ac87b2..0018d3a8 100644
--- a/Wabbajack.Common/Extensions/RxExt.cs
+++ b/Wabbajack.Common/Extensions/RxExt.cs
@@ -60,6 +60,32 @@ namespace Wabbajack
.Switch();
}
+ ///
+ /// Convenience operator to subscribe to the source observable, only when a second "switch" observable is on.
+ /// When the switch is on, the source will be subscribed to, and its updates passed through.
+ /// When the switch is off, the subscription to the source observable will be stopped, and no signal will be published.
+ ///
+ /// Source observable to subscribe to if on
+ /// On/Off signal of whether to subscribe to source observable
+ /// Value to fire when switching off
+ /// Observable that publishes data from source, if the switch is on.
+ public static IObservable FilterSwitch(this IObservable source, IObservable filterSwitch, T valueWhenOff)
+ {
+ return filterSwitch
+ .DistinctUntilChanged()
+ .Select(on =>
+ {
+ if (on)
+ {
+ return source;
+ }
+ else
+ {
+ return Observable.Return(valueWhenOff);
+ }
+ })
+ .Switch();
+ }
/// Inspiration:
/// http://reactivex.io/documentation/operators/debounce.html
diff --git a/Wabbajack/View Models/Compilers/MO2CompilerVM.cs b/Wabbajack/View Models/Compilers/MO2CompilerVM.cs
index 6555d608..5cc20243 100644
--- a/Wabbajack/View Models/Compilers/MO2CompilerVM.cs
+++ b/Wabbajack/View Models/Compilers/MO2CompilerVM.cs
@@ -40,13 +40,13 @@ namespace Wabbajack
{
this.ModlistLocation = new FilePickerVM()
{
- DoExistsCheck = true,
+ ExistCheckOption = FilePickerVM.ExistCheckOptions.On,
PathType = FilePickerVM.PathTypeOptions.File,
PromptTitle = "Select Modlist"
};
this.DownloadLocation = new FilePickerVM()
{
- DoExistsCheck = true,
+ ExistCheckOption = FilePickerVM.ExistCheckOptions.On,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Download Location",
};
diff --git a/Wabbajack/View Models/Compilers/ModlistSettingsEditorVM.cs b/Wabbajack/View Models/Compilers/ModlistSettingsEditorVM.cs
index 42066044..a6bc955d 100644
--- a/Wabbajack/View Models/Compilers/ModlistSettingsEditorVM.cs
+++ b/Wabbajack/View Models/Compilers/ModlistSettingsEditorVM.cs
@@ -36,7 +36,7 @@ namespace Wabbajack
this.settings = settings;
this.ImagePath = new FilePickerVM()
{
- DoExistsCheck = false,
+ ExistCheckOption = FilePickerVM.ExistCheckOptions.IfNotEmpty,
PathType = FilePickerVM.PathTypeOptions.File,
Filters =
{
@@ -46,7 +46,7 @@ namespace Wabbajack
this.ReadMeText = new FilePickerVM()
{
PathType = FilePickerVM.PathTypeOptions.File,
- DoExistsCheck = false,
+ ExistCheckOption = FilePickerVM.ExistCheckOptions.IfNotEmpty,
};
}
diff --git a/Wabbajack/View Models/Compilers/VortexCompilerVM.cs b/Wabbajack/View Models/Compilers/VortexCompilerVM.cs
index d31dd17f..44f9bff0 100644
--- a/Wabbajack/View Models/Compilers/VortexCompilerVM.cs
+++ b/Wabbajack/View Models/Compilers/VortexCompilerVM.cs
@@ -53,19 +53,19 @@ namespace Wabbajack
{
this.GameLocation = new FilePickerVM()
{
- DoExistsCheck = true,
+ ExistCheckOption = FilePickerVM.ExistCheckOptions.On,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Game Folder Location"
};
this.DownloadsLocation = new FilePickerVM()
{
- DoExistsCheck = true,
+ ExistCheckOption = FilePickerVM.ExistCheckOptions.On,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Downloads Folder"
};
this.StagingLocation = new FilePickerVM()
{
- DoExistsCheck = true,
+ ExistCheckOption = FilePickerVM.ExistCheckOptions.On,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Staging Folder"
};
diff --git a/Wabbajack/View Models/FilePickerVM.cs b/Wabbajack/View Models/FilePickerVM.cs
index c216cdb7..3e2fa7aa 100644
--- a/Wabbajack/View Models/FilePickerVM.cs
+++ b/Wabbajack/View Models/FilePickerVM.cs
@@ -23,6 +23,13 @@ namespace Wabbajack
Folder
}
+ public enum ExistCheckOptions
+ {
+ Off,
+ IfNotEmpty,
+ On
+ }
+
public object Parent { get; }
[Reactive]
@@ -38,7 +45,7 @@ namespace Wabbajack
public PathTypeOptions PathType { get; set; }
[Reactive]
- public bool DoExistsCheck { get; set; }
+ public ExistCheckOptions ExistCheckOption { get; set; }
[Reactive]
public IObservable AdditionalError { get; set; }
@@ -63,28 +70,60 @@ namespace Wabbajack
this.SetTargetPathCommand = ConstructTypicalPickerCommand();
// Check that file exists
- this._Exists = Observable.Interval(TimeSpan.FromSeconds(3))
- .FilterSwitch(
- Observable.CombineLatest(
- this.WhenAny(x => x.PathType),
- this.WhenAny(x => x.DoExistsCheck),
- resultSelector: (type, doExists) => type != PathTypeOptions.Off && doExists))
- .Unit()
- // Also do it when fields change
- .Merge(this.WhenAny(x => x.PathType).Unit())
- .Merge(this.WhenAny(x => x.DoExistsCheck).Unit())
- .CombineLatest(
- this.WhenAny(x => x.DoExistsCheck),
- this.WhenAny(x => x.PathType),
- this.WhenAny(x => x.TargetPath)
+
+ var existsCheckTuple = Observable.CombineLatest(
+ this.WhenAny(x => x.ExistCheckOption),
+ this.WhenAny(x => x.PathType),
+ this.WhenAny(x => x.TargetPath)
// Dont want to debounce the initial value, because we know it's null
.Skip(1)
- .Debounce(TimeSpan.FromMilliseconds(200)),
- resultSelector: (_, DoExists, Type, Path) => (DoExists, Type, Path))
+ .Debounce(TimeSpan.FromMilliseconds(200))
+ .StartWith(default(string)),
+ resultSelector: (ExistsOption, Type, Path) => (ExistsOption, Type, Path))
+ .Publish()
+ .RefCount();
+
+ this._Exists = Observable.Interval(TimeSpan.FromSeconds(3))
+ // Only check exists on timer if desired
+ .FilterSwitch(existsCheckTuple
+ .Select(t =>
+ {
+ // Don't do exists type if we don't know what path type we're tracking
+ if (t.Type == PathTypeOptions.Off) return false;
+ switch (t.ExistsOption)
+ {
+ case ExistCheckOptions.Off:
+ return false;
+ case ExistCheckOptions.IfNotEmpty:
+ return !string.IsNullOrWhiteSpace(t.Path);
+ case ExistCheckOptions.On:
+ return true;
+ default:
+ throw new NotImplementedException();
+ }
+ }))
+ .Unit()
+ // Also check though, when fields change
+ .Merge(this.WhenAny(x => x.PathType).Unit())
+ .Merge(this.WhenAny(x => x.ExistCheckOption).Unit())
+ .Merge(this.WhenAny(x => x.TargetPath).Unit())
+ // Signaled to check, get latest params for actual use
+ .CombineLatest(existsCheckTuple,
+ resultSelector: (_, tuple) => tuple)
// Refresh exists
.Select(t =>
{
- if (!t.DoExists) return true;
+ switch (t.ExistsOption)
+ {
+ case ExistCheckOptions.IfNotEmpty:
+ if (string.IsNullOrWhiteSpace(t.Path)) return true;
+ break;
+ case ExistCheckOptions.On:
+ break;
+ case ExistCheckOptions.Off:
+ default:
+ return true;
+ }
switch (t.Type)
{
case PathTypeOptions.Either:
diff --git a/Wabbajack/View Models/InstallerVM.cs b/Wabbajack/View Models/InstallerVM.cs
index 1f62ded0..1bc4e49a 100644
--- a/Wabbajack/View Models/InstallerVM.cs
+++ b/Wabbajack/View Models/InstallerVM.cs
@@ -99,7 +99,7 @@ namespace Wabbajack
this.Location = new FilePickerVM()
{
- DoExistsCheck = false,
+ ExistCheckOption = FilePickerVM.ExistCheckOptions.Off,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Installation Directory",
};
@@ -107,7 +107,7 @@ namespace Wabbajack
.Select(x => Utils.IsDirectoryPathValid(x));
this.DownloadLocation = new FilePickerVM()
{
- DoExistsCheck = false,
+ ExistCheckOption = FilePickerVM.ExistCheckOptions.Off,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select a location for MO2 downloads",
};