Skip to content

Commit

Permalink
RX State all new State handing
Browse files Browse the repository at this point in the history
Synchronized changing
  • Loading branch information
b-straub committed Apr 20, 2024
1 parent 904e4f5 commit be3a40d
Show file tree
Hide file tree
Showing 30 changed files with 123 additions and 99 deletions.
9 changes: 7 additions & 2 deletions RxBlazorLightCore/Component/RxBLServiceContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ protected override void OnInitialized()
{
foreach (var type in ServiceCollector.ServiceTypes)
{
ActivatorUtilities.CreateInstance(ServiceProvider, type);
var service = ActivatorUtilities.CreateInstance(ServiceProvider, type) as IRxBLService;
ArgumentNullException.ThrowIfNull(service);
ServiceCollector.AddService(service);
}
}
base.OnInitialized();
Expand All @@ -29,7 +31,10 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
{
foreach (var service in ServiceCollector.Services)
{
await service.OnContextReadyAsync();
if (!service.Initialized)
{
await service.OnContextReadyAsync();
}
}
}

Expand Down
21 changes: 4 additions & 17 deletions RxBlazorLightCore/Component/RxBLServiceSubscriber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,21 @@ protected override void OnInitialized()
.Sample(TimeSpan.FromMilliseconds(SampleRateMS))
.Select(async cr =>
{
await ServiceStateHasChangedAsync(cr);
ServiceStateHasChanged(cr);
await OnServiceStateHasChangedAsync(cr);
OnServiceStateHasChanged(cr);
await InvokeAsync(StateHasChanged);
})
.Subscribe();
}

protected virtual void ServiceStateHasChanged(ServiceChangeReason cr)
protected virtual void OnServiceStateHasChanged(ServiceChangeReason cr)
{
}

protected virtual Task ServiceStateHasChangedAsync(ServiceChangeReason cr)
protected virtual Task OnServiceStateHasChangedAsync(ServiceChangeReason cr)
{
return Task.CompletedTask;
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
if (!Service.Initialized)
{
await Service.OnContextReadyAsync();
}
}

await base.OnAfterRenderAsync(firstRender);
}
}

public class RxBLServiceSubscriber<T1, T2> : ComponentBase where T1 : IRxBLService where T2 : IRxBLService
Expand Down
4 changes: 2 additions & 2 deletions RxBlazorLightCore/Core/Interfaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ public interface IRxBLStateScope : IDisposable
public ValueTask OnContextReadyAsync();
}

