Files
NebulaLauncher/Nebula.Launcher/Configurations/ComplexConVarBinder.cs

87 lines
2.3 KiB
C#
Raw Normal View History

2025-08-07 22:34:25 +03:00
using System;
2025-08-06 21:29:00 +03:00
using System.ComponentModel;
2025-08-07 22:34:25 +03:00
using System.Threading;
using System.Threading.Tasks;
using Nebula.Shared.Configurations;
2025-08-06 21:29:00 +03:00
2025-08-07 22:34:25 +03:00
namespace Nebula.Launcher.Configurations;
2025-08-06 21:29:00 +03:00
public abstract class ComplexConVarBinder<T> : INotifyPropertyChanged, INotifyPropertyChanging
{
private readonly ConVarObserver<T> _baseConVar;
private readonly Lock _lock = new();
private readonly SemaphoreSlim _valueChangeSemaphore = new(1, 1);
public T? Value
{
get
{
lock (_lock)
{
return _baseConVar.Value;
}
}
set
{
_ = SetValueAsync(value);
}
}
2025-08-07 22:34:25 +03:00
public bool HasValue
{
get
{
lock (_lock)
{
return _baseConVar.HasValue;
}
}
}
2025-08-06 21:29:00 +03:00
protected ComplexConVarBinder(ConVarObserver<T> baseConVar)
{
_baseConVar = baseConVar ?? throw new ArgumentNullException(nameof(baseConVar));
_baseConVar.PropertyChanged += BaseConVarOnPropertyChanged;
_baseConVar.PropertyChanging += BaseConVarOnPropertyChanging;
}
private async Task SetValueAsync(T? value)
{
await _valueChangeSemaphore.WaitAsync().ConfigureAwait(false);
try
{
var newValue = await OnValueChange(value).ConfigureAwait(false);
lock (_lock)
{
_baseConVar.Value = newValue;
}
}
finally
{
_valueChangeSemaphore.Release();
}
}
protected abstract Task<T?> OnValueChange(T? newValue);
private void BaseConVarOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
2025-08-07 22:34:25 +03:00
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasValue)));
2025-08-06 21:29:00 +03:00
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
}
private void BaseConVarOnPropertyChanging(object? sender, PropertyChangingEventArgs e)
{
2025-08-07 22:34:25 +03:00
PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(nameof(HasValue)));
2025-08-06 21:29:00 +03:00
PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(nameof(Value)));
}
public event PropertyChangedEventHandler? PropertyChanged;
public event PropertyChangingEventHandler? PropertyChanging;
}