Skip to content

Commit

Permalink
RX State all new State handling
Browse files Browse the repository at this point in the history
Introduce Commands again
  • Loading branch information
Bernhard Straub committed Mar 27, 2024
1 parent f1cc590 commit a89b857
Show file tree
Hide file tree
Showing 59 changed files with 825 additions and 735 deletions.
36 changes: 24 additions & 12 deletions RxBlazorLightCore/Core/Interfaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,42 +35,54 @@ public enum StatePhase
EXCEPTION
}

public interface IStateBase<T>
public interface IState<T>
{
public T Value { get; set; }

[MemberNotNullWhen(true, nameof(Value))]
public bool HasValue();
public void NotifyChanging();
public StatePhase Phase { get; }
public Guid ID { get; }
}

public interface IStateCommandBase
{
public StatePhase Phase { get; }
public Guid ID { get; }
public Guid? ChangeCallerID { get; }
}

public interface IState<T> : IStateBase<T>
public interface IStateCommandAsyncBase
{
public bool CanChange(Func<IState<T>, bool> canChangeDelegate);
public void NotifyChanging();
}

public void Change(Action<IState<T>> changeDelegate);
public interface IStateCommand : IStateCommandBase
{
public void Change();

public void Change(Action changeDelegate);
}

public interface IStateAsync<T> : IStateBase<T>
public interface IStateCommandAsync : IStateCommand, IStateCommandAsyncBase
{
public bool CanChange(Func<IStateAsync<T>, bool> canChangeDelegate);
public Task ChangeAsync(Func<IStateAsync<T>, Task> changeDelegateAsync, bool notifyChanging = false, Guid? changeCallerID = null);
public Task ChangeAsync(Func<IStateAsync<T>, CancellationToken, Task> changeDelegateAsync, bool notifyChanging = true, Guid? changeCallerID = null);
public Task ChangeAsync(Func<Task> changeDelegateAsync, bool notifyChanging = true, Guid? changeCallerID = null);
public Task ChangeAsync(Func<CancellationToken, Task> changeDelegateAsync, bool notifyChanging = true, Guid? changeCallerID = null);
public void Cancel();
}

public interface IStateGroup<T> : IState<T>

public interface IStateGroup<T> : IStateCommand
{
public T Value { get; set; }

public T[] Items { get; }
public bool ItemDisabled(int index);
}

public interface IStateGroupAsync<T> : IStateAsync<T>
public interface IStateGroupAsync<T> : IStateCommandAsync
{
public T Value { get; set; }

public T[] Items { get; }
public bool ItemDisabled(int index);
}
Expand Down
27 changes: 16 additions & 11 deletions RxBlazorLightCore/Core/RxExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,47 @@ public static IState<T> CreateState<T>(this RxBLService service, T value)
return State<T>.Create(service, value);
}

public static IStateAsync<T> CreateStateAsync<T>(this RxBLService service, T value)
public static IStateCommand CreateStateCommand(this RxBLService service)
{
return StateAsync<T>.Create(service, value);
return StateCommand.Create(service);
}

public static IStateGroup<T> CreateStateGroup<T>(this RxBLService service, T[] items, T inititalItem, Func<int, bool>? itemDisabledDelegate = null)
public static IStateCommandAsync CreateStateCommandAsync(this RxBLService service)
{
return StateGroup<T>.Create(service, items, inititalItem, itemDisabledDelegate);
return StateCommandAsync.Create(service);
}

public static IStateGroupAsync<T> CreateStateGroupAsync<T>(this RxBLService service, T[] items, T inititalItem, Func<int, bool>? itemDisabledDelegate = null)
public static IStateGroup<T> CreateStateGroup<T>(this RxBLService service, T[] items, T value, Func<int, bool>? itemDisabledDelegate = null)
{
return StateGroupAsync<T>.Create(service, items, inititalItem, itemDisabledDelegate);
return StateGroup<T>.Create(service, items, value, itemDisabledDelegate);
}

public static bool Changing<T>(this IStateBase<T> state)
public static IStateGroupAsync<T> CreateStateGroupAsync<T>(this RxBLService service, T[] items, T value, Func<int, bool>? itemDisabledDelegate = null)
{
return StateGroupAsync<T>.Create(service, items, value, itemDisabledDelegate);
}

