refactor RxMap and RxList to completely remove the need to use value
Showing
12 changed files
with
620 additions
and
434 deletions
@@ -73,7 +73,7 @@ packages: | @@ -73,7 +73,7 @@ packages: | ||
73 | path: ".." | 73 | path: ".." |
74 | relative: true | 74 | relative: true |
75 | source: path | 75 | source: path |
76 | - version: "3.5.1" | 76 | + version: "3.6.0" |
77 | http_parser: | 77 | http_parser: |
78 | dependency: transitive | 78 | dependency: transitive |
79 | description: | 79 | description: |
1 | import 'dart:async'; | 1 | import 'dart:async'; |
2 | import 'dart:collection'; | 2 | import 'dart:collection'; |
3 | - | ||
4 | import 'rx_interface.dart'; | 3 | import 'rx_interface.dart'; |
5 | 4 | ||
6 | RxInterface getObs; | 5 | RxInterface getObs; |
7 | 6 | ||
8 | -typedef bool Condition(); | ||
9 | - | ||
10 | class _RxImpl<T> implements RxInterface<T> { | 7 | class _RxImpl<T> implements RxInterface<T> { |
11 | StreamController<T> subject = StreamController<T>.broadcast(); | 8 | StreamController<T> subject = StreamController<T>.broadcast(); |
12 | HashMap<Stream<T>, StreamSubscription> _subscriptions = | 9 | HashMap<Stream<T>, StreamSubscription> _subscriptions = |
@@ -159,374 +156,6 @@ class _RxImpl<T> implements RxInterface<T> { | @@ -159,374 +156,6 @@ class _RxImpl<T> implements RxInterface<T> { | ||
159 | Stream<R> map<R>(R mapper(T data)) => stream.map(mapper); | 156 | Stream<R> map<R>(R mapper(T data)) => stream.map(mapper); |
160 | } | 157 | } |
161 | 158 | ||
162 | -class RxMap<K, V> extends RxInterface<Map<K, V>> implements Map<K, V> { | ||
163 | - RxMap([Map<K, V> initial]) { | ||
164 | - _value = initial; | ||
165 | - } | ||
166 | - | ||
167 | - @override | ||
168 | - StreamController<Map<K, V>> subject = StreamController<Map<K, V>>.broadcast(); | ||
169 | - final Map<Stream<Map<K, V>>, StreamSubscription> _subscriptions = {}; | ||
170 | - | ||
171 | - Map<K, V> _value; | ||
172 | - Map<K, V> get value { | ||
173 | - if (getObs != null) { | ||
174 | - getObs.addListener(subject.stream); | ||
175 | - } | ||
176 | - return _value; | ||
177 | - } | ||
178 | - | ||
179 | - String get string => value.toString(); | ||
180 | - | ||
181 | - bool get canUpdate { | ||
182 | - return _subscriptions.length > 0; | ||
183 | - } | ||
184 | - | ||
185 | - @override | ||
186 | - void close() { | ||
187 | - _subscriptions.forEach((observable, subscription) { | ||
188 | - subscription.cancel(); | ||
189 | - }); | ||
190 | - _subscriptions.clear(); | ||
191 | - subject.close(); | ||
192 | - } | ||
193 | - | ||
194 | - @override | ||
195 | - void addListener(Stream rxGetx) { | ||
196 | - if (_subscriptions.containsKey(rxGetx)) { | ||
197 | - return; | ||
198 | - } | ||
199 | - _subscriptions[rxGetx] = rxGetx.listen((data) { | ||
200 | - subject.add(data); | ||
201 | - }); | ||
202 | - } | ||
203 | - | ||
204 | - set value(Map<K, V> val) { | ||
205 | - if (_value == val) return; | ||
206 | - _value = val; | ||
207 | - subject.add(_value); | ||
208 | - } | ||
209 | - | ||
210 | - Stream<Map<K, V>> get stream => subject.stream; | ||
211 | - | ||
212 | - StreamSubscription<Map<K, V>> listen(void Function(Map<K, V>) onData, | ||
213 | - {Function onError, void Function() onDone, bool cancelOnError}) => | ||
214 | - stream.listen(onData, onError: onError, onDone: onDone); | ||
215 | - | ||
216 | - void bindStream(Stream<Map<K, V>> stream) => | ||
217 | - stream.listen((va) => value = va); | ||
218 | - | ||
219 | - void add(K key, V value) { | ||
220 | - _value[key] = value; | ||
221 | - subject.add(_value); | ||
222 | - } | ||
223 | - | ||
224 | - void addIf(condition, K key, V value) { | ||
225 | - if (condition is Condition) condition = condition(); | ||
226 | - if (condition is bool && condition) { | ||
227 | - _value[key] = value; | ||
228 | - subject.add(_value); | ||
229 | - } | ||
230 | - } | ||
231 | - | ||
232 | - void addAllIf(condition, Map<K, V> values) { | ||
233 | - if (condition is Condition) condition = condition(); | ||
234 | - if (condition is bool && condition) addAll(values); | ||
235 | - } | ||
236 | - | ||
237 | - @override | ||
238 | - V operator [](Object key) { | ||
239 | - return value[key]; | ||
240 | - } | ||
241 | - | ||
242 | - @override | ||
243 | - void operator []=(K key, V value) { | ||
244 | - _value[key] = value; | ||
245 | - subject.add(_value); | ||
246 | - } | ||
247 | - | ||
248 | - @override | ||
249 | - void addAll(Map<K, V> other) { | ||
250 | - _value.addAll(other); | ||
251 | - subject.add(_value); | ||
252 | - } | ||
253 | - | ||
254 | - @override | ||
255 | - void addEntries(Iterable<MapEntry<K, V>> entries) { | ||
256 | - _value.addEntries(entries); | ||
257 | - subject.add(_value); | ||
258 | - } | ||
259 | - | ||
260 | - @override | ||
261 | - void clear() { | ||
262 | - _value.clear(); | ||
263 | - subject.add(_value); | ||
264 | - } | ||
265 | - | ||
266 | - @override | ||
267 | - Map<K2, V2> cast<K2, V2>() => _value.cast<K2, V2>(); | ||
268 | - | ||
269 | - @override | ||
270 | - bool containsKey(Object key) => _value.containsKey(key); | ||
271 | - | ||
272 | - @override | ||
273 | - bool containsValue(Object value) => _value.containsValue(value); | ||
274 | - | ||
275 | - @override | ||
276 | - Iterable<MapEntry<K, V>> get entries => _value.entries; | ||
277 | - | ||
278 | - @override | ||
279 | - void forEach(void Function(K, V) f) { | ||
280 | - _value.forEach(f); | ||
281 | - } | ||
282 | - | ||
283 | - @override | ||
284 | - bool get isEmpty => _value.isEmpty; | ||
285 | - | ||
286 | - @override | ||
287 | - bool get isNotEmpty => _value.isNotEmpty; | ||
288 | - | ||
289 | - @override | ||
290 | - Iterable<K> get keys => _value.keys; | ||
291 | - | ||
292 | - @override | ||
293 | - int get length => value.length; | ||
294 | - | ||
295 | - @override | ||
296 | - Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> Function(K, V) transform) => | ||
297 | - value.map(transform); | ||
298 | - | ||
299 | - @override | ||
300 | - V putIfAbsent(K key, V Function() ifAbsent) { | ||
301 | - final val = _value.putIfAbsent(key, ifAbsent); | ||
302 | - subject.add(_value); | ||
303 | - return val; | ||
304 | - } | ||
305 | - | ||
306 | - @override | ||
307 | - V remove(Object key) { | ||
308 | - final val = _value.remove(key); | ||
309 | - subject.add(_value); | ||
310 | - return val; | ||
311 | - } | ||
312 | - | ||
313 | - @override | ||
314 | - void removeWhere(bool Function(K, V) test) { | ||
315 | - _value.removeWhere(test); | ||
316 | - subject.add(_value); | ||
317 | - } | ||
318 | - | ||
319 | - @override | ||
320 | - Iterable<V> get values => value.values; | ||
321 | - | ||
322 | - @override | ||
323 | - String toString() => _value.toString(); | ||
324 | - | ||
325 | - @override | ||
326 | - V update(K key, V Function(V) update, {V Function() ifAbsent}) { | ||
327 | - final val = _value.update(key, update, ifAbsent: ifAbsent); | ||
328 | - subject.add(_value); | ||
329 | - return val; | ||
330 | - } | ||
331 | - | ||
332 | - @override | ||
333 | - void updateAll(V Function(K, V) update) { | ||
334 | - _value.updateAll(update); | ||
335 | - subject.add(_value); | ||
336 | - } | ||
337 | -} | ||
338 | - | ||
339 | -/// Create a list similar to `List<T>` | ||
340 | -class RxList<E> extends Iterable<E> implements RxInterface<List<E>> { | ||
341 | - RxList([List<E> initial]) { | ||
342 | - _list = initial; | ||
343 | - } | ||
344 | - | ||
345 | - @override | ||
346 | - Iterator<E> get iterator => _list.iterator; | ||
347 | - | ||
348 | - @override | ||
349 | - bool get isEmpty => value.isEmpty; | ||
350 | - | ||
351 | - bool get canUpdate { | ||
352 | - return _subscriptions.length > 0; | ||
353 | - } | ||
354 | - | ||
355 | - @override | ||
356 | - bool get isNotEmpty => value.isNotEmpty; | ||
357 | - | ||
358 | - StreamController<List<E>> subject = StreamController<List<E>>.broadcast(); | ||
359 | - Map<Stream<List<E>>, StreamSubscription> _subscriptions = Map(); | ||
360 | - | ||
361 | - /// Adds [item] only if [condition] resolves to true. | ||
362 | - void addIf(condition, E item) { | ||
363 | - if (condition is Condition) condition = condition(); | ||
364 | - if (condition is bool && condition) add(item); | ||
365 | - } | ||
366 | - | ||
367 | - /// Adds all [items] only if [condition] resolves to true. | ||
368 | - void addAllIf(condition, Iterable<E> items) { | ||
369 | - if (condition is Condition) condition = condition(); | ||
370 | - if (condition is bool && condition) addAll(items); | ||
371 | - } | ||
372 | - | ||
373 | - operator []=(int index, E val) { | ||
374 | - _list[index] = val; | ||
375 | - subject.add(_list); | ||
376 | - } | ||
377 | - | ||
378 | - /// Special override to push() element(s) in a reactive way | ||
379 | - /// inside the List, | ||
380 | - RxList<E> operator +(val) { | ||
381 | - if (val is Iterable) | ||
382 | - subject.add(_list..addAll(val)); | ||
383 | - else | ||
384 | - subject.add(_list..add(val)); | ||
385 | - return this; | ||
386 | - } | ||
387 | - | ||
388 | - E operator [](int index) { | ||
389 | - return value[index]; | ||
390 | - } | ||
391 | - | ||
392 | - void add(E item) { | ||
393 | - _list.add(item); | ||
394 | - subject.add(_list); | ||
395 | - } | ||
396 | - | ||
397 | - void addAll(Iterable<E> item) { | ||
398 | - _list.addAll(item); | ||
399 | - subject.add(_list); | ||
400 | - } | ||
401 | - | ||
402 | - /// Adds only if [item] is not null. | ||
403 | - void addNonNull(E item) { | ||
404 | - if (item != null) add(item); | ||
405 | - } | ||
406 | - | ||
407 | - /// Adds only if [item] is not null. | ||
408 | - void addAllNonNull(Iterable<E> item) { | ||
409 | - if (item != null) addAll(item); | ||
410 | - } | ||
411 | - | ||
412 | - void insert(int index, E item) { | ||
413 | - _list.insert(index, item); | ||
414 | - subject.add(_list); | ||
415 | - } | ||
416 | - | ||
417 | - void insertAll(int index, Iterable<E> iterable) { | ||
418 | - _list.insertAll(index, iterable); | ||
419 | - subject.add(_list); | ||
420 | - } | ||
421 | - | ||
422 | - int get length => value.length; | ||
423 | - | ||
424 | - /// Removes an item from the list. | ||
425 | - /// | ||
426 | - /// This is O(N) in the number of items in the list. | ||
427 | - /// | ||
428 | - /// Returns whether the item was present in the list. | ||
429 | - bool remove(Object item) { | ||
430 | - bool hasRemoved = _list.remove(item); | ||
431 | - if (hasRemoved) { | ||
432 | - subject.add(_list); | ||
433 | - } | ||
434 | - return hasRemoved; | ||
435 | - } | ||
436 | - | ||
437 | - E removeAt(int index) { | ||
438 | - E item = _list.removeAt(index); | ||
439 | - subject.add(_list); | ||
440 | - return item; | ||
441 | - } | ||
442 | - | ||
443 | - E removeLast() { | ||
444 | - E item = _list.removeLast(); | ||
445 | - subject.add(_list); | ||
446 | - return item; | ||
447 | - } | ||
448 | - | ||
449 | - void removeRange(int start, int end) { | ||
450 | - _list.removeRange(start, end); | ||
451 | - subject.add(_list); | ||
452 | - } | ||
453 | - | ||
454 | - void removeWhere(bool Function(E) test) { | ||
455 | - _list.removeWhere(test); | ||
456 | - subject.add(_list); | ||
457 | - } | ||
458 | - | ||
459 | - void clear() { | ||
460 | - _list.clear(); | ||
461 | - subject.add(_list); | ||
462 | - } | ||
463 | - | ||
464 | - void sort([int compare(E a, E b)]) { | ||
465 | - _list.sort(); | ||
466 | - subject.add(_list); | ||
467 | - } | ||
468 | - | ||
469 | - close() { | ||
470 | - _subscriptions.forEach((observable, subscription) { | ||
471 | - subscription.cancel(); | ||
472 | - }); | ||
473 | - _subscriptions.clear(); | ||
474 | - subject.close(); | ||
475 | - } | ||
476 | - | ||
477 | - /// Replaces all existing items of this list with [item] | ||
478 | - void assign(E item) { | ||
479 | - clear(); | ||
480 | - add(item); | ||
481 | - } | ||
482 | - | ||
483 | - void update(void fn(Iterable<E> value)) { | ||
484 | - fn(value); | ||
485 | - subject.add(_list); | ||
486 | - } | ||
487 | - | ||
488 | - /// Replaces all existing items of this list with [items] | ||
489 | - void assignAll(Iterable<E> items) { | ||
490 | - clear(); | ||
491 | - addAll(items); | ||
492 | - } | ||
493 | - | ||
494 | - List<E> get value { | ||
495 | - if (getObs != null) { | ||
496 | - getObs.addListener(subject.stream); | ||
497 | - } | ||
498 | - return _list; | ||
499 | - } | ||
500 | - | ||
501 | - String get string => value.toString(); | ||
502 | - | ||
503 | - addListener(Stream<List<E>> rxGetx) { | ||
504 | - if (_subscriptions.containsKey(rxGetx)) { | ||
505 | - return; | ||
506 | - } | ||
507 | - _subscriptions[rxGetx] = rxGetx.listen((data) { | ||
508 | - subject.add(data); | ||
509 | - }); | ||
510 | - } | ||
511 | - | ||
512 | - set value(Iterable<E> val) { | ||
513 | - if (_list == val) return; | ||
514 | - _list = val; | ||
515 | - subject.add(_list); | ||
516 | - } | ||
517 | - | ||
518 | - Stream<List<E>> get stream => subject.stream; | ||
519 | - | ||
520 | - StreamSubscription<List<E>> listen(void Function(List<E>) onData, | ||
521 | - {Function onError, void Function() onDone, bool cancelOnError}) => | ||
522 | - stream.listen(onData, onError: onError, onDone: onDone); | ||
523 | - | ||
524 | - void bindStream(Stream<Iterable<E>> stream) => | ||
525 | - stream.listen((va) => value = va); | ||
526 | - | ||
527 | - List<E> _list = <E>[]; | ||
528 | -} | ||
529 | - | ||
530 | class RxBool extends _RxImpl<bool> { | 159 | class RxBool extends _RxImpl<bool> { |
531 | RxBool([bool initial]) { | 160 | RxBool([bool initial]) { |
532 | _value = initial; | 161 | _value = initial; |
@@ -664,24 +293,6 @@ extension BoolExtension on bool { | @@ -664,24 +293,6 @@ extension BoolExtension on bool { | ||
664 | RxBool get obs => RxBool(this); | 293 | RxBool get obs => RxBool(this); |
665 | } | 294 | } |
666 | 295 | ||
667 | -extension MapExtension<K, V> on Map<K, V> { | ||
668 | - RxMap<K, V> get obs { | ||
669 | - if (this != null) | ||
670 | - return RxMap<K, V>(<K, V>{})..addAll(this); | ||
671 | - else | ||
672 | - return RxMap<K, V>(null); | ||
673 | - } | ||
674 | -} | ||
675 | - | ||
676 | -extension ListExtension<E> on List<E> { | ||
677 | - RxList<E> get obs { | ||
678 | - if (this != null) | ||
679 | - return RxList<E>(<E>[])..addAllNonNull(this); | ||
680 | - else | ||
681 | - return RxList<E>(null); | ||
682 | - } | ||
683 | -} | ||
684 | - | ||
685 | extension RxT<T> on T { | 296 | extension RxT<T> on T { |
686 | Rx<T> get obs => Rx<T>(this); | 297 | Rx<T> get obs => Rx<T>(this); |
687 | } | 298 | } |
lib/src/state_manager/rx/rx_list.dart
0 → 100644
1 | +import 'dart:async'; | ||
2 | +import 'dart:math'; | ||
3 | +import 'package:flutter/foundation.dart'; | ||
4 | + | ||
5 | +import 'rx_impl.dart'; | ||
6 | +import 'rx_interface.dart'; | ||
7 | +import 'rx_typedefs.dart'; | ||
8 | + | ||
9 | +/// Create a list similar to `List<T>` | ||
10 | +class RxList<E> implements List<E>, RxInterface<List<E>> { | ||
11 | + RxList([List<E> initial]) { | ||
12 | + _list = initial; | ||
13 | + } | ||
14 | + | ||
15 | + @override | ||
16 | + Iterator<E> get iterator => _list.iterator; | ||
17 | + | ||
18 | + @override | ||
19 | + bool get isEmpty => value.isEmpty; | ||
20 | + | ||
21 | + bool get canUpdate { | ||
22 | + return _subscriptions.length > 0; | ||
23 | + } | ||
24 | + | ||
25 | + @override | ||
26 | + bool get isNotEmpty => value.isNotEmpty; | ||
27 | + | ||
28 | + StreamController<List<E>> subject = StreamController<List<E>>.broadcast(); | ||
29 | + Map<Stream<List<E>>, StreamSubscription> _subscriptions = Map(); | ||
30 | + | ||
31 | + /// Adds [item] only if [condition] resolves to true. | ||
32 | + void addIf(condition, E item) { | ||
33 | + if (condition is Condition) condition = condition(); | ||
34 | + if (condition is bool && condition) add(item); | ||
35 | + } | ||
36 | + | ||
37 | + /// Adds all [items] only if [condition] resolves to true. | ||
38 | + void addAllIf(condition, Iterable<E> items) { | ||
39 | + if (condition is Condition) condition = condition(); | ||
40 | + if (condition is bool && condition) addAll(items); | ||
41 | + } | ||
42 | + | ||
43 | + operator []=(int index, E val) { | ||
44 | + _list[index] = val; | ||
45 | + subject.add(_list); | ||
46 | + } | ||
47 | + | ||
48 | + /// Special override to push() element(s) in a reactive way | ||
49 | + /// inside the List, | ||
50 | + RxList<E> operator +(Iterable<E> val) { | ||
51 | + addAll(val); | ||
52 | + subject.add(_list); | ||
53 | + return this; | ||
54 | + } | ||
55 | + | ||
56 | + E operator [](int index) { | ||
57 | + return value[index]; | ||
58 | + } | ||
59 | + | ||
60 | + void add(E item) { | ||
61 | + _list.add(item); | ||
62 | + subject.add(_list); | ||
63 | + } | ||
64 | + | ||
65 | + void addAll(Iterable<E> item) { | ||
66 | + _list.addAll(item); | ||
67 | + subject.add(_list); | ||
68 | + } | ||
69 | + | ||
70 | + /// Adds only if [item] is not null. | ||
71 | + void addNonNull(E item) { | ||
72 | + if (item != null) add(item); | ||
73 | + } | ||
74 | + | ||
75 | + /// Adds only if [item] is not null. | ||
76 | + void addAllNonNull(Iterable<E> item) { | ||
77 | + if (item != null) addAll(item); | ||
78 | + } | ||
79 | + | ||
80 | + void insert(int index, E item) { | ||
81 | + _list.insert(index, item); | ||
82 | + subject.add(_list); | ||
83 | + } | ||
84 | + | ||
85 | + void insertAll(int index, Iterable<E> iterable) { | ||
86 | + _list.insertAll(index, iterable); | ||
87 | + subject.add(_list); | ||
88 | + } | ||
89 | + | ||
90 | + int get length => value.length; | ||
91 | + | ||
92 | + /// Removes an item from the list. | ||
93 | + /// | ||
94 | + /// This is O(N) in the number of items in the list. | ||
95 | + /// | ||
96 | + /// Returns whether the item was present in the list. | ||
97 | + bool remove(Object item) { | ||
98 | + bool hasRemoved = _list.remove(item); | ||
99 | + if (hasRemoved) { | ||
100 | + subject.add(_list); | ||
101 | + } | ||
102 | + return hasRemoved; | ||
103 | + } | ||
104 | + | ||
105 | + E removeAt(int index) { | ||
106 | + E item = _list.removeAt(index); | ||
107 | + subject.add(_list); | ||
108 | + return item; | ||
109 | + } | ||
110 | + | ||
111 | + E removeLast() { | ||
112 | + E item = _list.removeLast(); | ||
113 | + subject.add(_list); | ||
114 | + return item; | ||
115 | + } | ||
116 | + | ||
117 | + void removeRange(int start, int end) { | ||
118 | + _list.removeRange(start, end); | ||
119 | + subject.add(_list); | ||
120 | + } | ||
121 | + | ||
122 | + void removeWhere(bool Function(E) test) { | ||
123 | + _list.removeWhere(test); | ||
124 | + subject.add(_list); | ||
125 | + } | ||
126 | + | ||
127 | + void clear() { | ||
128 | + _list.clear(); | ||
129 | + subject.add(_list); | ||
130 | + } | ||
131 | + | ||
132 | + void sort([int compare(E a, E b)]) { | ||
133 | + _list.sort(); | ||
134 | + subject.add(_list); | ||
135 | + } | ||
136 | + | ||
137 | + close() { | ||
138 | + _subscriptions.forEach((observable, subscription) { | ||
139 | + subscription.cancel(); | ||
140 | + }); | ||
141 | + _subscriptions.clear(); | ||
142 | + subject.close(); | ||
143 | + } | ||
144 | + | ||
145 | + /// Replaces all existing items of this list with [item] | ||
146 | + void assign(E item) { | ||
147 | + clear(); | ||
148 | + add(item); | ||
149 | + } | ||
150 | + | ||
151 | + void update(void fn(Iterable<E> value)) { | ||
152 | + fn(value); | ||
153 | + subject.add(_list); | ||
154 | + } | ||
155 | + | ||
156 | + /// Replaces all existing items of this list with [items] | ||
157 | + void assignAll(Iterable<E> items) { | ||
158 | + clear(); | ||
159 | + addAll(items); | ||
160 | + } | ||
161 | + | ||
162 | + @protected | ||
163 | + List<E> get value { | ||
164 | + if (getObs != null) { | ||
165 | + getObs.addListener(subject.stream); | ||
166 | + } | ||
167 | + return _list; | ||
168 | + } | ||
169 | + | ||
170 | + String get string => value.toString(); | ||
171 | + | ||
172 | + addListener(Stream<List<E>> rxGetx) { | ||
173 | + if (_subscriptions.containsKey(rxGetx)) { | ||
174 | + return; | ||
175 | + } | ||
176 | + _subscriptions[rxGetx] = rxGetx.listen((data) { | ||
177 | + subject.add(data); | ||
178 | + }); | ||
179 | + } | ||
180 | + | ||
181 | + set value(Iterable<E> val) { | ||
182 | + if (_list == val) return; | ||
183 | + _list = val; | ||
184 | + subject.add(_list); | ||
185 | + } | ||
186 | + | ||
187 | + Stream<List<E>> get stream => subject.stream; | ||
188 | + | ||
189 | + StreamSubscription<List<E>> listen(void Function(List<E>) onData, | ||
190 | + {Function onError, void Function() onDone, bool cancelOnError}) => | ||
191 | + stream.listen(onData, onError: onError, onDone: onDone); | ||
192 | + | ||
193 | + void bindStream(Stream<Iterable<E>> stream) => | ||
194 | + stream.listen((va) => value = va); | ||
195 | + | ||
196 | + List<E> _list = <E>[]; | ||
197 | + | ||
198 | + @override | ||
199 | + E get first => _list.first; | ||
200 | + | ||
201 | + @override | ||
202 | + E get last => _list.last; | ||
203 | + | ||
204 | + @override | ||
205 | + bool any(bool Function(E) test) { | ||
206 | + return _list.any(test); | ||
207 | + } | ||
208 | + | ||
209 | + @override | ||
210 | + Map<int, E> asMap() { | ||
211 | + return _list.asMap(); | ||
212 | + } | ||
213 | + | ||
214 | + @override | ||
215 | + List<R> cast<R>() { | ||
216 | + return _list.cast<R>(); | ||
217 | + } | ||
218 | + | ||
219 | + @override | ||
220 | + bool contains(Object element) { | ||
221 | + return _list.contains(element); | ||
222 | + } | ||
223 | + | ||
224 | + @override | ||
225 | + E elementAt(int index) { | ||
226 | + return _list.elementAt(index); | ||
227 | + } | ||
228 | + | ||
229 | + @override | ||
230 | + bool every(bool Function(E) test) { | ||
231 | + return _list.every(test); | ||
232 | + } | ||
233 | + | ||
234 | + @override | ||
235 | + Iterable<T> expand<T>(Iterable<T> Function(E) f) { | ||
236 | + return _list.expand(f); | ||
237 | + } | ||
238 | + | ||
239 | + @override | ||
240 | + void fillRange(int start, int end, [E fillValue]) { | ||
241 | + _list.fillRange(start, end, fillValue); | ||
242 | + } | ||
243 | + | ||
244 | + @override | ||
245 | + E firstWhere(bool Function(E) test, {E Function() orElse}) { | ||
246 | + return _list.firstWhere(test, orElse: orElse); | ||
247 | + } | ||
248 | + | ||
249 | + @override | ||
250 | + T fold<T>(T initialValue, T Function(T, E) combine) { | ||
251 | + return _list.fold(initialValue, combine); | ||
252 | + } | ||
253 | + | ||
254 | + @override | ||
255 | + Iterable<E> followedBy(Iterable<E> other) { | ||
256 | + return _list.followedBy(other); | ||
257 | + } | ||
258 | + | ||
259 | + @override | ||
260 | + void forEach(void Function(E) f) { | ||
261 | + _list.forEach(f); | ||
262 | + } | ||
263 | + | ||
264 | + @override | ||
265 | + Iterable<E> getRange(int start, int end) { | ||
266 | + return _list.getRange(start, end); | ||
267 | + } | ||
268 | + | ||
269 | + @override | ||
270 | + int indexOf(E element, [int start = 0]) { | ||
271 | + return _list.indexOf(element, start); | ||
272 | + } | ||
273 | + | ||
274 | + @override | ||
275 | + int indexWhere(bool Function(E) test, [int start = 0]) { | ||
276 | + return _list.indexWhere(test, start); | ||
277 | + } | ||
278 | + | ||
279 | + @override | ||
280 | + String join([String separator = ""]) { | ||
281 | + return _list.join(separator); | ||
282 | + } | ||
283 | + | ||
284 | + @override | ||
285 | + int lastIndexOf(E element, [int start]) { | ||
286 | + return _list.lastIndexOf(element, start); | ||
287 | + } | ||
288 | + | ||
289 | + @override | ||
290 | + int lastIndexWhere(bool Function(E) test, [int start]) { | ||
291 | + return _list.lastIndexWhere(test, start); | ||
292 | + } | ||
293 | + | ||
294 | + @override | ||
295 | + E lastWhere(bool Function(E) test, {E Function() orElse}) { | ||
296 | + return _list.lastWhere(test, orElse: orElse); | ||
297 | + } | ||
298 | + | ||
299 | + @override | ||
300 | + set length(int newLength) { | ||
301 | + _list.length = newLength; | ||
302 | + } | ||
303 | + | ||
304 | + @override | ||
305 | + Iterable<T> map<T>(T Function(E) f) { | ||
306 | + return _list.map(f); | ||
307 | + } | ||
308 | + | ||
309 | + @override | ||
310 | + E reduce(E Function(E, E) combine) { | ||
311 | + return _list.reduce(combine); | ||
312 | + } | ||
313 | + | ||
314 | + @override | ||
315 | + void replaceRange(int start, int end, Iterable<E> replacement) { | ||
316 | + _list.replaceRange(start, end, replacement); | ||
317 | + } | ||
318 | + | ||
319 | + @override | ||
320 | + void retainWhere(bool Function(E) test) { | ||
321 | + _list.retainWhere(test); | ||
322 | + } | ||
323 | + | ||
324 | + @override | ||
325 | + Iterable<E> get reversed => _list.reversed; | ||
326 | + | ||
327 | + @override | ||
328 | + void setAll(int index, Iterable<E> iterable) { | ||
329 | + _list.setAll(index, iterable); | ||
330 | + } | ||
331 | + | ||
332 | + @override | ||
333 | + void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) { | ||
334 | + _list.setRange(start, end, iterable, skipCount); | ||
335 | + } | ||
336 | + | ||
337 | + @override | ||
338 | + void shuffle([Random random]) { | ||
339 | + _list.shuffle(random); | ||
340 | + } | ||
341 | + | ||
342 | + @override | ||
343 | + E get single => _list.single; | ||
344 | + | ||
345 | + @override | ||
346 | + E singleWhere(bool Function(E) test, {E Function() orElse}) { | ||
347 | + return _list.singleWhere(test, orElse: orElse); | ||
348 | + } | ||
349 | + | ||
350 | + @override | ||
351 | + Iterable<E> skip(int count) { | ||
352 | + return _list.skip(count); | ||
353 | + } | ||
354 | + | ||
355 | + @override | ||
356 | + Iterable<E> skipWhile(bool Function(E) test) { | ||
357 | + return _list.skipWhile(test); | ||
358 | + } | ||
359 | + | ||
360 | + @override | ||
361 | + List<E> sublist(int start, [int end]) { | ||
362 | + return _list.sublist(start, end); | ||
363 | + } | ||
364 | + | ||
365 | + @override | ||
366 | + Iterable<E> take(int count) { | ||
367 | + return _list.take(count); | ||
368 | + } | ||
369 | + | ||
370 | + @override | ||
371 | + Iterable<E> takeWhile(bool Function(E) test) { | ||
372 | + return _list.takeWhile(test); | ||
373 | + } | ||
374 | + | ||
375 | + @override | ||
376 | + List<E> toList({bool growable = true}) { | ||
377 | + return _list.toList(growable: growable); | ||
378 | + } | ||
379 | + | ||
380 | + @override | ||
381 | + Set<E> toSet() { | ||
382 | + return _list.toSet(); | ||
383 | + } | ||
384 | + | ||
385 | + @override | ||
386 | + Iterable<E> where(bool Function(E) test) { | ||
387 | + return _list.where(test); | ||
388 | + } | ||
389 | + | ||
390 | + @override | ||
391 | + Iterable<T> whereType<T>() { | ||
392 | + return _list.whereType<T>(); | ||
393 | + } | ||
394 | + | ||
395 | + @override | ||
396 | + set first(E value) { | ||
397 | + _list.first = value; | ||
398 | + } | ||
399 | + | ||
400 | + @override | ||
401 | + set last(E value) { | ||
402 | + _list.last = value; | ||
403 | + } | ||
404 | +} | ||
405 | + | ||
406 | +extension ListExtension<E> on List<E> { | ||
407 | + RxList<E> get obs { | ||
408 | + if (this != null) | ||
409 | + return RxList<E>(<E>[])..addAllNonNull(this); | ||
410 | + else | ||
411 | + return RxList<E>(null); | ||
412 | + } | ||
413 | +} |
lib/src/state_manager/rx/rx_map.dart
0 → 100644
1 | +import 'dart:async'; | ||
2 | +import 'package:meta/meta.dart'; | ||
3 | +import '../../../get.dart'; | ||
4 | +import 'rx_interface.dart'; | ||
5 | +import 'rx_typedefs.dart'; | ||
6 | + | ||
7 | +class RxMap<K, V> extends RxInterface<Map<K, V>> implements Map<K, V> { | ||
8 | + RxMap([Map<K, V> initial]) { | ||
9 | + _value = initial; | ||
10 | + } | ||
11 | + | ||
12 | + @override | ||
13 | + StreamController<Map<K, V>> subject = StreamController<Map<K, V>>.broadcast(); | ||
14 | + final Map<Stream<Map<K, V>>, StreamSubscription> _subscriptions = {}; | ||
15 | + | ||
16 | + Map<K, V> _value; | ||
17 | + | ||
18 | + @protected | ||
19 | + Map<K, V> get value { | ||
20 | + if (getObs != null) { | ||
21 | + getObs.addListener(subject.stream); | ||
22 | + } | ||
23 | + return _value; | ||
24 | + } | ||
25 | + | ||
26 | + String get string => value.toString(); | ||
27 | + | ||
28 | + bool get canUpdate { | ||
29 | + return _subscriptions.length > 0; | ||
30 | + } | ||
31 | + | ||
32 | + @override | ||
33 | + void close() { | ||
34 | + _subscriptions.forEach((observable, subscription) { | ||
35 | + subscription.cancel(); | ||
36 | + }); | ||
37 | + _subscriptions.clear(); | ||
38 | + subject.close(); | ||
39 | + } | ||
40 | + | ||
41 | + @override | ||
42 | + void addListener(Stream rxGetx) { | ||
43 | + if (_subscriptions.containsKey(rxGetx)) { | ||
44 | + return; | ||
45 | + } | ||
46 | + _subscriptions[rxGetx] = rxGetx.listen((data) { | ||
47 | + subject.add(data); | ||
48 | + }); | ||
49 | + } | ||
50 | + | ||
51 | + set value(Map<K, V> val) { | ||
52 | + if (_value == val) return; | ||
53 | + _value = val; | ||
54 | + subject.add(_value); | ||
55 | + } | ||
56 | + | ||
57 | + Stream<Map<K, V>> get stream => subject.stream; | ||
58 | + | ||
59 | + StreamSubscription<Map<K, V>> listen(void Function(Map<K, V>) onData, | ||
60 | + {Function onError, void Function() onDone, bool cancelOnError}) => | ||
61 | + stream.listen(onData, onError: onError, onDone: onDone); | ||
62 | + | ||
63 | + void bindStream(Stream<Map<K, V>> stream) => | ||
64 | + stream.listen((va) => value = va); | ||
65 | + | ||
66 | + void add(K key, V value) { | ||
67 | + _value[key] = value; | ||
68 | + subject.add(_value); | ||
69 | + } | ||
70 | + | ||
71 | + void addIf(condition, K key, V value) { | ||
72 | + if (condition is Condition) condition = condition(); | ||
73 | + if (condition is bool && condition) { | ||
74 | + _value[key] = value; | ||
75 | + subject.add(_value); | ||
76 | + } | ||
77 | + } | ||
78 | + | ||
79 | + void addAllIf(condition, Map<K, V> values) { | ||
80 | + if (condition is Condition) condition = condition(); | ||
81 | + if (condition is bool && condition) addAll(values); | ||
82 | + } | ||
83 | + | ||
84 | + @override | ||
85 | + V operator [](Object key) { | ||
86 | + return value[key]; | ||
87 | + } | ||
88 | + | ||
89 | + @override | ||
90 | + void operator []=(K key, V value) { | ||
91 | + _value[key] = value; | ||
92 | + subject.add(_value); | ||
93 | + } | ||
94 | + | ||
95 | + @override | ||
96 | + void addAll(Map<K, V> other) { | ||
97 | + _value.addAll(other); | ||
98 | + subject.add(_value); | ||
99 | + } | ||
100 | + | ||
101 | + @override | ||
102 | + void addEntries(Iterable<MapEntry<K, V>> entries) { | ||
103 | + _value.addEntries(entries); | ||
104 | + subject.add(_value); | ||
105 | + } | ||
106 | + | ||
107 | + @override | ||
108 | + void clear() { | ||
109 | + _value.clear(); | ||
110 | + subject.add(_value); | ||
111 | + } | ||
112 | + | ||
113 | + @override | ||
114 | + Map<K2, V2> cast<K2, V2>() => _value.cast<K2, V2>(); | ||
115 | + | ||
116 | + @override | ||
117 | + bool containsKey(Object key) => _value.containsKey(key); | ||
118 | + | ||
119 | + @override | ||
120 | + bool containsValue(Object value) => _value.containsValue(value); | ||
121 | + | ||
122 | + @override | ||
123 | + Iterable<MapEntry<K, V>> get entries => _value.entries; | ||
124 | + | ||
125 | + @override | ||
126 | + void forEach(void Function(K, V) f) { | ||
127 | + _value.forEach(f); | ||
128 | + } | ||
129 | + | ||
130 | + @override | ||
131 | + bool get isEmpty => value.isEmpty; | ||
132 | + | ||
133 | + @override | ||
134 | + bool get isNotEmpty => value.isNotEmpty; | ||
135 | + | ||
136 | + @override | ||
137 | + Iterable<K> get keys => _value.keys; | ||
138 | + | ||
139 | + @override | ||
140 | + int get length => value.length; | ||
141 | + | ||
142 | + @override | ||
143 | + Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> Function(K, V) transform) => | ||
144 | + value.map(transform); | ||
145 | + | ||
146 | + @override | ||
147 | + V putIfAbsent(K key, V Function() ifAbsent) { | ||
148 | + final val = _value.putIfAbsent(key, ifAbsent); | ||
149 | + subject.add(_value); | ||
150 | + return val; | ||
151 | + } | ||
152 | + | ||
153 | + @override | ||
154 | + V remove(Object key) { | ||
155 | + final val = _value.remove(key); | ||
156 | + subject.add(_value); | ||
157 | + return val; | ||
158 | + } | ||
159 | + | ||
160 | + @override | ||
161 | + void removeWhere(bool Function(K, V) test) { | ||
162 | + _value.removeWhere(test); | ||
163 | + subject.add(_value); | ||
164 | + } | ||
165 | + | ||
166 | + @override | ||
167 | + Iterable<V> get values => value.values; | ||
168 | + | ||
169 | + @override | ||
170 | + String toString() => _value.toString(); | ||
171 | + | ||
172 | + @override | ||
173 | + V update(K key, V Function(V) update, {V Function() ifAbsent}) { | ||
174 | + final val = _value.update(key, update, ifAbsent: ifAbsent); | ||
175 | + subject.add(_value); | ||
176 | + return val; | ||
177 | + } | ||
178 | + | ||
179 | + @override | ||
180 | + void updateAll(V Function(K, V) update) { | ||
181 | + _value.updateAll(update); | ||
182 | + subject.add(_value); | ||
183 | + } | ||
184 | +} | ||
185 | + | ||
186 | +extension MapExtension<K, V> on Map<K, V> { | ||
187 | + RxMap<K, V> get obs { | ||
188 | + if (this != null) | ||
189 | + return RxMap<K, V>(<K, V>{})..addAll(this); | ||
190 | + else | ||
191 | + return RxMap<K, V>(null); | ||
192 | + } | ||
193 | +} |
1 | -class Change<T> { | ||
2 | - /// Value before change | ||
3 | - final T $old; | ||
4 | - | ||
5 | - /// Value after change | ||
6 | - final $new; | ||
7 | - | ||
8 | - final ListChangeOp op; | ||
9 | - | ||
10 | - final int pos; | ||
11 | - | ||
12 | - final DateTime time; | ||
13 | - final int batch; | ||
14 | - Change({this.$new, this.$old, this.batch, this.op, this.pos, DateTime time}) | ||
15 | - : time = time ?? DateTime.now(); | ||
16 | - String toString() => 'Change(new: ${$new}, old: ${$old})'; | ||
17 | - | ||
18 | - Change.insert({this.$new, this.$old, this.batch, this.pos, DateTime time}) | ||
19 | - : op = ListChangeOp.add, | ||
20 | - time = time ?? new DateTime.now(); | ||
21 | - | ||
22 | - Change.set({this.$new, this.$old, this.batch, this.pos, DateTime time}) | ||
23 | - : op = ListChangeOp.set, | ||
24 | - time = time ?? new DateTime.now(); | ||
25 | - | ||
26 | - Change.remove({this.$new, this.$old, this.batch, this.pos, DateTime time}) | ||
27 | - : op = ListChangeOp.remove, | ||
28 | - time = time ?? new DateTime.now(); | ||
29 | - | ||
30 | - Change.clear({this.$new, this.$old, this.batch, DateTime time}) | ||
31 | - : op = ListChangeOp.clear, | ||
32 | - pos = null, | ||
33 | - time = time ?? new DateTime.now(); | ||
34 | -} | ||
35 | - | ||
36 | -typedef bool Condition(); | ||
37 | - | ||
38 | -/// Change operation | ||
39 | -enum ListChangeOp { add, remove, clear, set } |
lib/src/state_manager/rx/rx_typedefs.dart
0 → 100644
1 | +typedef bool Condition(); |
@@ -5,6 +5,8 @@ export 'src/state_manager/simple/simple_builder.dart'; | @@ -5,6 +5,8 @@ export 'src/state_manager/simple/simple_builder.dart'; | ||
5 | export 'src/state_manager/simple/mixin_state.dart'; | 5 | export 'src/state_manager/simple/mixin_state.dart'; |
6 | export 'src/state_manager/rx/rx_interface.dart'; | 6 | export 'src/state_manager/rx/rx_interface.dart'; |
7 | export 'src/state_manager/rx/rx_impl.dart'; | 7 | export 'src/state_manager/rx/rx_impl.dart'; |
8 | +export 'src/state_manager/rx/rx_list.dart'; | ||
9 | +export 'src/state_manager/rx/rx_map.dart'; | ||
8 | export 'src/state_manager/rx/rx_event.dart'; | 10 | export 'src/state_manager/rx/rx_event.dart'; |
9 | export 'src/state_manager/rx/rx_obx.dart'; | 11 | export 'src/state_manager/rx/rx_obx.dart'; |
10 | export 'src/state_manager/rx/rx_getbuilder.dart'; | 12 | export 'src/state_manager/rx/rx_getbuilder.dart'; |
1 | name: get | 1 | name: get |
2 | description: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with GetX. | 2 | description: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with GetX. |
3 | -version: 3.5.1 | 3 | +version: 3.6.0 |
4 | homepage: https://github.com/jonataslaw/get | 4 | homepage: https://github.com/jonataslaw/get |
5 | 5 | ||
6 | environment: | 6 | environment: |
@@ -30,7 +30,7 @@ void main() { | @@ -30,7 +30,7 @@ void main() { | ||
30 | 'Bool: ${controller.boolean.value}', | 30 | 'Bool: ${controller.boolean.value}', |
31 | ), | 31 | ), |
32 | Text( | 32 | Text( |
33 | - 'Map: ${controller.map.value.length}', | 33 | + 'Map: ${controller.map.length}', |
34 | ), | 34 | ), |
35 | FlatButton( | 35 | FlatButton( |
36 | child: Text("increment"), | 36 | child: Text("increment"), |
@@ -27,14 +27,14 @@ void main() { | @@ -27,14 +27,14 @@ void main() { | ||
27 | 'Bool: ${controller.boolean.value}', | 27 | 'Bool: ${controller.boolean.value}', |
28 | ), | 28 | ), |
29 | Text( | 29 | Text( |
30 | - 'Map: ${controller.map.value.length}', | 30 | + 'Map: ${controller.map.length}', |
31 | ), | 31 | ), |
32 | FlatButton( | 32 | FlatButton( |
33 | child: Text("increment"), | 33 | child: Text("increment"), |
34 | onPressed: () => controller.increment(), | 34 | onPressed: () => controller.increment(), |
35 | ), | 35 | ), |
36 | Obx(() => Text( | 36 | Obx(() => Text( |
37 | - 'Obx: ${controller.map.value.length}', | 37 | + 'Obx: ${controller.map.length}', |
38 | )) | 38 | )) |
39 | ]), | 39 | ]), |
40 | ), | 40 | ), |
@@ -28,7 +28,7 @@ void main() { | @@ -28,7 +28,7 @@ void main() { | ||
28 | 'Bool: ${controller.boolean.value}', | 28 | 'Bool: ${controller.boolean.value}', |
29 | ), | 29 | ), |
30 | Text( | 30 | Text( |
31 | - 'Map: ${controller.map.value.length}', | 31 | + 'Map: ${controller.map.length}', |
32 | ), | 32 | ), |
33 | FlatButton( | 33 | FlatButton( |
34 | child: Text("increment"), | 34 | child: Text("increment"), |
-
Please register or login to post a comment