Skip to content

Commit

Permalink
RX State all new State handling
Browse files Browse the repository at this point in the history
Major changes and simplification
  • Loading branch information
Bernhard Straub committed Mar 17, 2024
1 parent 5716749 commit 6ee6a3f
Show file tree
Hide file tree
Showing 70 changed files with 2,181 additions and 2,298 deletions.
5 changes: 4 additions & 1 deletion RxBlazorLightCore/Component/RxBLServiceScope.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ public sealed partial class RxBLServiceScope<TScope, TService> : ComponentBase,
[CascadingParameter]
public required TService Service { get; init; }

[Parameter, EditorRequired]
public required Func<IRxBLScope> ScopeFactory { get; init; }

[Parameter]
public required RenderFragment ChildContent { get; init; }

Expand All @@ -18,7 +21,7 @@ public sealed partial class RxBLServiceScope<TScope, TService> : ComponentBase,
protected override void OnInitialized()
{
ArgumentNullException.ThrowIfNull(Service);
Scope = (TScope)Service.CreateScope();
Scope = (TScope)ScopeFactory();
Scope.EnterScope();
ArgumentNullException.ThrowIfNull(Scope);
base.OnInitialized();
Expand Down
25 changes: 0 additions & 25 deletions RxBlazorLightCore/Component/RxBLServiceStateSubscriberS.cs

This file was deleted.

109 changes: 32 additions & 77 deletions RxBlazorLightCore/Core/Interfaces.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
global using ServiceChangeReason = (RxBlazorLightCore.ChangeReason Reason, System.Guid ID);
global using ServiceException = (System.Exception Exception, System.Guid ID);

using System.Diagnostics.CodeAnalysis;
using System.Reactive;
using System.Diagnostics.CodeAnalysis;

namespace RxBlazorLightCore
{
Expand All @@ -13,7 +13,7 @@ public enum ChangeReason
STATE
}

public interface IRxBLScope
public interface IRxBLScope
{
public void EnterScope() { }
public void LeaveScope() { }
Expand All @@ -25,111 +25,66 @@ public interface IRxBLService : IObservable<ServiceChangeReason>
public bool Initialized { get; }
public IEnumerable<ServiceException> Exceptions { get; }
public void ResetExceptions();
public IRxBLScope CreateScope();
public Guid ID { get; }
}

public interface IRxObservableStateBase : IObservable<StateChangePhase>
{
public StateChangePhase Phase { get; }
public bool LongRunning { get; }
public bool CanCancel { get; }
public void Cancel();
}

public interface IRxObservableState : IRxObservableStateBase
{
public void Set();
}

public interface IRxObservableStateAsync : IRxObservableStateBase
public enum StatePhase
{
public Task SetAsync();
}

public interface IRxBLService<S> : IRxBLService
{
public S State { get; }
public void SetState(Action<S> action);
public IRxObservableState CreateObservableState(Action<S> action);
public Task SetStateAsync(Func<S, Task> actionAsync, Action<StateChangePhase>? phaseCB);
public IRxObservableStateAsync CreateObservableStateAsync(Func<S, Task> actionAsync);
public Task SetStateAsync(Func<S, CancellationToken, Task> actionAsync, CancellationToken cancellationToken, Action<StateChangePhase>? phaseCB);
CHANGING,
CHANGED,
CANCELED,
EXCEPTION
}


public interface IState<TInterface, TType> : IStateTransformer<TType> where TType : TInterface
public interface IStateBase<T> : IObservable<StatePhase>
{
public TInterface? Value { get; }
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 IState<TType> : IState<TType, TType>;

public interface IState : IState<Unit, Unit>
{
public static Unit Default { get; } = Unit.Default;
}

public interface IStateGroup<TType> : IState<TType>
public interface IState<T> : IStateBase<T>
{
public TType[] GetItems();
public bool IsItemDisabled(int index);
}
public bool CanChange(Func<IState<T>, bool> canChangeDelegate);

public interface IStateGroup<TInterface, TType> : IState<TInterface, TType>
where TType : TInterface
{
public TInterface[] GetItems();
public bool IsItemDisabled(int index);
public void Change(Action<IState<T>> changeDelegate, bool notify = true);
}

public enum StateChangePhase
public interface IStateAsync<T> : IStateBase<T>
{
NONE,
CHANGING,
CHANGED,
COMPLETED,
CANCELED,
EXCEPTION
}

public interface IStateProvideTransformBase
{
public StateChangePhase Phase { get; }
public bool LongRunning { get; }
public bool CanChange(Func<IStateAsync<T>, bool> canChangeDelegate);
public Task ChangeAsync(Func<IStateAsync<T>, Task> changeDelegateAsync, bool notify = true);
public Task ChangeAsync(Func<IStateAsync<T>, CancellationToken, Task> changeDelegateAsync, bool notify = true);
public bool CanCancel { get; }
public void Cancel();
public Guid ID { get; }
}

public interface IStateTransformer<T> : IStateProvideTransformBase
public interface IState: IState<Unit>
{
public void Transform(T value);

public bool CanTransform(T? value);
public bool CanChange(Func<IState, bool> canChangeDelegate);
public void Change(Action<IRxBLService> changeDelegate, bool notify = true);
}

public interface IObservableStateProvider<T> : IStateProvideTransformBase, IObserver<T>
public interface IStateAsync : IStateAsync<Unit>
{
void Provide(T value);
public bool CanChange(Func<IStateAsync, bool> canChangeDelegate);
public Task ChangeAsync(Func<IRxBLService, Task> changeDelegateAsync, bool notify = true);
public Task ChangeAsync(Func<IRxBLService, CancellationToken, Task> changeDelegateAsync, bool notify = true);
}

public interface IObservableStateProvider : IObservableStateProvider<Unit>
public interface IStateGroup<T> : IState<T>
{
void Provide();
}

public interface IStateProvider<T> : IStateProvideTransformBase
{
public void Provide();

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

public interface IStateProvider : IStateProvider<Unit>
public interface IStateGroupAsync<T> : IStateAsync<T>
{
public T[] Items { get; }
public bool ItemDisabled(int index);
}
}
77 changes: 24 additions & 53 deletions RxBlazorLightCore/Core/RxExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,93 +1,64 @@

using System;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;

namespace RxBlazorLightCore
{
public static class RxExtensions
{
public static IState<TInterface, TType> CreateState<S, TInterface, TType>(this S service, TType? value, Func<IState<TInterface, TType>, IStateTransformer<TType>>? stateProviderTransformerFactory = null)
where S : RxBLService
where TType : class, TInterface
{
return State<S, TInterface, TType>.Create(service, value, stateProviderTransformerFactory);
}

public static IState<TType> CreateState<S, TType>(this S service, TType? value, Func<IState<TType>, IStateTransformer<TType>>? stateProviderTransformerFactory = null) where S : RxBLService
{
return State<S, TType>.Create(service, value, stateProviderTransformerFactory);
}

public static IObservableStateProvider CreateObservableStateProvider<S>(this S service) where S : RxBLService
public static IState CreateState(this RxBLService service)
{
return ObservableStateProvider<S>.Create(service);
return State.Create(service);
}

public static IObservableStateProvider<T> CreateObservableStateProvider<S, T>(this S service, IState<T> state) where S : RxBLService
public static IStateAsync CreateStateAsync(this RxBLService service)
{
return ObservableStateProvider<S, T>.Create(service, state);
return StateAsync.Create(service);
}

public static IObservable<Unit> GetStatePhaseObservable<S>(this S service, IStateProvideTransformBase stateProviderTransformer,
StateChangePhase phase = StateChangePhase.CHANGED) where S : RxBLService
public static IState<T> CreateState<T>(this RxBLService service, T value)
{
return service
.Where(sc => sc.ID == stateProviderTransformer.ID && stateProviderTransformer.Phase == phase)
.Select(_ => Unit.Default);
return State<T>.Create(service, value);
}

public static bool Changing(this IStateProvideTransformBase stateProviderTransformer)
public static IStateAsync<T> CreateStateAsync<T>(this RxBLService service, T value)
{
return stateProviderTransformer.Phase is StateChangePhase.CHANGING;
return StateAsync<T>.Create(service, value);
}

public static bool Changed(this IStateProvideTransformBase stateProviderTransformer)
public static IStateGroup<T> CreateStateGroup<T>(this RxBLService service, T[] items, T inititalItem, Func<int, bool>? itemDisabledDelegate = null)
{
return stateProviderTransformer.Phase is StateChangePhase.CHANGED;
return StateGroup<T>.Create(service, items, inititalItem, itemDisabledDelegate);
}

public static bool Completed(this IStateProvideTransformBase stateProviderTransformer)
public static IStateGroupAsync<T> CreateStateGroupAsync<T>(this RxBLService service, T[] items, T inititalItem, Func<int, bool>? itemDisabledDelegate = null)
{
return stateProviderTransformer.Phase is StateChangePhase.COMPLETED;
return StateGroupAsync<T>.Create(service, items, inititalItem, itemDisabledDelegate);
}

public static bool Canceled(this IStateProvideTransformBase stateProviderTransformer)
public static bool Changing<T>(this IStateBase<T> state)
{
return stateProviderTransformer.Phase is StateChangePhase.CANCELED;
return state.Phase is StatePhase.CHANGING;
}

public static bool Exception(this IStateProvideTransformBase stateProviderTransformer)
public static bool Changed<T>(this IStateBase<T> state)
{
return stateProviderTransformer.Phase is StateChangePhase.EXCEPTION;
return state.Phase is StatePhase.CHANGED;
}

public static bool Done(this IStateProvideTransformBase stateProviderTransformer)
public static bool Canceled<T>(this IStateBase<T> state)
{
return stateProviderTransformer.Phase is StateChangePhase.CHANGED ||
stateProviderTransformer.Phase is StateChangePhase.CANCELED ||
stateProviderTransformer.Phase is StateChangePhase.EXCEPTION;
return state.Phase is StatePhase.CANCELED;
}

internal static void RunValueTask(this ValueTask valueTask)
public static bool Exception<T>(this IStateBase<T> state)
{
if (!valueTask.IsCompleted)
{
throw new InvalidOperationException("ValueTask does not run synchronously!");
}

valueTask.GetAwaiter().GetResult();
return state.Phase is StatePhase.EXCEPTION;
}

internal static TResult RunValueTask<TResult>(this ValueTask<TResult> valueTask)
public static bool Done<T>(this IStateBase<T> state)
{
if (!valueTask.IsCompleted)
{
throw new InvalidOperationException("ValueTask does not run synchronously!");
}

return valueTask.GetAwaiter().GetResult();
return state.Phase is StatePhase.CHANGED ||
state.Phase is StatePhase.CANCELED ||
state.Phase is StatePhase.EXCEPTION;
}
}
}
Loading

0 comments on commit 6ee6a3f

Please sign in to comment.