public static bool Changing(this IStateCommandBase state)
{
return state.Phase is StatePhase.CHANGING;
}

public static bool Changed<T>(this IStateBase<T> state)
public static bool Changed(this IStateCommandBase state)
{
return state.Phase is StatePhase.CHANGED;
}

public static bool Canceled<T>(this IStateBase<T> state)
public static bool Canceled(this IStateCommandBase state)
{
return state.Phase is StatePhase.CANCELED;
}

public static bool Exception<T>(this IStateBase<T> state)
public static bool Exception(this IStateCommandBase state)
{
return state.Phase is StatePhase.EXCEPTION;
}

public static bool Done<T>(this IStateBase<T> state)
public static bool Done(this IStateCommandBase state)
{
return state.Phase is StatePhase.CHANGED ||
state.Phase is StatePhase.CANCELED ||
Expand Down
3 changes: 0 additions & 3 deletions RxBlazorLightCore/Core/ServiceExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@

using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Reactive.Linq;

namespace RxBlazorLightCore
{
Expand Down
109 changes: 68 additions & 41 deletions RxBlazorLightCore/Core/State.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,20 @@

namespace RxBlazorLightCore
{
public class StateBase<T> : IStateBase<T>
public class StateBase : IStateCommandBase, IStateCommandAsyncBase
{
public T Value { get; set; }
public StatePhase Phase { get; private set; } = StatePhase.CHANGED;
public Guid ID { get; } = Guid.NewGuid();
public Guid? ChangeCallerID { get; protected set; }

protected readonly RxBLService _service;
private bool _notifyChanging = true;

protected StateBase(RxBLService service, T value)
protected StateBase(RxBLService service)
{
Value = value;
_service = service;
}

[MemberNotNullWhen(true, nameof(Value))]
public bool HasValue()
{
return Value is not null;
}

public void NotifyChanging()
{
if (!_notifyChanging)
Expand Down Expand Up @@ -68,49 +60,80 @@ protected void PhaseChanged(bool changed, bool notify = true, Exception? excepti
}
}

public class State<T> : StateBase<T>, IState<T>
public class State<T> : StateBase, IState<T>
{
public T Value
{
get => _value;
set
{
_value = value;
PhaseChanged(true);
}
}

private T _value;

protected State(RxBLService service, T value) : base(service)
{
_value = value;
}

[MemberNotNullWhen(true, nameof(Value))]
public bool HasValue()
{
return Value is not null;
}

public static IState<T> Create(RxBLService service, T value)
{
return new State<T>(service, value);
}
}

public class StateCommandBase : StateBase
{
protected State(RxBLService service, T value) : base(service, value) { }
protected StateCommandBase(RxBLService service) : base(service) { }

public bool CanChange(Func<IState<T>, bool> canChangeDelegate)
public void Change()
{
return canChangeDelegate(this);
PhaseChanged(true);
}

public void Change(Action<IState<T>> changeDelegate)
public void Change(Action changeDelegate)
{
try
{
PhaseChanged(false);
changeDelegate(this);
changeDelegate();
PhaseChanged(true);
}
catch (Exception ex)
{
PhaseChanged(true, true, ex);
}
}
}

public static IState<T> Create(RxBLService service, T value)
public class StateCommand : StateCommandBase, IStateCommand
{
protected StateCommand(RxBLService service) : base(service) { }

public static IStateCommand Create(RxBLService service)
{
return new State<T>(service, value);
return new StateCommand(service);
}
}

public class StateAsync<T> : StateBase<T>, IStateAsync<T>
public class StateCommandAsync : StateCommandBase, IStateCommandAsync
{
private CancellationTokenSource _cancellationTokenSource = new();

protected StateAsync(RxBLService service, T value) : base(service, value) { }
protected StateCommandAsync(RxBLService service) : base(service) { }

private bool _canCancel;

public bool CanChange(Func<IStateAsync<T>, bool> canChangeDelegate)
{
return canChangeDelegate(this);
}

public async Task ChangeAsync(Func<IStateAsync<T>, CancellationToken, Task> changeDelegateAsync, bool notifyChanging, Guid? changeCallerID = null)
public async Task ChangeAsync(Func<CancellationToken, Task> changeDelegateAsync, bool notifyChanging, Guid? changeCallerID = null)
{
try
{
Expand All @@ -119,7 +142,7 @@ public async Task ChangeAsync(Func<IStateAsync<T>, CancellationToken, Task> chan
ResetCancellationToken();
_canCancel = true;
PhaseChanged(false, notifyChanging);
await changeDelegateAsync(this, _cancellationTokenSource.Token);
await changeDelegateAsync(_cancellationTokenSource.Token);
PhaseChanged(true);
}
catch (Exception ex)
Expand All @@ -133,15 +156,15 @@ public async Task ChangeAsync(Func<IStateAsync<T>, CancellationToken, Task> chan
}
}

public async Task ChangeAsync(Func<IStateAsync<T>, Task> changeDelegateAsync, bool notifyChanging, Guid? changeCallerID = null)
public async Task ChangeAsync(Func<Task> changeDelegateAsync, bool notifyChanging, Guid? changeCallerID = null)
{
try
{
ChangeCallerID = changeCallerID;

ResetCancellationToken();
PhaseChanged(false, notifyChanging);
await changeDelegateAsync(this);
await changeDelegateAsync();
PhaseChanged(true);
}
catch (Exception ex)
Expand Down Expand Up @@ -170,22 +193,24 @@ private void ResetCancellationToken()
}
}

public static IStateAsync<T> Create(RxBLService service, T value)
public static IStateCommandAsync Create(RxBLService service)
{
return new StateAsync<T>(service, value);
return new StateCommandAsync(service);
}
}

public class StateGroup<T> : State<T>, IStateGroup<T>
public class StateGroup<T> : StateCommand, IStateGroup<T>, IStateCommand
{
public T Value { get; set; }
public T[] Items => _items;

private readonly T[] _items;
private readonly Func<int, bool>? _itemDisabledDelegate;

protected StateGroup(RxBLService service, T inititalItem, T[] items, Func<int, bool>? itemDisabledDelegate) :
base(service, inititalItem)
protected StateGroup(RxBLService service, T value, T[] items, Func<int, bool>? itemDisabledDelegate) :
base(service)
{
Value = value;
_items = items;
_itemDisabledDelegate = itemDisabledDelegate;
}
Expand All @@ -195,22 +220,24 @@ public bool ItemDisabled(int index)
return _itemDisabledDelegate is not null && _itemDisabledDelegate(index);
}

public static IStateGroup<T> Create(RxBLService service, T[] items, T inititalItem, Func<int, bool>? itemDisabledDelegate = null)
public static IStateGroup<T> Create(RxBLService service, T[] items, T value, Func<int, bool>? itemDisabledDelegate = null)
{
return new StateGroup<T>(service, inititalItem, items, itemDisabledDelegate);
return new StateGroup<T>(service, value, items, itemDisabledDelegate);
}
}

public class StateGroupAsync<T> : StateAsync<T>, IStateGroupAsync<T>
public class StateGroupAsync<T> : StateCommandAsync, IStateGroupAsync<T>, IStateCommandAsync
{
public T Value { get; set; }
public T[] Items => _items;

private readonly T[] _items;
private readonly Func<int, bool>? _itemDisabledDelegate;

protected StateGroupAsync(RxBLService service, T inititalItem, T[] items, Func<int, bool>? itemDisabledDelegate) :
base(service, inititalItem)
protected StateGroupAsync(RxBLService service, T value, T[] items, Func<int, bool>? itemDisabledDelegate) :
base(service)
{
Value = value;
_items = items;
_itemDisabledDelegate = itemDisabledDelegate;
}
Expand All @@ -220,9 +247,9 @@ public bool ItemDisabled(int index)
return _itemDisabledDelegate is not null && _itemDisabledDelegate(index);
}

public static IStateGroupAsync<T> Create(RxBLService service, T[] items, T inititalItem, Func<int, bool>? itemDisabledDelegate = null)
public static IStateGroupAsync<T> Create(RxBLService service, T[] items, T value, Func<int, bool>? itemDisabledDelegate = null)
{
return new StateGroupAsync<T>(service, inititalItem, items, itemDisabledDelegate);
return new StateGroupAsync<T>(service, value, items, itemDisabledDelegate);
}
}
}
Loading

0 comments on commit a89b857

Please sign in to comment.