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.
Files changed (117) hide show
  1. package/README.md +2 -0
  2. package/README.md.meta +7 -0
  3. package/Runtime/CollectionIdProvider.cs +72 -0
  4. package/Runtime/CollectionIdProvider.cs.meta +2 -0
  5. package/Runtime/IObservable.cs +66 -0
  6. package/Runtime/IObservable.cs.meta +2 -0
  7. package/Runtime/Implementations/Observable.cs +30 -0
  8. package/Runtime/Implementations/Observable.cs.meta +2 -0
  9. package/Runtime/Implementations/ObservableBase.cs +173 -0
  10. package/Runtime/Implementations/ObservableBase.cs.meta +2 -0
  11. package/Runtime/Implementations/ObservableCollection.cs +141 -0
  12. package/Runtime/Implementations/ObservableCollection.cs.meta +2 -0
  13. package/Runtime/Implementations/ObservableDictionary.cs +166 -0
  14. package/Runtime/Implementations/ObservableDictionary.cs.meta +2 -0
  15. package/Runtime/Implementations/ObservableList.cs +163 -0
  16. package/Runtime/Implementations/ObservableList.cs.meta +2 -0
  17. package/Runtime/Implementations/ObservableSet.cs +137 -0
  18. package/Runtime/Implementations/ObservableSet.cs.meta +2 -0
  19. package/Runtime/Implementations/ObservableValue.cs +59 -0
  20. package/Runtime/Implementations/ObservableValue.cs.meta +2 -0
  21. package/Runtime/Implementations.meta +8 -0
  22. package/Runtime/Observables/BatchObservable.cs +72 -0
  23. package/Runtime/Observables/BatchObservable.cs.meta +2 -0
  24. package/Runtime/Observables/CastObservable.cs +128 -0
  25. package/Runtime/Observables/CastObservable.cs.meta +2 -0
  26. package/Runtime/Observables/CombineObservable.cs +96 -0
  27. package/Runtime/Observables/CombineObservable.cs.meta +2 -0
  28. package/Runtime/Observables/CombineValueObservable.cs +319 -0
  29. package/Runtime/Observables/CombineValueObservable.cs.meta +2 -0
  30. package/Runtime/Observables/ConcatObservable.cs +75 -0
  31. package/Runtime/Observables/ConcatObservable.cs.meta +2 -0
  32. package/Runtime/Observables/ContainsObservable.cs +71 -0
  33. package/Runtime/Observables/ContainsObservable.cs.meta +2 -0
  34. package/Runtime/Observables/CountObservable.cs +29 -0
  35. package/Runtime/Observables/CountObservable.cs.meta +2 -0
  36. package/Runtime/Observables/DistinctObservable.cs +55 -0
  37. package/Runtime/Observables/DistinctObservable.cs.meta +2 -0
  38. package/Runtime/Observables/FirstObservable.cs +53 -0
  39. package/Runtime/Observables/FirstObservable.cs.meta +2 -0
  40. package/Runtime/Observables/IndexOfObservable.cs +83 -0
  41. package/Runtime/Observables/IndexOfObservable.cs.meta +2 -0
  42. package/Runtime/Observables/OperationStreamObservable.cs +194 -0
  43. package/Runtime/Observables/OperationStreamObservable.cs.meta +2 -0
  44. package/Runtime/Observables/OrderByObservable.cs +116 -0
  45. package/Runtime/Observables/OrderByObservable.cs.meta +2 -0
  46. package/Runtime/Observables/SelectCollectionObservable.cs +29 -0
  47. package/Runtime/Observables/SelectCollectionObservable.cs.meta +2 -0
  48. package/Runtime/Observables/SelectListObservable.cs +29 -0
  49. package/Runtime/Observables/SelectListObservable.cs.meta +2 -0
  50. package/Runtime/Observables/SelectManyObservable.cs +78 -0
  51. package/Runtime/Observables/SelectManyObservable.cs.meta +2 -0
  52. package/Runtime/Observables/SelectValueObservable.cs +28 -0
  53. package/Runtime/Observables/SelectValueObservable.cs.meta +2 -0
  54. package/Runtime/Observables/SkipWhileObservable.cs +32 -0
  55. package/Runtime/Observables/SkipWhileObservable.cs.meta +2 -0
  56. package/Runtime/Observables/ThenObservable.cs +209 -0
  57. package/Runtime/Observables/ThenObservable.cs.meta +2 -0
  58. package/Runtime/Observables/ToDictionaryObservable.cs +35 -0
  59. package/Runtime/Observables/ToDictionaryObservable.cs.meta +2 -0
  60. package/Runtime/Observables/TrackObservable.cs +74 -0
  61. package/Runtime/Observables/TrackObservable.cs.meta +2 -0
  62. package/Runtime/Observables/UnwrapCollectionObservable.cs +64 -0
  63. package/Runtime/Observables/UnwrapCollectionObservable.cs.meta +2 -0
  64. package/Runtime/Observables/UnwrapListObservable.cs +69 -0
  65. package/Runtime/Observables/UnwrapListObservable.cs.meta +2 -0
  66. package/Runtime/Observables/UnwrapValueObservable.cs +56 -0
  67. package/Runtime/Observables/UnwrapValueObservable.cs.meta +2 -0
  68. package/Runtime/Observables/WhereObservable.cs +85 -0
  69. package/Runtime/Observables/WhereObservable.cs.meta +2 -0
  70. package/Runtime/Observables/WithPreviousObservable.cs +36 -0
  71. package/Runtime/Observables/WithPreviousObservable.cs.meta +2 -0
  72. package/Runtime/Observables.cs +467 -0
  73. package/Runtime/Observables.cs.meta +2 -0
  74. package/Runtime/Observables.meta +8 -0
  75. package/Runtime/ObservationContext.cs +126 -0
  76. package/Runtime/ObservationContext.cs.meta +2 -0
  77. package/Runtime/Observers.cs +403 -0
  78. package/Runtime/Observers.cs.meta +2 -0
  79. package/Runtime/Operators/BatchOperator.cs +71 -0
  80. package/Runtime/Operators/BatchOperator.cs.meta +2 -0
  81. package/Runtime/Operators/CollectionOperator.cs +30 -0
  82. package/Runtime/Operators/CollectionOperator.cs.meta +2 -0
  83. package/Runtime/Operators/DictionaryOperator.cs +45 -0
  84. package/Runtime/Operators/DictionaryOperator.cs.meta +2 -0
  85. package/Runtime/Operators/IInitializationOperationsProvider.cs +10 -0
  86. package/Runtime/Operators/IInitializationOperationsProvider.cs.meta +2 -0
  87. package/Runtime/Operators/ListOperator.cs +44 -0
  88. package/Runtime/Operators/ListOperator.cs.meta +2 -0
  89. package/Runtime/Operators/ObservableOperator.cs +75 -0
  90. package/Runtime/Operators/ObservableOperator.cs.meta +2 -0
  91. package/Runtime/Operators/Operator.cs +65 -0
  92. package/Runtime/Operators/Operator.cs.meta +2 -0
  93. package/Runtime/Operators/SetOperator.cs +44 -0
  94. package/Runtime/Operators/SetOperator.cs.meta +2 -0
  95. package/Runtime/Operators/ValueOperator.cs +30 -0
  96. package/Runtime/Operators/ValueOperator.cs.meta +2 -0
  97. package/Runtime/Operators.meta +8 -0
  98. package/Runtime/PriorityQueue.cs +1096 -0
  99. package/Runtime/PriorityQueue.cs.meta +2 -0
  100. package/Runtime/com.fofx.observething.asmdef +14 -0
  101. package/Runtime/com.fofx.observething.asmdef.meta +7 -0
  102. package/Runtime.meta +8 -0
  103. package/Tests/CollectionObservableTests.cs +739 -0
  104. package/Tests/CollectionObservableTests.cs.meta +2 -0
  105. package/Tests/DictionaryObservableTests.cs +85 -0
  106. package/Tests/DictionaryObservableTests.cs.meta +2 -0
  107. package/Tests/ListObservableTests.cs +148 -0
  108. package/Tests/ListObservableTests.cs.meta +2 -0
  109. package/Tests/ObservationContextTests.cs +359 -0
  110. package/Tests/ObservationContextTests.cs.meta +2 -0
  111. package/Tests/ValueObservableTests.cs +322 -0
  112. package/Tests/ValueObservableTests.cs.meta +2 -0
  113. package/Tests/com.fofx.observething.tests.asmdef +24 -0
  114. package/Tests/com.fofx.observething.tests.asmdef.meta +7 -0
  115. package/Tests.meta +8 -0
  116. package/package.json +24 -0
  117. 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,2 @@
1
+ fileFormatVersion: 2
2
+ guid: fbbca2a10a02b2041aa62844d22b2b96
@@ -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,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 684b042b1e76a7342b93df51ad9c7e49
@@ -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,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 784847fbcbcf661478ba0c44c0fa1e72
@@ -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,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 3cb20673244d7db458b38ce9ad8f342c
@@ -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,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 593009250a2863d479f8ea8a62598f91
@@ -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,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 70a4ad018a097bf4494e0ae83c700b8d
@@ -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,2 @@
1
+ fileFormatVersion: 2
2
+ guid: b4cecb9a6846d0f4dac20d79da9d8294
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 899825cfd315d304f8ac10fcd96ff36a