com.fofx.observething 1.0.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 +2 -0
- package/README.md.meta +7 -0
- package/Runtime/CollectionIdProvider.cs +72 -0
- package/Runtime/CollectionIdProvider.cs.meta +2 -0
- package/Runtime/IObservable.cs +66 -0
- package/Runtime/IObservable.cs.meta +2 -0
- package/Runtime/Implementations/Observable.cs +30 -0
- package/Runtime/Implementations/Observable.cs.meta +2 -0
- package/Runtime/Implementations/ObservableBase.cs +173 -0
- package/Runtime/Implementations/ObservableBase.cs.meta +2 -0
- package/Runtime/Implementations/ObservableCollection.cs +141 -0
- package/Runtime/Implementations/ObservableCollection.cs.meta +2 -0
- package/Runtime/Implementations/ObservableDictionary.cs +166 -0
- package/Runtime/Implementations/ObservableDictionary.cs.meta +2 -0
- package/Runtime/Implementations/ObservableList.cs +163 -0
- package/Runtime/Implementations/ObservableList.cs.meta +2 -0
- package/Runtime/Implementations/ObservableSet.cs +137 -0
- package/Runtime/Implementations/ObservableSet.cs.meta +2 -0
- package/Runtime/Implementations/ObservableValue.cs +59 -0
- package/Runtime/Implementations/ObservableValue.cs.meta +2 -0
- package/Runtime/Implementations.meta +8 -0
- package/Runtime/Observables/BatchObservable.cs +72 -0
- package/Runtime/Observables/BatchObservable.cs.meta +2 -0
- package/Runtime/Observables/CastObservable.cs +128 -0
- package/Runtime/Observables/CastObservable.cs.meta +2 -0
- package/Runtime/Observables/CombineObservable.cs +96 -0
- package/Runtime/Observables/CombineObservable.cs.meta +2 -0
- package/Runtime/Observables/CombineValueObservable.cs +319 -0
- package/Runtime/Observables/CombineValueObservable.cs.meta +2 -0
- package/Runtime/Observables/ConcatObservable.cs +75 -0
- package/Runtime/Observables/ConcatObservable.cs.meta +2 -0
- package/Runtime/Observables/ContainsObservable.cs +71 -0
- package/Runtime/Observables/ContainsObservable.cs.meta +2 -0
- package/Runtime/Observables/CountObservable.cs +29 -0
- package/Runtime/Observables/CountObservable.cs.meta +2 -0
- package/Runtime/Observables/DistinctObservable.cs +55 -0
- package/Runtime/Observables/DistinctObservable.cs.meta +2 -0
- package/Runtime/Observables/FirstObservable.cs +53 -0
- package/Runtime/Observables/FirstObservable.cs.meta +2 -0
- package/Runtime/Observables/IndexOfObservable.cs +83 -0
- package/Runtime/Observables/IndexOfObservable.cs.meta +2 -0
- package/Runtime/Observables/OperationStreamObservable.cs +194 -0
- package/Runtime/Observables/OperationStreamObservable.cs.meta +2 -0
- package/Runtime/Observables/OrderByObservable.cs +116 -0
- package/Runtime/Observables/OrderByObservable.cs.meta +2 -0
- package/Runtime/Observables/SelectCollectionObservable.cs +29 -0
- package/Runtime/Observables/SelectCollectionObservable.cs.meta +2 -0
- package/Runtime/Observables/SelectListObservable.cs +29 -0
- package/Runtime/Observables/SelectListObservable.cs.meta +2 -0
- package/Runtime/Observables/SelectManyObservable.cs +78 -0
- package/Runtime/Observables/SelectManyObservable.cs.meta +2 -0
- package/Runtime/Observables/SelectValueObservable.cs +28 -0
- package/Runtime/Observables/SelectValueObservable.cs.meta +2 -0
- package/Runtime/Observables/SkipWhileObservable.cs +32 -0
- package/Runtime/Observables/SkipWhileObservable.cs.meta +2 -0
- package/Runtime/Observables/ThenObservable.cs +209 -0
- package/Runtime/Observables/ThenObservable.cs.meta +2 -0
- package/Runtime/Observables/ToDictionaryObservable.cs +35 -0
- package/Runtime/Observables/ToDictionaryObservable.cs.meta +2 -0
- package/Runtime/Observables/TrackObservable.cs +74 -0
- package/Runtime/Observables/TrackObservable.cs.meta +2 -0
- package/Runtime/Observables/UnwrapCollectionObservable.cs +64 -0
- package/Runtime/Observables/UnwrapCollectionObservable.cs.meta +2 -0
- package/Runtime/Observables/UnwrapListObservable.cs +69 -0
- package/Runtime/Observables/UnwrapListObservable.cs.meta +2 -0
- package/Runtime/Observables/UnwrapValueObservable.cs +56 -0
- package/Runtime/Observables/UnwrapValueObservable.cs.meta +2 -0
- package/Runtime/Observables/WhereObservable.cs +85 -0
- package/Runtime/Observables/WhereObservable.cs.meta +2 -0
- package/Runtime/Observables/WithPreviousObservable.cs +36 -0
- package/Runtime/Observables/WithPreviousObservable.cs.meta +2 -0
- package/Runtime/Observables.cs +467 -0
- package/Runtime/Observables.cs.meta +2 -0
- package/Runtime/Observables.meta +8 -0
- package/Runtime/ObservationContext.cs +126 -0
- package/Runtime/ObservationContext.cs.meta +2 -0
- package/Runtime/Observers.cs +403 -0
- package/Runtime/Observers.cs.meta +2 -0
- package/Runtime/Operators/BatchOperator.cs +71 -0
- package/Runtime/Operators/BatchOperator.cs.meta +2 -0
- package/Runtime/Operators/CollectionOperator.cs +30 -0
- package/Runtime/Operators/CollectionOperator.cs.meta +2 -0
- package/Runtime/Operators/DictionaryOperator.cs +45 -0
- package/Runtime/Operators/DictionaryOperator.cs.meta +2 -0
- package/Runtime/Operators/IInitializationOperationsProvider.cs +10 -0
- package/Runtime/Operators/IInitializationOperationsProvider.cs.meta +2 -0
- package/Runtime/Operators/ListOperator.cs +44 -0
- package/Runtime/Operators/ListOperator.cs.meta +2 -0
- package/Runtime/Operators/ObservableOperator.cs +75 -0
- package/Runtime/Operators/ObservableOperator.cs.meta +2 -0
- package/Runtime/Operators/Operator.cs +65 -0
- package/Runtime/Operators/Operator.cs.meta +2 -0
- package/Runtime/Operators/SetOperator.cs +44 -0
- package/Runtime/Operators/SetOperator.cs.meta +2 -0
- package/Runtime/Operators/ValueOperator.cs +30 -0
- package/Runtime/Operators/ValueOperator.cs.meta +2 -0
- package/Runtime/Operators.meta +8 -0
- package/Runtime/PriorityQueue.cs +1096 -0
- package/Runtime/PriorityQueue.cs.meta +2 -0
- package/Runtime/com.fofx.observething.asmdef +14 -0
- package/Runtime/com.fofx.observething.asmdef.meta +7 -0
- package/Runtime.meta +8 -0
- package/Tests/CollectionObservableTests.cs +739 -0
- package/Tests/CollectionObservableTests.cs.meta +2 -0
- package/Tests/DictionaryObservableTests.cs +85 -0
- package/Tests/DictionaryObservableTests.cs.meta +2 -0
- package/Tests/ListObservableTests.cs +148 -0
- package/Tests/ListObservableTests.cs.meta +2 -0
- package/Tests/ObservationContextTests.cs +359 -0
- package/Tests/ObservationContextTests.cs.meta +2 -0
- package/Tests/ValueObservableTests.cs +322 -0
- package/Tests/ValueObservableTests.cs.meta +2 -0
- package/Tests/com.fofx.observething.tests.asmdef +24 -0
- package/Tests/com.fofx.observething.tests.asmdef.meta +7 -0
- package/Tests.meta +8 -0
- package/package.json +24 -0
- package/package.json.meta +7 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
|
|
3
|
+
namespace ObserveThing
|
|
4
|
+
{
|
|
5
|
+
public class ThenValueObservable<T> : IDisposable
|
|
6
|
+
{
|
|
7
|
+
private IValueObservable<T> _source;
|
|
8
|
+
private IValueObserver<T> _then;
|
|
9
|
+
private ObservableValue<T> _operand;
|
|
10
|
+
private IDisposable _subscriptions;
|
|
11
|
+
|
|
12
|
+
public ThenValueObservable(IValueObservable<T> source, IValueObserver<T> then, ObservableValue<T> operand)
|
|
13
|
+
{
|
|
14
|
+
_source = source;
|
|
15
|
+
_then = then;
|
|
16
|
+
_operand = operand;
|
|
17
|
+
_subscriptions = _source.Subscribe(
|
|
18
|
+
onNext: x =>
|
|
19
|
+
{
|
|
20
|
+
_then.OnNext(x);
|
|
21
|
+
_operand.value = x;
|
|
22
|
+
},
|
|
23
|
+
onError: exc =>
|
|
24
|
+
{
|
|
25
|
+
_then.OnError(exc);
|
|
26
|
+
_operand.OnError(exc);
|
|
27
|
+
},
|
|
28
|
+
onDispose: Dispose
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public void Dispose()
|
|
33
|
+
{
|
|
34
|
+
_subscriptions?.Dispose();
|
|
35
|
+
_subscriptions = null;
|
|
36
|
+
|
|
37
|
+
_then.OnDispose();
|
|
38
|
+
_operand.Dispose();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public class ThenCollectionObservable<T> : IDisposable
|
|
43
|
+
{
|
|
44
|
+
private ICollectionObservable<T> _source;
|
|
45
|
+
private ICollectionObserver<T> _then;
|
|
46
|
+
private ObservableCollection<T> _operand;
|
|
47
|
+
private IDisposable _subscriptions;
|
|
48
|
+
|
|
49
|
+
public ThenCollectionObservable(ICollectionObservable<T> source, ICollectionObserver<T> then, ObservableCollection<T> operand)
|
|
50
|
+
{
|
|
51
|
+
_source = source;
|
|
52
|
+
_then = then;
|
|
53
|
+
_operand = operand;
|
|
54
|
+
_subscriptions = _source.SubscribeWithId(
|
|
55
|
+
onAdd: (id, element) =>
|
|
56
|
+
{
|
|
57
|
+
then.OnAdd(id, element);
|
|
58
|
+
operand.Add(id, element);
|
|
59
|
+
},
|
|
60
|
+
onRemove: (id, element) =>
|
|
61
|
+
{
|
|
62
|
+
then.OnRemove(id, element);
|
|
63
|
+
operand.Remove(id);
|
|
64
|
+
},
|
|
65
|
+
onError: exc =>
|
|
66
|
+
{
|
|
67
|
+
_then.OnError(exc);
|
|
68
|
+
_operand.OnError(exc);
|
|
69
|
+
},
|
|
70
|
+
onDispose: Dispose
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public void Dispose()
|
|
75
|
+
{
|
|
76
|
+
_subscriptions?.Dispose();
|
|
77
|
+
_subscriptions = null;
|
|
78
|
+
|
|
79
|
+
_then.OnDispose();
|
|
80
|
+
_operand.Dispose();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public class ThenListObservable<T> : IDisposable
|
|
85
|
+
{
|
|
86
|
+
private IListObservable<T> _source;
|
|
87
|
+
private IListObserver<T> _then;
|
|
88
|
+
private ObservableList<T> _operand;
|
|
89
|
+
private IDisposable _subscriptions;
|
|
90
|
+
|
|
91
|
+
public ThenListObservable(IListObservable<T> source, IListObserver<T> then, ObservableList<T> operand)
|
|
92
|
+
{
|
|
93
|
+
_source = source;
|
|
94
|
+
_then = then;
|
|
95
|
+
_operand = operand;
|
|
96
|
+
_subscriptions = _source.SubscribeWithId(
|
|
97
|
+
onAdd: (id, index, element) =>
|
|
98
|
+
{
|
|
99
|
+
then.OnAdd(id, index, element);
|
|
100
|
+
operand.Insert(index, element);
|
|
101
|
+
},
|
|
102
|
+
onRemove: (id, index, element) =>
|
|
103
|
+
{
|
|
104
|
+
then.OnRemove(id, index, element);
|
|
105
|
+
operand.RemoveAt(index);
|
|
106
|
+
},
|
|
107
|
+
onError: exc =>
|
|
108
|
+
{
|
|
109
|
+
_then.OnError(exc);
|
|
110
|
+
_operand.OnError(exc);
|
|
111
|
+
},
|
|
112
|
+
onDispose: Dispose
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public void Dispose()
|
|
117
|
+
{
|
|
118
|
+
_subscriptions?.Dispose();
|
|
119
|
+
_subscriptions = null;
|
|
120
|
+
|
|
121
|
+
_then.OnDispose();
|
|
122
|
+
_operand.Dispose();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public class ThenSetObservable<T> : IDisposable
|
|
127
|
+
{
|
|
128
|
+
private ISetObservable<T> _source;
|
|
129
|
+
private ISetObserver<T> _then;
|
|
130
|
+
private ObservableSet<T> _operand;
|
|
131
|
+
private IDisposable _subscriptions;
|
|
132
|
+
|
|
133
|
+
public ThenSetObservable(ISetObservable<T> source, ISetObserver<T> then, ObservableSet<T> operand)
|
|
134
|
+
{
|
|
135
|
+
_source = source;
|
|
136
|
+
_then = then;
|
|
137
|
+
_operand = operand;
|
|
138
|
+
_subscriptions = _source.SubscribeWithId(
|
|
139
|
+
onAdd: (id, element) =>
|
|
140
|
+
{
|
|
141
|
+
then.OnAdd(id, element);
|
|
142
|
+
operand.Add(element);
|
|
143
|
+
},
|
|
144
|
+
onRemove: (id, element) =>
|
|
145
|
+
{
|
|
146
|
+
then.OnRemove(id, element);
|
|
147
|
+
operand.Remove(element);
|
|
148
|
+
},
|
|
149
|
+
onError: exc =>
|
|
150
|
+
{
|
|
151
|
+
_then.OnError(exc);
|
|
152
|
+
_operand.OnError(exc);
|
|
153
|
+
},
|
|
154
|
+
onDispose: Dispose
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
public void Dispose()
|
|
159
|
+
{
|
|
160
|
+
_subscriptions?.Dispose();
|
|
161
|
+
_subscriptions = null;
|
|
162
|
+
|
|
163
|
+
_then.OnDispose();
|
|
164
|
+
_operand.Dispose();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
public class ThenDictionaryObservable<TKey, TValue> : IDisposable
|
|
169
|
+
{
|
|
170
|
+
private IDictionaryObservable<TKey, TValue> _source;
|
|
171
|
+
private IDictionaryObserver<TKey, TValue> _then;
|
|
172
|
+
private ObservableDictionary<TKey, TValue> _operand;
|
|
173
|
+
private IDisposable _subscriptions;
|
|
174
|
+
|
|
175
|
+
public ThenDictionaryObservable(IDictionaryObservable<TKey, TValue> source, IDictionaryObserver<TKey, TValue> then, ObservableDictionary<TKey, TValue> operand)
|
|
176
|
+
{
|
|
177
|
+
_source = source;
|
|
178
|
+
_then = then;
|
|
179
|
+
_operand = operand;
|
|
180
|
+
_subscriptions = _source.SubscribeWithId(
|
|
181
|
+
onAdd: (id, kvp) =>
|
|
182
|
+
{
|
|
183
|
+
then.OnAdd(id, kvp);
|
|
184
|
+
operand.Add(kvp.Key, kvp.Value);
|
|
185
|
+
},
|
|
186
|
+
onRemove: (id, kvp) =>
|
|
187
|
+
{
|
|
188
|
+
then.OnRemove(id, kvp);
|
|
189
|
+
operand.Remove(kvp.Key);
|
|
190
|
+
},
|
|
191
|
+
onError: exc =>
|
|
192
|
+
{
|
|
193
|
+
_then.OnError(exc);
|
|
194
|
+
_operand.OnError(exc);
|
|
195
|
+
},
|
|
196
|
+
onDispose: Dispose
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public void Dispose()
|
|
201
|
+
{
|
|
202
|
+
_subscriptions?.Dispose();
|
|
203
|
+
_subscriptions = null;
|
|
204
|
+
|
|
205
|
+
_then.OnDispose();
|
|
206
|
+
_operand.Dispose();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
|
|
4
|
+
namespace ObserveThing
|
|
5
|
+
{
|
|
6
|
+
public class ToDictionaryObservable<T, TKey, TValue> : IDisposable
|
|
7
|
+
{
|
|
8
|
+
private IDisposable _subscription;
|
|
9
|
+
private ObservableDictionary<TKey, TValue> _operand;
|
|
10
|
+
|
|
11
|
+
public ToDictionaryObservable(ICollectionObservable<T> source, Func<T, IValueObservable<TKey>> selectKey, Func<T, IValueObservable<TValue>> selectValue, ObservableDictionary<TKey, TValue> operand)
|
|
12
|
+
{
|
|
13
|
+
_operand = operand;
|
|
14
|
+
_subscription = source.ObservableSelect(
|
|
15
|
+
x => Observables.ObservableCombineValues(
|
|
16
|
+
selectKey(x),
|
|
17
|
+
selectValue(x),
|
|
18
|
+
(key, value) => new KeyValuePair<TKey, TValue>(key, value)
|
|
19
|
+
)
|
|
20
|
+
).Subscribe(
|
|
21
|
+
onAdd: kvp => _operand.Add(kvp.Key, kvp.Value),
|
|
22
|
+
onRemove: kvp => _operand.Remove(kvp.Key),
|
|
23
|
+
onError: operand.OnError,
|
|
24
|
+
onDispose: Dispose
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public void Dispose()
|
|
29
|
+
{
|
|
30
|
+
_subscription?.Dispose();
|
|
31
|
+
_subscription = null;
|
|
32
|
+
_operand.Dispose();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
|
|
4
|
+
namespace ObserveThing
|
|
5
|
+
{
|
|
6
|
+
public class TrackObservable<TKey, TValue> : IDisposable
|
|
7
|
+
{
|
|
8
|
+
private ObservableValue<(bool keyPresent, TValue value)> _operand;
|
|
9
|
+
private Dictionary<TKey, TValue> _dict = new Dictionary<TKey, TValue>();
|
|
10
|
+
private TKey _key = default;
|
|
11
|
+
private bool _present = false;
|
|
12
|
+
|
|
13
|
+
private IDisposable _subscriptions;
|
|
14
|
+
|
|
15
|
+
public TrackObservable(IDictionaryObservable<TKey, TValue> source, IValueObservable<TKey> key, ObservableValue<(bool keyPresent, TValue value)> operand)
|
|
16
|
+
{
|
|
17
|
+
_operand = operand;
|
|
18
|
+
_subscriptions = new ComposedDisposable(
|
|
19
|
+
|
|
20
|
+
source.Subscribe(
|
|
21
|
+
onAdd: kvp =>
|
|
22
|
+
{
|
|
23
|
+
_dict.Add(kvp.Key, kvp.Value);
|
|
24
|
+
if (Equals(kvp.Key, _key))
|
|
25
|
+
{
|
|
26
|
+
_present = true;
|
|
27
|
+
_operand.value = new(_present, kvp.Value);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
onRemove: kvp =>
|
|
31
|
+
{
|
|
32
|
+
if (_dict.Remove(kvp.Key) && Equals(kvp.Key, _key))
|
|
33
|
+
{
|
|
34
|
+
_present = false;
|
|
35
|
+
_operand.value = new(_present, default);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
onError: _operand.OnError,
|
|
39
|
+
onDispose: Dispose,
|
|
40
|
+
immediate: true
|
|
41
|
+
),
|
|
42
|
+
|
|
43
|
+
key.Subscribe(
|
|
44
|
+
onNext: key =>
|
|
45
|
+
{
|
|
46
|
+
_key = key;
|
|
47
|
+
|
|
48
|
+
if (_dict.TryGetValue(_key, out var value))
|
|
49
|
+
{
|
|
50
|
+
_present = true;
|
|
51
|
+
_operand.value = new(_present, value);
|
|
52
|
+
}
|
|
53
|
+
else
|
|
54
|
+
{
|
|
55
|
+
_present = false;
|
|
56
|
+
_operand.value = new(_present, default);
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
onError: _operand.OnError,
|
|
60
|
+
onDispose: Dispose,
|
|
61
|
+
immediate: true
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public void Dispose()
|
|
68
|
+
{
|
|
69
|
+
_subscriptions?.Dispose();
|
|
70
|
+
_subscriptions = null;
|
|
71
|
+
_operand.Dispose();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
|
|
4
|
+
namespace ObserveThing
|
|
5
|
+
{
|
|
6
|
+
public class UnwrapCollectionObservable<T> : IDisposable
|
|
7
|
+
{
|
|
8
|
+
private ObservableCollection<T> _operand;
|
|
9
|
+
private Dictionary<uint, EntryData> _dataById = new Dictionary<uint, EntryData>();
|
|
10
|
+
private IDisposable _subscriptions;
|
|
11
|
+
|
|
12
|
+
private class EntryData
|
|
13
|
+
{
|
|
14
|
+
public IDisposable subscription;
|
|
15
|
+
public bool initialized;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public UnwrapCollectionObservable(ICollectionObservable<IValueObservable<T>> source, ObservableCollection<T> operand)
|
|
19
|
+
{
|
|
20
|
+
_operand = operand;
|
|
21
|
+
_subscriptions = source.Subscribe(new CollectionObserver<IValueObservable<T>>(
|
|
22
|
+
onAdd: HandleAdd,
|
|
23
|
+
onRemove: HandleRemove,
|
|
24
|
+
onError: operand.OnError,
|
|
25
|
+
onDispose: Dispose
|
|
26
|
+
), immediate: true);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private void HandleAdd(uint id, IValueObservable<T> observable)
|
|
30
|
+
{
|
|
31
|
+
var data = new EntryData();
|
|
32
|
+
_dataById.Add(id, data);
|
|
33
|
+
data.subscription = observable.Subscribe(new ValueObserver<T>(
|
|
34
|
+
onNext: x =>
|
|
35
|
+
{
|
|
36
|
+
if (data.initialized)
|
|
37
|
+
_operand.Remove(id);
|
|
38
|
+
|
|
39
|
+
data.initialized = true;
|
|
40
|
+
_operand.Add(id, x);
|
|
41
|
+
},
|
|
42
|
+
onError: _operand.OnError
|
|
43
|
+
), immediate: true);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private void HandleRemove(uint id, IValueObservable<T> observable)
|
|
47
|
+
{
|
|
48
|
+
var data = _dataById[id];
|
|
49
|
+
_dataById.Remove(id);
|
|
50
|
+
data.subscription.Dispose();
|
|
51
|
+
_operand.Remove(id);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public void Dispose()
|
|
55
|
+
{
|
|
56
|
+
foreach (var data in _dataById.Values)
|
|
57
|
+
data.subscription.Dispose();
|
|
58
|
+
|
|
59
|
+
_subscriptions?.Dispose();
|
|
60
|
+
_subscriptions = null;
|
|
61
|
+
_operand.Dispose();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
|
|
4
|
+
namespace ObserveThing
|
|
5
|
+
{
|
|
6
|
+
public class UnwrapListObservable<T> : IDisposable
|
|
7
|
+
{
|
|
8
|
+
private ObservableList<T> _operand;
|
|
9
|
+
private List<EntryData> _data = new List<EntryData>();
|
|
10
|
+
private IDisposable _subscriptions;
|
|
11
|
+
|
|
12
|
+
private class EntryData
|
|
13
|
+
{
|
|
14
|
+
public IDisposable subscription;
|
|
15
|
+
public bool initialized;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public UnwrapListObservable(IListObservable<IValueObservable<T>> source, ObservableList<T> operand)
|
|
19
|
+
{
|
|
20
|
+
_operand = operand;
|
|
21
|
+
_subscriptions = source.Subscribe(
|
|
22
|
+
onAdd: HandleAdd,
|
|
23
|
+
onRemove: HandleRemove,
|
|
24
|
+
onError: _operand.OnError,
|
|
25
|
+
onDispose: Dispose,
|
|
26
|
+
immediate: true
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private void HandleAdd(int index, IValueObservable<T> element)
|
|
31
|
+
{
|
|
32
|
+
var data = new EntryData();
|
|
33
|
+
_data.Insert(index, data);
|
|
34
|
+
data.subscription = element.Subscribe(
|
|
35
|
+
onNext: x =>
|
|
36
|
+
{
|
|
37
|
+
var index = _data.IndexOf(data);
|
|
38
|
+
|
|
39
|
+
if (data.initialized)
|
|
40
|
+
_operand.RemoveAt(index);
|
|
41
|
+
|
|
42
|
+
data.initialized = true;
|
|
43
|
+
_operand.Insert(index, x);
|
|
44
|
+
},
|
|
45
|
+
onError: _operand.OnError,
|
|
46
|
+
immediate: true
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private void HandleRemove(int index, IValueObservable<T> element)
|
|
51
|
+
{
|
|
52
|
+
var data = _data[index];
|
|
53
|
+
_data.RemoveAt(index);
|
|
54
|
+
data.subscription.Dispose();
|
|
55
|
+
_operand.RemoveAt(index);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public void Dispose()
|
|
59
|
+
{
|
|
60
|
+
_subscriptions?.Dispose();
|
|
61
|
+
_subscriptions = null;
|
|
62
|
+
|
|
63
|
+
foreach (var data in _data)
|
|
64
|
+
data.subscription.Dispose();
|
|
65
|
+
|
|
66
|
+
_operand.Dispose();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
|
|
3
|
+
namespace ObserveThing
|
|
4
|
+
{
|
|
5
|
+
public class UnwrapValueObservable<T> : IDisposable
|
|
6
|
+
{
|
|
7
|
+
private ObservableValue<T> _operand;
|
|
8
|
+
private ValueObserver<T> _nestedObserver;
|
|
9
|
+
private IDisposable _nestedSubscription;
|
|
10
|
+
private IDisposable _subscriptions;
|
|
11
|
+
|
|
12
|
+
public UnwrapValueObservable(IValueObservable<IValueObservable<T>> source, ObservableValue<T> operand)
|
|
13
|
+
{
|
|
14
|
+
_operand = operand;
|
|
15
|
+
|
|
16
|
+
_nestedObserver = new ValueObserver<T>(
|
|
17
|
+
onNext: x => operand.value = x,
|
|
18
|
+
onError: operand.OnError
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
_subscriptions = source.Subscribe(
|
|
22
|
+
new ValueObserver<IValueObservable<T>>(
|
|
23
|
+
onNext: HandleNext,
|
|
24
|
+
onDispose: Dispose,
|
|
25
|
+
onError: operand.OnError
|
|
26
|
+
),
|
|
27
|
+
immediate: true
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private void HandleNext(IValueObservable<T> value)
|
|
32
|
+
{
|
|
33
|
+
_nestedSubscription?.Dispose();
|
|
34
|
+
_nestedSubscription = null;
|
|
35
|
+
|
|
36
|
+
if (value == null)
|
|
37
|
+
{
|
|
38
|
+
_operand.value = default;
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
_nestedSubscription = value.Subscribe(_nestedObserver, immediate: true);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public void Dispose()
|
|
46
|
+
{
|
|
47
|
+
_subscriptions?.Dispose();
|
|
48
|
+
_subscriptions = null;
|
|
49
|
+
|
|
50
|
+
_nestedSubscription?.Dispose();
|
|
51
|
+
_nestedSubscription = null;
|
|
52
|
+
|
|
53
|
+
_operand.Dispose();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
|
|
4
|
+
namespace ObserveThing
|
|
5
|
+
{
|
|
6
|
+
public class WhereObservable<T> : IDisposable
|
|
7
|
+
{
|
|
8
|
+
private ObservableCollection<T> _operand;
|
|
9
|
+
private Func<T, IValueObservable<bool>> _where;
|
|
10
|
+
private Dictionary<uint, EntryData> _dataById = new Dictionary<uint, EntryData>();
|
|
11
|
+
private IDisposable _subscriptions;
|
|
12
|
+
|
|
13
|
+
private class EntryData
|
|
14
|
+
{
|
|
15
|
+
public bool initialized;
|
|
16
|
+
public T value;
|
|
17
|
+
public bool included;
|
|
18
|
+
public IDisposable subscription;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public WhereObservable(ICollectionObservable<T> source, Func<T, IValueObservable<bool>> where, ObservableCollection<T> operand)
|
|
22
|
+
{
|
|
23
|
+
_operand = operand;
|
|
24
|
+
_where = where;
|
|
25
|
+
_subscriptions = source.SubscribeWithId(
|
|
26
|
+
onAdd: HandleAdd,
|
|
27
|
+
onRemove: HandleRemove,
|
|
28
|
+
onDispose: Dispose,
|
|
29
|
+
onError: _operand.OnError,
|
|
30
|
+
immediate: true
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private void HandleAdd(uint id, T value)
|
|
35
|
+
{
|
|
36
|
+
var data = new EntryData() { value = value };
|
|
37
|
+
_dataById.Add(id, data);
|
|
38
|
+
data.subscription = _where(value).Subscribe(
|
|
39
|
+
onNext: included =>
|
|
40
|
+
{
|
|
41
|
+
data.included = included;
|
|
42
|
+
|
|
43
|
+
if (!data.initialized)
|
|
44
|
+
{
|
|
45
|
+
data.initialized = true;
|
|
46
|
+
|
|
47
|
+
if (!included)
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (included)
|
|
52
|
+
{
|
|
53
|
+
_operand.Add(id, data.value);
|
|
54
|
+
}
|
|
55
|
+
else if (data.initialized)
|
|
56
|
+
{
|
|
57
|
+
_operand.Remove(id);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
onError: _operand.OnError,
|
|
61
|
+
immediate: true
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private void HandleRemove(uint id, T value)
|
|
66
|
+
{
|
|
67
|
+
var data = _dataById[id];
|
|
68
|
+
data.subscription.Dispose();
|
|
69
|
+
_dataById.Remove(id);
|
|
70
|
+
|
|
71
|
+
if (data.included)
|
|
72
|
+
_operand.Remove(id);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public void Dispose()
|
|
76
|
+
{
|
|
77
|
+
foreach (var data in _dataById.Values)
|
|
78
|
+
data.subscription.Dispose();
|
|
79
|
+
|
|
80
|
+
_subscriptions?.Dispose();
|
|
81
|
+
_subscriptions = null;
|
|
82
|
+
_operand.Dispose();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
|
|
3
|
+
namespace ObserveThing
|
|
4
|
+
{
|
|
5
|
+
public class WithPreviousObservable<T> : IDisposable
|
|
6
|
+
{
|
|
7
|
+
private ObservableValue<(T previous, T current)> _operand;
|
|
8
|
+
private T _previousValue;
|
|
9
|
+
private IDisposable _subscriptions;
|
|
10
|
+
|
|
11
|
+
public WithPreviousObservable(IValueObservable<T> source, ObservableValue<(T previous, T current)> operand)
|
|
12
|
+
{
|
|
13
|
+
_operand = operand;
|
|
14
|
+
_subscriptions = source.Subscribe(
|
|
15
|
+
onNext: HandleNext,
|
|
16
|
+
onError: _operand.OnError,
|
|
17
|
+
onDispose: Dispose,
|
|
18
|
+
immediate: true
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private void HandleNext(T value)
|
|
23
|
+
{
|
|
24
|
+
var pair = (value, _previousValue);
|
|
25
|
+
_previousValue = value;
|
|
26
|
+
_operand.value = pair;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public void Dispose()
|
|
30
|
+
{
|
|
31
|
+
_subscriptions?.Dispose();
|
|
32
|
+
_subscriptions = null;
|
|
33
|
+
_operand.Dispose();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|