public interface IRxBLService : IObservable<ServiceChangeReason>, IObserver<Unit>
public interface IRxBLService : IObservable<ServiceChangeReason>, IObserver<Unit>, IStateInformation
{
public ValueTask OnContextReadyAsync();
public bool Initialized { get; }
public IEnumerable<ServiceException> Exceptions { get; }
public void ResetExceptions();
public Guid ID { get; }
public void StateHasChanged();
public IStateCommand Command { get; }
public IStateCommandAsync CommandAsync { get; }
Expand All @@ -43,6 +42,7 @@ public interface IStateInformation
{
public StatePhase Phase { get; }
public Guid ID { get; }
public bool Disabled { get; }
}

public interface IState<T> : IStateInformation
Expand Down
35 changes: 30 additions & 5 deletions RxBlazorLightCore/Core/RxExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,52 @@ public static class RxExtensions
{
public static IState<T> CreateState<T>(this RxBLService service, T value)
{
return State<T>.Create(service, value);
return State<T>.Create(service, value, false);
}

public static IState<T> CreateIndependentState<T>(this RxBLService service, T value)
{
return State<T>.Create(service, value, true);
}

public static IStateCommand CreateStateCommand(this RxBLService service)
{
return StateCommand.Create(service);
return StateCommand.Create(service, false);
}

public static IStateCommand CreateIndependentStateCommand(this RxBLService service)
{
return StateCommand.Create(service, true);
}

public static IStateCommandAsync CreateStateCommandAsync(this RxBLService service, bool canCancel = false)
{
return StateCommandAsync.Create(service, canCancel);
return StateCommandAsync.Create(service, canCancel, false);
}

public static IStateCommandAsync CreateIndependentStateCommandAsync(this RxBLService service, bool canCancel = false)
{
return StateCommandAsync.Create(service, canCancel, true);
}

public static IStateGroup<T> CreateStateGroup<T>(this RxBLService service, T[] items, T? value = default)
{
return StateGroup<T>.Create(service, items, value);
return StateGroup<T>.Create(service, items, value, false);
}

public static IStateGroup<T> CreateIndependentStateGroup<T>(this RxBLService service, T[] items, T? value = default)
{
return StateGroup<T>.Create(service, items, value, true);
}

public static IStateGroupAsync<T> CreateStateGroupAsync<T>(this RxBLService service, T[] items, T? value = default)
{
return StateGroupAsync<T>.Create(service, items, value);
return StateGroupAsync<T>.Create(service, items, value, false);
}

public static IStateGroupAsync<T> CreateIndependentStateGroupAsync<T>(this RxBLService service, T[] items, T? value = default)
{
return StateGroupAsync<T>.Create(service, items, value, true);
}

public static bool Changing(this IStateInformation state)
Expand Down
26 changes: 18 additions & 8 deletions RxBlazorLightCore/Core/Service.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Reactive;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;

Expand Down Expand Up @@ -34,6 +33,8 @@ public class RxBLService : IRxBLService
public IStateCommand Command { get; }
public IStateCommandAsync CommandAsync { get; }
public IStateCommandAsync CancellableCommandAsync { get; }
public StatePhase Phase { get; private set; } = StatePhase.CHANGED;
public bool Disabled => Phase is not StatePhase.CHANGING;

private readonly Subject<ServiceChangeReason> _changedSubject = new();
private readonly IObservable<ServiceChangeReason> _changedObservable;
Expand All @@ -52,19 +53,28 @@ public RxBLService()

public void StateHasChanged()
{
StateHasChanged(ID);
StateHasChanged(this);
}

internal void StateHasChanged(Guid id, Exception? exception = null)
internal void StateHasChanged(IStateInformation stateInfo, Exception? exception = null)
{
if (exception is not null)
{
_serviceExceptions.Add(new(id, exception));
_changedSubject.OnNext(new(id, ChangeReason.EXCEPTION));
_serviceExceptions.Add(new(stateInfo.ID, exception));
_changedSubject.OnNext(new(stateInfo.ID, ChangeReason.EXCEPTION));
}
else
{
_changedSubject.OnNext(new(id, ChangeReason.STATE));
_changedSubject.OnNext(new(stateInfo.ID, ChangeReason.STATE));
}

if (stateInfo.Changing())
{
Phase = StatePhase.CHANGING;
}
else
{
Phase = StatePhase.CHANGED;
}
}

Expand All @@ -81,7 +91,7 @@ public async ValueTask OnContextReadyAsync()
}
await ContextReadyAsync();
Initialized = true;
StateHasChanged(ID);
StateHasChanged(this);
}

protected virtual ValueTask ContextReadyAsync()
Expand Down
5 changes: 1 addition & 4 deletions RxBlazorLightCore/Core/ServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class RxServiceCollector

private readonly List<Type> _serviceTypes = [];

