-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathStateChangedObserver.cs
64 lines (54 loc) · 1.94 KB
/
StateChangedObserver.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using Memento.Blazor.Internal;
using Microsoft.AspNetCore.Components;
using System.Collections.Concurrent;
namespace Memento.Blazor;
internal class Item(IDisposable disposable, bool isEnabled) {
public bool IsEnabled { get; set; } = isEnabled;
public IDisposable Disposable => disposable;
}
/// <summary>
/// Represents a component observer that subscribes to a collection of observables.
/// </summary>
public class StateChangedObserver : ComponentBase, IDisposable {
readonly ConcurrentDictionary<IObservable<object>, Item> _events = new();
/// <summary>
/// Gets or sets the collection of observables to subscribe to.
/// </summary>
[Parameter]
public IEnumerable<IObservable<object>> Observables { get; set; } = [];
/// <summary>
/// Gets or sets the event callback to invoke when the state has changed.
/// </summary>
[Parameter]
public EventCallback OnStateHasChanged { get; set; }
/// <inheritdoc/>
protected override void OnParametersSet() {
base.OnParametersSet();
foreach (var (k, v) in _events) {
_events[k].IsEnabled = false;
}
foreach (var observable in Observables) {
if (_events.ContainsKey(observable)) {
_events[observable].IsEnabled = true;
continue;
}
else {
var d = observable.Subscribe(new Observer<object>(_ => OnStateHasChanged.InvokeAsync()));
_events.TryAdd(observable, new Item(d, true));
}
}
foreach (var (k, v) in _events) {
if (v.IsEnabled is false) {
_events.TryRemove(k, out _);
v.Disposable.Dispose();
}
}
}
/// <inheritdoc/>
public void Dispose() {
foreach (var (k, v) in _events) {
v.Disposable.Dispose();
}
_events.Clear();
}
}