Files

51 lines
1.5 KiB
C#

using System;
namespace GodotHostTest.AetherBind;
/// <summary>
/// An object that allows communication through scopes (or inside the scope itself) by providing a couple getter/setter that can be injected in different scopes (or the same scope).
/// </summary>
/// <typeparam name="T">The type that's been passed through scopes.</typeparam>
/// <seealso cref="BuilderExtensions.AddValueProvider{TValueType,TScope}" />
/// <seealso cref="BuilderExtensions.AddValueProvider{TValueType,TSourceScope,TDestinationScope}" />
public class ValueProvider<T>
{
private IValueGetter<T>? _getter;
private bool _isSet;
private T? _value;
public ValueProvider()
{
Setter = new SetterImplementation(this);
}
public IValueSetter<T> Setter { get; }
public IValueGetter<T> Getter
{
get
{
_getter ??= !_isSet
? throw new InvalidOperationException($"Value of type {typeof(T)} has not been set yet.")
: new GetterImplementation(_value!);
return _getter;
}
}
private class SetterImplementation(ValueProvider<T> valueProvider) : IValueSetter<T>
{
public void Set(T value)
{
if (valueProvider._isSet)
throw new InvalidOperationException($"A value (of type {typeof(T)}) cannot be set more than once.");
valueProvider._value = value;
valueProvider._isSet = true;
}
}
private class GetterImplementation(T value) : IValueGetter<T>
{
public T Value => value;
}
}