internal void AddService<T>(T service) where T : IRxBLService
internal void AddService(IRxBLService service)
{
_services.Add(service);
}
Expand All @@ -37,8 +37,6 @@ public static RxServiceCollector AddRxBLServiceCollector(this IServiceCollection
{
var service = new T();
services.AddSingleton(service);
collector.AddService(service);

return services;
}

Expand All @@ -49,7 +47,6 @@ public static IServiceCollection AddRxBLService<T>(this IServiceCollection servi
services.AddSingleton(sp =>
{
var service = serviceFactory(sp);
collector.AddService(service);
return service;
});

Expand Down
47 changes: 25 additions & 22 deletions RxBlazorLightCore/Core/State.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@

namespace RxBlazorLightCore
{
public class StateBase
public class StateBase : IStateInformation
{
public StatePhase Phase { get; private set; } = StatePhase.CHANGED;
public Guid ID { get; } = Guid.NewGuid();
public bool Disabled => _independent ? Phase is StatePhase.CHANGING : _service.Changing();

protected readonly RxBLService _service;
private bool _notifyChanging = true;
private bool _independent = true;

protected StateBase(RxBLService service)
protected StateBase(RxBLService service, bool independent)
{
_service = service;
_independent = independent;
}

public void NotifyChanging()
Expand Down Expand Up @@ -53,7 +56,7 @@ protected void PhaseChanged(bool changed, bool notify = true, Exception? excepti

if (notify || _notifyChanging || exception is not null)
{
_service.StateHasChanged(ID, exception);
_service.StateHasChanged(this, exception);
_notifyChanging = notify;
}
}
Expand All @@ -73,7 +76,7 @@ public T Value

private T _value;

protected State(RxBLService service, T value) : base(service)
protected State(RxBLService service, T value, bool independent) : base(service, independent)
{
_value = value;
}
Expand All @@ -89,15 +92,15 @@ public bool HasValue()
return Value is not null;
}

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

public class StateCommand : StateBase, IStateCommand
{
protected StateCommand(RxBLService service) : base(service)
protected StateCommand(RxBLService service, bool independent) : base(service, independent)
{
}

Expand All @@ -114,9 +117,9 @@ public void Execute(Action changeCallback)
}
}

public static IStateCommand Create(RxBLService service)
public static IStateCommand Create(RxBLService service, bool independent)
{
return new StateCommand(service);
return new StateCommand(service, independent);
}
}

Expand All @@ -127,7 +130,7 @@ public class StateCommandAsync : StateCommand, IStateCommandAsync
public CancellationToken CancellationToken { get; private set; }
public Guid? ChangeCallerID { get; private set; }

protected StateCommandAsync(RxBLService service, bool canCancel) : base(service)
protected StateCommandAsync(RxBLService service, bool canCancel, bool independent) : base(service, independent)
{
CanCancel = canCancel;
if (CanCancel)
Expand Down Expand Up @@ -182,9 +185,9 @@ private void ResetCancellationToken()
}
}

public static IStateCommandAsync Create(RxBLService service, bool canCancel)
public static IStateCommandAsync Create(RxBLService service, bool canCancel, bool independent)
{
return new StateCommandAsync(service, canCancel);
return new StateCommandAsync(service, canCancel, independent);
}
}

Expand All @@ -195,8 +198,8 @@ public class StateGroupBase<T> : StateBase, IStateGroupBase<T>

private readonly T[] _items;

protected StateGroupBase(RxBLService service, T? value, T[] items) :
base(service)
protected StateGroupBase(RxBLService service, T? value, T[] items, bool independent) :
base(service, independent)
{
Value = value;
_items = items;
Expand All @@ -216,8 +219,8 @@ public bool HasValue()

public class StateGroup<T> : StateGroupBase<T>, IStateGroup<T>
{
protected StateGroup(RxBLService service, T? value, T[] items) :
base(service, value, items)
protected StateGroup(RxBLService service, T? value, T[] items, bool independent) :
base(service, value, items, independent)
{
}

Expand All @@ -240,16 +243,16 @@ public void ChangeValue(T value, Action<T, T>? changingCallback)
}
}

public static IStateGroup<T> Create(RxBLService service, T[] items, T? value = default)
public static IStateGroup<T> Create(RxBLService service, T[] items, T? value, bool independent)
{
return new StateGroup<T>(service, value, items);
return new StateGroup<T>(service, value, items, independent);
}
}

public class StateGroupAsync<T> : StateGroupBase<T>, IStateGroupAsync<T>
{
protected StateGroupAsync(RxBLService service, T? value, T[] items) :
base(service, value, items)
protected StateGroupAsync(RxBLService service, T? value, T[] items, bool independent) :
base(service, value, items, independent)
{
}

Expand All @@ -273,9 +276,9 @@ public async Task ChangeValueAsync(T value, Func<T, T, Task>? changingCallbackAs
}
}

public static IStateGroupAsync<T> Create(RxBLService service, T[] items, T? value = default)
public static IStateGroupAsync<T> Create(RxBLService service, T[] items, T? value, bool independent)
{
return new StateGroupAsync<T>(service, value, items);
return new StateGroupAsync<T>(service, value, items, independent);
}
}
}
2 changes: 0 additions & 2 deletions RxBlazorLightCore/RxBlazorLightCore.csproj.DotSettings

This file was deleted.

1 change: 0 additions & 1 deletion RxMudBlazorLight/ButtonBase/ButtonBaseRx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using MudBlazor;
using RxBlazorLightCore;
using RxMudBlazorLight.Extensions;
using System.Reflection.Emit;

namespace RxMudBlazorLight.ButtonBase
{
Expand Down
Loading

0 comments on commit be3a40d

Please sign in to comment.