com.fofx.observething 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/Runtime/CollectionIdProvider.cs +71 -71
- package/Runtime/CollectionIdProvider.cs.meta +1 -1
- package/Runtime/IObservable.cs +66 -66
- package/Runtime/IObservable.cs.meta +1 -1
- package/Runtime/Implementations/Observable.cs +29 -29
- package/Runtime/Implementations/Observable.cs.meta +1 -1
- package/Runtime/Implementations/ObservableBase.cs +172 -172
- package/Runtime/Implementations/ObservableBase.cs.meta +1 -1
- package/Runtime/Implementations/ObservableCollection.cs +140 -140
- package/Runtime/Implementations/ObservableCollection.cs.meta +1 -1
- package/Runtime/Implementations/ObservableDictionary.cs +165 -165
- package/Runtime/Implementations/ObservableDictionary.cs.meta +1 -1
- package/Runtime/Implementations/ObservableList.cs +162 -162
- package/Runtime/Implementations/ObservableList.cs.meta +1 -1
- package/Runtime/Implementations/ObservableSet.cs +136 -136
- package/Runtime/Implementations/ObservableSet.cs.meta +1 -1
- package/Runtime/Implementations/ObservableValue.cs +58 -58
- package/Runtime/Implementations/ObservableValue.cs.meta +1 -1
- package/Runtime/Observables/BatchObservable.cs +71 -71
- package/Runtime/Observables/BatchObservable.cs.meta +1 -1
- package/Runtime/Observables/CastObservable.cs +127 -127
- package/Runtime/Observables/CastObservable.cs.meta +1 -1
- package/Runtime/Observables/CombineObservable.cs +95 -95
- package/Runtime/Observables/CombineObservable.cs.meta +1 -1
- package/Runtime/Observables/CombineValueObservable.cs +318 -318
- package/Runtime/Observables/CombineValueObservable.cs.meta +1 -1
- package/Runtime/Observables/ConcatObservable.cs +74 -74
- package/Runtime/Observables/ConcatObservable.cs.meta +1 -1
- package/Runtime/Observables/ContainsObservable.cs +70 -70
- package/Runtime/Observables/ContainsObservable.cs.meta +1 -1
- package/Runtime/Observables/CountObservable.cs +29 -29
- package/Runtime/Observables/CountObservable.cs.meta +1 -1
- package/Runtime/Observables/DistinctObservable.cs +54 -54
- package/Runtime/Observables/DistinctObservable.cs.meta +1 -1
- package/Runtime/Observables/FirstObservable.cs +52 -52
- package/Runtime/Observables/FirstObservable.cs.meta +1 -1
- package/Runtime/Observables/IndexOfObservable.cs +82 -82
- package/Runtime/Observables/IndexOfObservable.cs.meta +1 -1
- package/Runtime/Observables/OperationStreamObservable.cs +193 -193
- package/Runtime/Observables/OperationStreamObservable.cs.meta +1 -1
- package/Runtime/Observables/OrderByObservable.cs +115 -116
- package/Runtime/Observables/OrderByObservable.cs.meta +1 -1
- package/Runtime/Observables/SelectCollectionObservable.cs +28 -28
- package/Runtime/Observables/SelectCollectionObservable.cs.meta +1 -1
- package/Runtime/Observables/SelectListObservable.cs +28 -28
- package/Runtime/Observables/SelectListObservable.cs.meta +1 -1
- package/Runtime/Observables/SelectManyObservable.cs +77 -77
- package/Runtime/Observables/SelectManyObservable.cs.meta +1 -1
- package/Runtime/Observables/SelectValueObservable.cs +27 -27
- package/Runtime/Observables/SelectValueObservable.cs.meta +1 -1
- package/Runtime/Observables/SkipWhileObservable.cs +31 -31
- package/Runtime/Observables/SkipWhileObservable.cs.meta +1 -1
- package/Runtime/Observables/ThenObservable.cs +208 -208
- package/Runtime/Observables/ThenObservable.cs.meta +1 -1
- package/Runtime/Observables/ToDictionaryObservable.cs +35 -35
- package/Runtime/Observables/ToDictionaryObservable.cs.meta +1 -1
- package/Runtime/Observables/TrackObservable.cs +74 -74
- package/Runtime/Observables/TrackObservable.cs.meta +1 -1
- package/Runtime/Observables/UnwrapCollectionObservable.cs +63 -63
- package/Runtime/Observables/UnwrapCollectionObservable.cs.meta +1 -1
- package/Runtime/Observables/UnwrapListObservable.cs +69 -69
- package/Runtime/Observables/UnwrapListObservable.cs.meta +1 -1
- package/Runtime/Observables/UnwrapValueObservable.cs +55 -55
- package/Runtime/Observables/UnwrapValueObservable.cs.meta +1 -1
- package/Runtime/Observables/WhereObservable.cs +84 -84
- package/Runtime/Observables/WhereObservable.cs.meta +1 -1
- package/Runtime/Observables/WithPreviousObservable.cs +36 -36
- package/Runtime/Observables/WithPreviousObservable.cs.meta +1 -1
- package/Runtime/Observables.cs +466 -466
- package/Runtime/Observables.meta +8 -8
- package/Runtime/ObservationContext.cs +125 -125
- package/Runtime/ObservationContext.cs.meta +1 -1
- package/Runtime/Observers.cs +402 -402
- package/Runtime/Observers.cs.meta +1 -1
- package/Runtime/Operators/BatchOperator.cs +70 -70
- package/Runtime/Operators/BatchOperator.cs.meta +1 -1
- package/Runtime/Operators/CollectionOperator.cs +30 -30
- package/Runtime/Operators/CollectionOperator.cs.meta +1 -1
- package/Runtime/Operators/DictionaryOperator.cs +45 -45
- package/Runtime/Operators/DictionaryOperator.cs.meta +1 -1
- package/Runtime/Operators/IInitializationOperationsProvider.cs +10 -10
- package/Runtime/Operators/IInitializationOperationsProvider.cs.meta +1 -1
- package/Runtime/Operators/ListOperator.cs +44 -44
- package/Runtime/Operators/ListOperator.cs.meta +1 -1
- package/Runtime/Operators/ObservableOperator.cs +74 -74
- package/Runtime/Operators/ObservableOperator.cs.meta +1 -1
- package/Runtime/Operators/Operator.cs +65 -65
- package/Runtime/Operators/Operator.cs.meta +1 -1
- package/Runtime/Operators/SetOperator.cs +44 -44
- package/Runtime/Operators/SetOperator.cs.meta +1 -1
- package/Runtime/Operators/ValueOperator.cs +29 -29
- package/Runtime/Operators/ValueOperator.cs.meta +1 -1
- package/Runtime/Operators.meta +8 -8
- package/Runtime/PriorityQueue.cs +1095 -1095
- package/Runtime/PriorityQueue.cs.meta +1 -1
- package/Tests/CollectionObservableTests.cs +738 -738
- package/Tests/DictionaryObservableTests.cs +84 -84
- package/Tests/ListObservableTests.cs +147 -147
- package/Tests/ObservationContextTests.cs +359 -359
- package/Tests/ObservationContextTests.cs.meta +1 -1
- package/Tests/ValueObservableTests.cs +321 -321
- package/package.json +24 -24
|
@@ -1,137 +1,137 @@
|
|
|
1
|
-
using System;
|
|
2
|
-
using System.Collections;
|
|
3
|
-
using System.Collections.Generic;
|
|
4
|
-
using System.Linq;
|
|
5
|
-
|
|
6
|
-
namespace ObserveThing
|
|
7
|
-
{
|
|
8
|
-
public interface ISetOp : IOperation
|
|
9
|
-
{
|
|
10
|
-
uint elementId { get; }
|
|
11
|
-
object element { get; }
|
|
12
|
-
bool isRemove { get; }
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
public struct SetOp<T> : ISetOp
|
|
16
|
-
{
|
|
17
|
-
public IObservable<IOperation> source { get; set; }
|
|
18
|
-
public uint elementId { get; set; }
|
|
19
|
-
public T element { get; set; }
|
|
20
|
-
public bool isRemove { get; set; }
|
|
21
|
-
|
|
22
|
-
object ISetOp.element => element;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
public class ObservableSet<T> : ObservableBase<ISetObserver<T>, SetOp<T>>, ISetObservable<T>, IEnumerable<T>
|
|
26
|
-
{
|
|
27
|
-
public int count => _set.Count;
|
|
28
|
-
|
|
29
|
-
public IEnumerator<T> GetEnumerator()
|
|
30
|
-
=> _set.Keys.GetEnumerator();
|
|
31
|
-
|
|
32
|
-
IEnumerator IEnumerable.GetEnumerator()
|
|
33
|
-
=> _set.Keys.GetEnumerator();
|
|
34
|
-
|
|
35
|
-
private Dictionary<T, uint> _set = new Dictionary<T, uint>();
|
|
36
|
-
private CollectionIdProvider _idProvider;
|
|
37
|
-
|
|
38
|
-
public ObservableSet() : this(default, default) { }
|
|
39
|
-
public ObservableSet(IEnumerable<T> values) : this(default, values) { }
|
|
40
|
-
public ObservableSet(ObservationContext context) : this(context, null) { }
|
|
41
|
-
public ObservableSet(ObservationContext context, IEnumerable<T> values) : base(context)
|
|
42
|
-
{
|
|
43
|
-
_idProvider = new CollectionIdProvider(x => _set.ContainsValue(x));
|
|
44
|
-
|
|
45
|
-
if (values == null)
|
|
46
|
-
return;
|
|
47
|
-
|
|
48
|
-
foreach (T value in values)
|
|
49
|
-
_set.Add(value, _idProvider.GetUnusedId());
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
public bool Add(T element)
|
|
53
|
-
{
|
|
54
|
-
if (_set.ContainsKey(element))
|
|
55
|
-
return false;
|
|
56
|
-
|
|
57
|
-
var id = _idProvider.GetUnusedId();
|
|
58
|
-
_set.Add(element, id);
|
|
59
|
-
EnqueuePendingOperation(new SetOp<T>() { source = this, elementId = id, element = element, isRemove = false });
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public void AddRange(IEnumerable<T> elements)
|
|
64
|
-
{
|
|
65
|
-
foreach (var element in elements)
|
|
66
|
-
Add(element);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
public bool Remove(T element)
|
|
70
|
-
{
|
|
71
|
-
if (!_set.TryGetValue(element, out var id))
|
|
72
|
-
return false;
|
|
73
|
-
|
|
74
|
-
_set.Remove(element);
|
|
75
|
-
EnqueuePendingOperation(new SetOp<T>() { source = this, elementId = id, element = element, isRemove = true });
|
|
76
|
-
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
public void Clear()
|
|
81
|
-
{
|
|
82
|
-
foreach (var kvp in _set.ToArray())
|
|
83
|
-
{
|
|
84
|
-
_set.Remove(kvp.Key);
|
|
85
|
-
EnqueuePendingOperation(new SetOp<T>() { source = this, elementId = kvp.Value, element = kvp.Key, isRemove = true });
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
public bool Contains(T element)
|
|
90
|
-
=> _set.ContainsKey(element);
|
|
91
|
-
|
|
92
|
-
public uint GetElementId(T element)
|
|
93
|
-
=> _set[element];
|
|
94
|
-
|
|
95
|
-
protected override IEnumerable<SetOp<T>> GetInitializationOperations()
|
|
96
|
-
{
|
|
97
|
-
foreach (var element in _set)
|
|
98
|
-
yield return new SetOp<T>() { source = this, element = element.Key, elementId = element.Value, isRemove = false };
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
protected override void SendOperation(ISetObserver<T> observer, SetOp<T> operation)
|
|
102
|
-
{
|
|
103
|
-
if (operation.isRemove)
|
|
104
|
-
{
|
|
105
|
-
observer.OnRemove(operation.elementId, operation.element);
|
|
106
|
-
}
|
|
107
|
-
else
|
|
108
|
-
{
|
|
109
|
-
observer.OnAdd(operation.elementId, operation.element);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
IDisposable ISetObservable.Subscribe(ISetObserver observer, bool immediate, uint? priority)
|
|
114
|
-
=> Subscribe(new SetObserver<T>(
|
|
115
|
-
onAdd: (id, element) => observer.OnAdd(id, element),
|
|
116
|
-
onRemove: (id, element) => observer.OnRemove(id, element),
|
|
117
|
-
onDispose: observer.OnDispose,
|
|
118
|
-
onError: observer.OnError
|
|
119
|
-
), immediate, priority);
|
|
120
|
-
|
|
121
|
-
IDisposable ICollectionObservable<T>.Subscribe(ICollectionObserver<T> observer, bool immediate, uint? priority)
|
|
122
|
-
=> Subscribe(new SetObserver<T>(
|
|
123
|
-
onAdd: (id, element) => observer.OnAdd(id, element),
|
|
124
|
-
onRemove: (id, element) => observer.OnRemove(id, element),
|
|
125
|
-
onDispose: observer.OnDispose,
|
|
126
|
-
onError: observer.OnError
|
|
127
|
-
), immediate, priority);
|
|
128
|
-
|
|
129
|
-
IDisposable ICollectionObservable.Subscribe(ICollectionObserver observer, bool immediate, uint? priority)
|
|
130
|
-
=> Subscribe(new SetObserver<T>(
|
|
131
|
-
onAdd: (id, element) => observer.OnAdd(id, element),
|
|
132
|
-
onRemove: (id, element) => observer.OnRemove(id, element),
|
|
133
|
-
onDispose: observer.OnDispose,
|
|
134
|
-
onError: observer.OnError
|
|
135
|
-
), immediate, priority);
|
|
136
|
-
}
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections;
|
|
3
|
+
using System.Collections.Generic;
|
|
4
|
+
using System.Linq;
|
|
5
|
+
|
|
6
|
+
namespace ObserveThing
|
|
7
|
+
{
|
|
8
|
+
public interface ISetOp : IOperation
|
|
9
|
+
{
|
|
10
|
+
uint elementId { get; }
|
|
11
|
+
object element { get; }
|
|
12
|
+
bool isRemove { get; }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public struct SetOp<T> : ISetOp
|
|
16
|
+
{
|
|
17
|
+
public IObservable<IOperation> source { get; set; }
|
|
18
|
+
public uint elementId { get; set; }
|
|
19
|
+
public T element { get; set; }
|
|
20
|
+
public bool isRemove { get; set; }
|
|
21
|
+
|
|
22
|
+
object ISetOp.element => element;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public class ObservableSet<T> : ObservableBase<ISetObserver<T>, SetOp<T>>, ISetObservable<T>, IEnumerable<T>
|
|
26
|
+
{
|
|
27
|
+
public int count => _set.Count;
|
|
28
|
+
|
|
29
|
+
public IEnumerator<T> GetEnumerator()
|
|
30
|
+
=> _set.Keys.GetEnumerator();
|
|
31
|
+
|
|
32
|
+
IEnumerator IEnumerable.GetEnumerator()
|
|
33
|
+
=> _set.Keys.GetEnumerator();
|
|
34
|
+
|
|
35
|
+
private Dictionary<T, uint> _set = new Dictionary<T, uint>();
|
|
36
|
+
private CollectionIdProvider _idProvider;
|
|
37
|
+
|
|
38
|
+
public ObservableSet() : this(default, default) { }
|
|
39
|
+
public ObservableSet(IEnumerable<T> values) : this(default, values) { }
|
|
40
|
+
public ObservableSet(ObservationContext context) : this(context, null) { }
|
|
41
|
+
public ObservableSet(ObservationContext context, IEnumerable<T> values) : base(context)
|
|
42
|
+
{
|
|
43
|
+
_idProvider = new CollectionIdProvider(x => _set.ContainsValue(x));
|
|
44
|
+
|
|
45
|
+
if (values == null)
|
|
46
|
+
return;
|
|
47
|
+
|
|
48
|
+
foreach (T value in values)
|
|
49
|
+
_set.Add(value, _idProvider.GetUnusedId());
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public bool Add(T element)
|
|
53
|
+
{
|
|
54
|
+
if (_set.ContainsKey(element))
|
|
55
|
+
return false;
|
|
56
|
+
|
|
57
|
+
var id = _idProvider.GetUnusedId();
|
|
58
|
+
_set.Add(element, id);
|
|
59
|
+
EnqueuePendingOperation(new SetOp<T>() { source = this, elementId = id, element = element, isRemove = false });
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public void AddRange(IEnumerable<T> elements)
|
|
64
|
+
{
|
|
65
|
+
foreach (var element in elements)
|
|
66
|
+
Add(element);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public bool Remove(T element)
|
|
70
|
+
{
|
|
71
|
+
if (!_set.TryGetValue(element, out var id))
|
|
72
|
+
return false;
|
|
73
|
+
|
|
74
|
+
_set.Remove(element);
|
|
75
|
+
EnqueuePendingOperation(new SetOp<T>() { source = this, elementId = id, element = element, isRemove = true });
|
|
76
|
+
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public void Clear()
|
|
81
|
+
{
|
|
82
|
+
foreach (var kvp in _set.ToArray())
|
|
83
|
+
{
|
|
84
|
+
_set.Remove(kvp.Key);
|
|
85
|
+
EnqueuePendingOperation(new SetOp<T>() { source = this, elementId = kvp.Value, element = kvp.Key, isRemove = true });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public bool Contains(T element)
|
|
90
|
+
=> _set.ContainsKey(element);
|
|
91
|
+
|
|
92
|
+
public uint GetElementId(T element)
|
|
93
|
+
=> _set[element];
|
|
94
|
+
|
|
95
|
+
protected override IEnumerable<SetOp<T>> GetInitializationOperations()
|
|
96
|
+
{
|
|
97
|
+
foreach (var element in _set)
|
|
98
|
+
yield return new SetOp<T>() { source = this, element = element.Key, elementId = element.Value, isRemove = false };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
protected override void SendOperation(ISetObserver<T> observer, SetOp<T> operation)
|
|
102
|
+
{
|
|
103
|
+
if (operation.isRemove)
|
|
104
|
+
{
|
|
105
|
+
observer.OnRemove(operation.elementId, operation.element);
|
|
106
|
+
}
|
|
107
|
+
else
|
|
108
|
+
{
|
|
109
|
+
observer.OnAdd(operation.elementId, operation.element);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
IDisposable ISetObservable.Subscribe(ISetObserver observer, bool immediate, uint? priority)
|
|
114
|
+
=> Subscribe(new SetObserver<T>(
|
|
115
|
+
onAdd: (id, element) => observer.OnAdd(id, element),
|
|
116
|
+
onRemove: (id, element) => observer.OnRemove(id, element),
|
|
117
|
+
onDispose: observer.OnDispose,
|
|
118
|
+
onError: observer.OnError
|
|
119
|
+
), immediate, priority);
|
|
120
|
+
|
|
121
|
+
IDisposable ICollectionObservable<T>.Subscribe(ICollectionObserver<T> observer, bool immediate, uint? priority)
|
|
122
|
+
=> Subscribe(new SetObserver<T>(
|
|
123
|
+
onAdd: (id, element) => observer.OnAdd(id, element),
|
|
124
|
+
onRemove: (id, element) => observer.OnRemove(id, element),
|
|
125
|
+
onDispose: observer.OnDispose,
|
|
126
|
+
onError: observer.OnError
|
|
127
|
+
), immediate, priority);
|
|
128
|
+
|
|
129
|
+
IDisposable ICollectionObservable.Subscribe(ICollectionObserver observer, bool immediate, uint? priority)
|
|
130
|
+
=> Subscribe(new SetObserver<T>(
|
|
131
|
+
onAdd: (id, element) => observer.OnAdd(id, element),
|
|
132
|
+
onRemove: (id, element) => observer.OnRemove(id, element),
|
|
133
|
+
onDispose: observer.OnDispose,
|
|
134
|
+
onError: observer.OnError
|
|
135
|
+
), immediate, priority);
|
|
136
|
+
}
|
|
137
137
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
fileFormatVersion: 2
|
|
1
|
+
fileFormatVersion: 2
|
|
2
2
|
guid: dfaadf050c3e8ac46a34cab50963c385
|
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
using System;
|
|
2
|
-
using System.Collections.Generic;
|
|
3
|
-
|
|
4
|
-
namespace ObserveThing
|
|
5
|
-
{
|
|
6
|
-
public interface IValueOp : IOperation
|
|
7
|
-
{
|
|
8
|
-
object value { get; }
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
public struct ValueOp<T> : IValueOp
|
|
12
|
-
{
|
|
13
|
-
public IObservable<IOperation> source { get; set; }
|
|
14
|
-
public T value { get; set; }
|
|
15
|
-
|
|
16
|
-
object IValueOp.value => value;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
public class ObservableValue<T> : ObservableBase<IValueObserver<T>, ValueOp<T>>, IValueObservable<T>
|
|
20
|
-
{
|
|
21
|
-
public T value
|
|
22
|
-
{
|
|
23
|
-
get => _value;
|
|
24
|
-
set
|
|
25
|
-
{
|
|
26
|
-
if (Equals(_value, value))
|
|
27
|
-
return;
|
|
28
|
-
|
|
29
|
-
_value = value;
|
|
30
|
-
EnqueuePendingOperation(new ValueOp<T>() { source = this, value = value });
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
private T _value;
|
|
35
|
-
|
|
36
|
-
public ObservableValue() : this(default, default) { }
|
|
37
|
-
public ObservableValue(T value) : this(default, value) { }
|
|
38
|
-
public ObservableValue(ObservationContext context) : this(context, default) { }
|
|
39
|
-
public ObservableValue(ObservationContext context, T value) : base(context)
|
|
40
|
-
{
|
|
41
|
-
_value = value;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
protected override IEnumerable<ValueOp<T>> GetInitializationOperations()
|
|
45
|
-
{
|
|
46
|
-
yield return new ValueOp<T>() { source = this, value = _value };
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
protected override void SendOperation(IValueObserver<T> observer, ValueOp<T> operation)
|
|
50
|
-
=> observer.OnNext(operation.value);
|
|
51
|
-
|
|
52
|
-
public IDisposable Subscribe(IValueObserver observer, bool immediate = false, uint? priority = null)
|
|
53
|
-
=> Subscribe(new ValueObserver<T>(
|
|
54
|
-
onNext: x => observer.OnNext(x),
|
|
55
|
-
onDispose: observer.OnDispose,
|
|
56
|
-
onError: observer.OnError
|
|
57
|
-
), immediate, priority);
|
|
58
|
-
}
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
|
|
4
|
+
namespace ObserveThing
|
|
5
|
+
{
|
|
6
|
+
public interface IValueOp : IOperation
|
|
7
|
+
{
|
|
8
|
+
object value { get; }
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public struct ValueOp<T> : IValueOp
|
|
12
|
+
{
|
|
13
|
+
public IObservable<IOperation> source { get; set; }
|
|
14
|
+
public T value { get; set; }
|
|
15
|
+
|
|
16
|
+
object IValueOp.value => value;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public class ObservableValue<T> : ObservableBase<IValueObserver<T>, ValueOp<T>>, IValueObservable<T>
|
|
20
|
+
{
|
|
21
|
+
public T value
|
|
22
|
+
{
|
|
23
|
+
get => _value;
|
|
24
|
+
set
|
|
25
|
+
{
|
|
26
|
+
if (Equals(_value, value))
|
|
27
|
+
return;
|
|
28
|
+
|
|
29
|
+
_value = value;
|
|
30
|
+
EnqueuePendingOperation(new ValueOp<T>() { source = this, value = value });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private T _value;
|
|
35
|
+
|
|
36
|
+
public ObservableValue() : this(default, default) { }
|
|
37
|
+
public ObservableValue(T value) : this(default, value) { }
|
|
38
|
+
public ObservableValue(ObservationContext context) : this(context, default) { }
|
|
39
|
+
public ObservableValue(ObservationContext context, T value) : base(context)
|
|
40
|
+
{
|
|
41
|
+
_value = value;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
protected override IEnumerable<ValueOp<T>> GetInitializationOperations()
|
|
45
|
+
{
|
|
46
|
+
yield return new ValueOp<T>() { source = this, value = _value };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
protected override void SendOperation(IValueObserver<T> observer, ValueOp<T> operation)
|
|
50
|
+
=> observer.OnNext(operation.value);
|
|
51
|
+
|
|
52
|
+
public IDisposable Subscribe(IValueObserver observer, bool immediate = false, uint? priority = null)
|
|
53
|
+
=> Subscribe(new ValueObserver<T>(
|
|
54
|
+
onNext: x => observer.OnNext(x),
|
|
55
|
+
onDispose: observer.OnDispose,
|
|
56
|
+
onError: observer.OnError
|
|
57
|
+
), immediate, priority);
|
|
58
|
+
}
|
|
59
59
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
fileFormatVersion: 2
|
|
1
|
+
fileFormatVersion: 2
|
|
2
2
|
guid: dd9a80008bec9ae46b50b03a4fd34819
|
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
using System;
|
|
2
|
-
using System.Collections.Generic;
|
|
3
|
-
|
|
4
|
-
namespace ObserveThing
|
|
5
|
-
{
|
|
6
|
-
public class BatchObservable<T> : IInitializationOperationsProvider<BatchOp<T>>, IPendingObserver where T : IOperation
|
|
7
|
-
{
|
|
8
|
-
public bool immediate { get; } = false;
|
|
9
|
-
public uint priority { get; private set; }
|
|
10
|
-
public bool disposed { get; private set; }
|
|
11
|
-
|
|
12
|
-
private IObservable<T> _source;
|
|
13
|
-
private Observable<BatchOp<T>> _operand;
|
|
14
|
-
private IDisposable _subscriptions;
|
|
15
|
-
private bool _pending;
|
|
16
|
-
|
|
17
|
-
private List<T> _batchedOperations = new List<T>();
|
|
18
|
-
|
|
19
|
-
public BatchObservable(IObservable<T> source, Observable<BatchOp<T>> operand)
|
|
20
|
-
{
|
|
21
|
-
priority = source.context.AllocateObserverPriority();
|
|
22
|
-
|
|
23
|
-
_source = source;
|
|
24
|
-
_operand = operand;
|
|
25
|
-
|
|
26
|
-
_subscriptions = source.Subscribe(new Observer<T>(
|
|
27
|
-
onNext: HandleSourceOperation,
|
|
28
|
-
onError: operand.OnError,
|
|
29
|
-
onDispose: Dispose
|
|
30
|
-
), immediate: true);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
private void HandleSourceOperation(T operation)
|
|
34
|
-
{
|
|
35
|
-
_batchedOperations.Add(operation);
|
|
36
|
-
|
|
37
|
-
if (_pending)
|
|
38
|
-
return;
|
|
39
|
-
|
|
40
|
-
_pending = true;
|
|
41
|
-
_source.context.RegisterPendingObserver(this);
|
|
42
|
-
_source.context.NotifyPendingObserversIfNecessary();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
public IEnumerable<BatchOp<T>> GetInitializationOperations()
|
|
46
|
-
{
|
|
47
|
-
List<T> initOps = new List<T>();
|
|
48
|
-
var subscription = _source.Subscribe(new Observer<T>(x => initOps.Add(x)));
|
|
49
|
-
subscription.Dispose();
|
|
50
|
-
yield return new BatchOp<T>() { source = _source, operations = initOps };
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public void SendNext()
|
|
54
|
-
{
|
|
55
|
-
_pending = false;
|
|
56
|
-
|
|
57
|
-
var batch = _batchedOperations.ToArray();
|
|
58
|
-
_batchedOperations.Clear();
|
|
59
|
-
|
|
60
|
-
_operand.EnqueueOperation(new BatchOp<T>() { source = _source, operations = batch });
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public void Dispose()
|
|
64
|
-
{
|
|
65
|
-
disposed = true;
|
|
66
|
-
_source.context.DeallocateObserverPriority(priority);
|
|
67
|
-
_subscriptions?.Dispose();
|
|
68
|
-
_subscriptions = null;
|
|
69
|
-
_operand.Dispose();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
|
|
4
|
+
namespace ObserveThing
|
|
5
|
+
{
|
|
6
|
+
public class BatchObservable<T> : IInitializationOperationsProvider<BatchOp<T>>, IPendingObserver where T : IOperation
|
|
7
|
+
{
|
|
8
|
+
public bool immediate { get; } = false;
|
|
9
|
+
public uint priority { get; private set; }
|
|
10
|
+
public bool disposed { get; private set; }
|
|
11
|
+
|
|
12
|
+
private IObservable<T> _source;
|
|
13
|
+
private Observable<BatchOp<T>> _operand;
|
|
14
|
+
private IDisposable _subscriptions;
|
|
15
|
+
private bool _pending;
|
|
16
|
+
|
|
17
|
+
private List<T> _batchedOperations = new List<T>();
|
|
18
|
+
|
|
19
|
+
public BatchObservable(IObservable<T> source, Observable<BatchOp<T>> operand)
|
|
20
|
+
{
|
|
21
|
+
priority = source.context.AllocateObserverPriority();
|
|
22
|
+
|
|
23
|
+
_source = source;
|
|
24
|
+
_operand = operand;
|
|
25
|
+
|
|
26
|
+
_subscriptions = source.Subscribe(new Observer<T>(
|
|
27
|
+
onNext: HandleSourceOperation,
|
|
28
|
+
onError: operand.OnError,
|
|
29
|
+
onDispose: Dispose
|
|
30
|
+
), immediate: true);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private void HandleSourceOperation(T operation)
|
|
34
|
+
{
|
|
35
|
+
_batchedOperations.Add(operation);
|
|
36
|
+
|
|
37
|
+
if (_pending)
|
|
38
|
+
return;
|
|
39
|
+
|
|
40
|
+
_pending = true;
|
|
41
|
+
_source.context.RegisterPendingObserver(this);
|
|
42
|
+
_source.context.NotifyPendingObserversIfNecessary();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public IEnumerable<BatchOp<T>> GetInitializationOperations()
|
|
46
|
+
{
|
|
47
|
+
List<T> initOps = new List<T>();
|
|
48
|
+
var subscription = _source.Subscribe(new Observer<T>(x => initOps.Add(x)));
|
|
49
|
+
subscription.Dispose();
|
|
50
|
+
yield return new BatchOp<T>() { source = _source, operations = initOps };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public void SendNext()
|
|
54
|
+
{
|
|
55
|
+
_pending = false;
|
|
56
|
+
|
|
57
|
+
var batch = _batchedOperations.ToArray();
|
|
58
|
+
_batchedOperations.Clear();
|
|
59
|
+
|
|
60
|
+
_operand.EnqueueOperation(new BatchOp<T>() { source = _source, operations = batch });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public void Dispose()
|
|
64
|
+
{
|
|
65
|
+
disposed = true;
|
|
66
|
+
_source.context.DeallocateObserverPriority(priority);
|
|
67
|
+
_subscriptions?.Dispose();
|
|
68
|
+
_subscriptions = null;
|
|
69
|
+
_operand.Dispose();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
72
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
fileFormatVersion: 2
|
|
1
|
+
fileFormatVersion: 2
|
|
2
2
|
guid: d36db333036392248810c9ce317875ec
|