wabbajack/Wabbajack.App.Wpf/LoadingLock.cs
2022-03-13 16:47:30 -06:00

87 lines
2.2 KiB
C#

using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace Wabbajack.Models;
public class LoadingLock : ReactiveObject, IDisposable
{
private readonly CompositeDisposable _disposable;
[Reactive]
public ErrorResponse? ErrorState { get; set; }
public LoadingLock()
{
_disposable = new CompositeDisposable();
this.WhenAnyValue(vm => vm.LoadLevel)
.StartWith(0)
.Subscribe(v => IsLoading = v > 0)
.DisposeWith(_disposable);
this.WhenAnyValue(vm => vm.LoadLevel)
.StartWith(0)
.Subscribe(v => IsNotLoading = v == 0)
.DisposeWith(_disposable);
}
[Reactive] public int LoadLevel { get; private set; }
[Reactive] public bool IsLoading { get; private set; }
[Reactive] public bool IsNotLoading { get; private set; }
public IObservable<bool> IsLoadingObservable => this.WhenAnyValue(ll => ll.IsLoading);
public IObservable<bool> IsNotLoadingObservable => this.WhenAnyValue(ll => ll.IsNotLoading);
public void Dispose()
{
GC.SuppressFinalize(this);
_disposable.Dispose();
}
public LockContext WithLoading()
{
RxApp.MainThreadScheduler.Schedule(0, (_, _) => { LoadLevel++;
return Disposable.Empty;
});
return new LockContext(this);
}
public class LockContext : IDisposable
{
private readonly LoadingLock _parent;
private bool _disposed;
public LockContext(LoadingLock parent)
{
_parent = parent;
_disposed = false;
}
public void Succeed()
{
_parent.ErrorState = ErrorResponse.Success;
Dispose();
}
public void Fail()
{
_parent.ErrorState = ErrorResponse.Failure;
Dispose();
}
public void Dispose()
{
if (_disposed) return;
_disposed = true;
RxApp.MainThreadScheduler.Schedule(0, (_, _) => { _parent.LoadLevel--;
return Disposable.Empty;
});
}
}
}