LCOV - code coverage report
Current view: top level - src/rx - rx_impl.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 76 187 40.6 %
Date: 2020-06-03 02:02:49 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:async';
       2             : import 'package:get/src/get_main.dart';
       3             : import 'rx_callbacks.dart';
       4             : import 'rx_interface.dart';
       5             : import 'rx_model.dart';
       6             : 
       7             : class _StoredValue<T> implements RxInterface<T> {
       8             :   StreamController<Change<T>> subject = StreamController<Change<T>>.broadcast();
       9             :   StreamController<Change<T>> _changeCtl =
      10             :       StreamController<Change<T>>.broadcast();
      11             :   Map<Stream<Change<T>>, StreamSubscription> _subscriptions = Map();
      12             : 
      13             :   T _value;
      14           4 :   T get v {
      15           4 :     if (Get.obs != null) {
      16          12 :       Get.obs.addListener(subject.stream);
      17             :     }
      18           4 :     return _value;
      19             :   }
      20             : 
      21           8 :   T get value => v;
      22           8 :   set value(T va) => v = va;
      23             : 
      24           0 :   String get string => v.toString();
      25             : 
      26           1 :   close() {
      27           3 :     _subscriptions.forEach((observable, subscription) {
      28           1 :       subscription.cancel();
      29             :     });
      30           2 :     _subscriptions.clear();
      31           2 :     _changeCtl.close();
      32             :   }
      33             : 
      34           1 :   addListener(Stream<Change<T>> rxGetx) {
      35           2 :     if (_subscriptions.containsKey(rxGetx)) {
      36             :       return;
      37             :     }
      38             : 
      39           4 :     _subscriptions[rxGetx] = rxGetx.listen((data) {
      40           2 :       subject.add(data);
      41             :     });
      42             :   }
      43             : 
      44           4 :   set v(T val) {
      45           8 :     if (_value == val) return;
      46           4 :     T old = _value;
      47           4 :     _value = val;
      48          16 :     subject.add(Change<T>($new: val, $old: old, batch: _cb));
      49             :   }
      50             : 
      51             :   int _cb = 0;
      52             : 
      53           4 :   _StoredValue([T initial]) : _value = initial {
      54          16 :     _onChange = subject.stream.asBroadcastStream();
      55             :   }
      56             : 
      57           0 :   void setCast(dynamic /* T */ val) => v = val;
      58             : 
      59             :   Stream<Change<T>> _onChange;
      60             : 
      61           0 :   Stream<Change<T>> get onChange {
      62           0 :     _cb++;
      63             : 
      64           0 :     _changeCtl.add(Change<T>($new: v, $old: null, batch: _cb));
      65           0 :     _changeCtl.addStream(_onChange.skipWhile((v) => v.batch < _cb));
      66           0 :     return _changeCtl.stream.asBroadcastStream();
      67             :   }
      68             : 
      69           0 :   Stream<T> get stream => onChange.map((c) => c.$new);
      70             : 
      71           0 :   void bind(RxInterface<T> reactive) {
      72           0 :     v = reactive.v;
      73           0 :     reactive.stream.listen((va) => v = va);
      74             :   }
      75             : 
      76           0 :   void bindStream(Stream<T> stream) => stream.listen((va) => v = va);
      77             : 
      78           0 :   void bindOrSet(/* T | Stream<T> | Reactive<T> */ other) {
      79           0 :     if (other is RxInterface<T>) {
      80           0 :       bind(other);
      81           0 :     } else if (other is Stream<T>) {
      82           0 :       bindStream(other.cast<T>());
      83             :     } else {
      84           0 :       v = other;
      85             :     }
      86             :   }
      87             : 
      88           0 :   StreamSubscription<T> listen(ValueCallback<T> callback) =>
      89           0 :       stream.listen(callback);
      90             : 
      91           0 :   Stream<R> map<R>(R mapper(T data)) => stream.map(mapper);
      92             : }
      93             : 
      94             : class StringX<String> extends _StoredValue<String> {
      95           3 :   StringX([String initial]) {
      96           3 :     _value = initial;
      97          12 :     _onChange = subject.stream.asBroadcastStream();
      98             :   }
      99             : }
     100             : 
     101             : class IntX<int> extends _StoredValue<int> {
     102           4 :   IntX([int initial]) {
     103           4 :     _value = initial;
     104          16 :     _onChange = subject.stream.asBroadcastStream();
     105             :   }
     106             : }
     107             : 
     108             : class MapX<Map> extends _StoredValue<Map> {
     109           3 :   MapX([Map initial]) {
     110           3 :     _value = initial;
     111          12 :     _onChange = subject.stream.asBroadcastStream();
     112             :   }
     113             : }
     114             : 
     115             : // class ListX<List> extends _StoredValue<List> {
     116             : //   ListX([List initial]) {
     117             : //     _value = initial;
     118             : //     _onChange = subject.stream.asBroadcastStream();
     119             : //   }
     120             : // }
     121             : 
     122             : class ListX<E> extends Iterable<E> implements RxInterface<E> {
     123             :   /// Create a list similar to `List<T>`
     124             : 
     125           3 :   ListX([List<E> initial]) {
     126           3 :     _list = initial;
     127          12 :     _onChange = subject.stream.asBroadcastStream();
     128             :   }
     129             : 
     130           0 :   @override
     131           0 :   Iterator<E> get iterator => _list.iterator;
     132             : 
     133           0 :   @override
     134           0 :   bool get isEmpty => _list.isEmpty;
     135             : 
     136           0 :   @override
     137           0 :   bool get isNotEmpty => _list.isNotEmpty;
     138             : 
     139             :   Map<Stream<Change<E>>, StreamSubscription> _subscriptions = Map();
     140             : 
     141             :   // StreamSubscription _changectl = StreamSubscription();
     142             : 
     143             :   StreamController<Change<E>> _changeCtl =
     144             :       StreamController<Change<E>>.broadcast();
     145             : 
     146             :   @override
     147             :   StreamController<Change<E>> subject = StreamController<Change<E>>.broadcast();
     148             : 
     149             :   /// Adds [item] only if [condition] resolves to true.
     150           0 :   void addIf(condition, E item) {
     151           0 :     if (condition is Condition) condition = condition();
     152           0 :     if (condition is bool && condition) add(item);
     153             :   }
     154             : 
     155             :   /// Adds all [items] only if [condition] resolves to true.
     156           0 :   void addAllIf(condition, Iterable<E> items) {
     157           0 :     if (condition is Condition) condition = condition();
     158           0 :     if (condition is bool && condition) addAll(items);
     159             :   }
     160             : 
     161           0 :   operator []=(int index, E val) {
     162           0 :     _list[index] = val;
     163           0 :     subject.add(Change<E>.set($new: val, item: val, pos: index));
     164             :   }
     165             : 
     166           0 :   E operator [](int index) {
     167           0 :     return value[index];
     168             :   }
     169             : 
     170           0 :   void add(E item) {
     171           0 :     _list.add(item);
     172           0 :     subject
     173           0 :         .add(Change<E>.insert($new: item, item: item, pos: _list.length - 1));
     174             :   }
     175             : 
     176           3 :   void addAll(List<E> item) {
     177           6 :     _list.addAll(item);
     178          21 :     subject.add(Change<E>.insert(item: _list, pos: _list.length - 1));
     179             :   }
     180             : 
     181             :   /// Adds only if [item] is not null.
     182           0 :   void addNonNull(E item) {
     183           0 :     if (item != null) add(item);
     184             :   }
     185             : 
     186             :   /// Adds only if [item] is not null.
     187           3 :   void addAllNonNull(Iterable<E> item) {
     188           3 :     if (item != null) addAll(item);
     189             :   }
     190             : 
     191           0 :   void insert(int index, E item) {
     192           0 :     _list.insert(index, item);
     193           0 :     subject.add(Change<E>.insert(item: item, pos: index));
     194             :   }
     195             : 
     196           0 :   void insertAll(int index, Iterable<E> iterable) {
     197           0 :     _list.insertAll(index, iterable);
     198           0 :     subject.add(Change<E>.insert(item: iterable.last, pos: index));
     199             :   }
     200             : 
     201           9 :   int get length => value.length;
     202             : 
     203             :   /// Removes an item from the list.
     204             :   ///
     205             :   /// This is O(N) in the number of items in the list.
     206             :   ///
     207             :   /// Returns whether the item was present in the list.
     208           0 :   bool remove(Object item) {
     209           0 :     int pos = _list.indexOf(item);
     210           0 :     bool hasRemoved = _list.remove(item);
     211             :     if (hasRemoved) {
     212           0 :       subject.add(Change<E>.remove(item: item, pos: pos));
     213             :     }
     214             :     return hasRemoved;
     215             :   }
     216             : 
     217           0 :   E removeAt(int index) {
     218           0 :     E item = _list.removeAt(index);
     219           0 :     subject.add(Change<E>.remove(item: item, pos: index));
     220             :     return item;
     221             :   }
     222             : 
     223           0 :   E removeLast() {
     224           0 :     int pos = _list.indexOf(_list.last);
     225           0 :     E item = _list.removeLast();
     226           0 :     subject.add(Change<E>.remove(item: item, pos: pos));
     227             :     return item;
     228             :   }
     229             : 
     230           0 :   void removeRange(int start, int end) {
     231           0 :     _list.removeRange(start, end);
     232           0 :     subject.add(Change<E>.remove(item: null, pos: null));
     233             :   }
     234             : 
     235           0 :   void removeWhere(bool Function(E) test) {
     236           0 :     _list.removeWhere(test);
     237           0 :     subject.add(Change<E>.remove(item: null, pos: null));
     238             :   }
     239             : 
     240           0 :   void clear() {
     241           0 :     _list.clear();
     242           0 :     subject.add(Change<E>.clear());
     243             :   }
     244             : 
     245           2 :   close() {
     246           6 :     _subscriptions.forEach((observable, subscription) {
     247           2 :       subscription.cancel();
     248             :     });
     249           4 :     _subscriptions.clear();
     250           4 :     subject.close();
     251           4 :     _changeCtl.close();
     252             :   }
     253             : 
     254             :   /// Replaces all existing items of this list with [item]
     255           0 :   void assign(E item) {
     256           0 :     clear();
     257           0 :     add(item);
     258             :   }
     259             : 
     260             :   /// Replaces all existing items of this list with [items]
     261           0 :   void assignAll(Iterable<E> items) {
     262           0 :     clear();
     263           0 :     addAll(items);
     264             :   }
     265             : 
     266             :   /// A stream of record of changes to this list
     267           0 :   Stream<Change<E>> get onChange {
     268           0 :     final now = DateTime.now();
     269             : 
     270           0 :     _onChange.skipWhile((m) => m.time.isBefore(now));
     271           0 :     return _changeCtl.stream.asBroadcastStream();
     272             :   }
     273             : 
     274             :   Stream<Change<E>> _onChange;
     275             : 
     276           2 :   addListener(Stream<Change<E>> rxGetx) {
     277           4 :     if (_subscriptions.containsKey(rxGetx)) {
     278             :       return;
     279             :     }
     280           8 :     _subscriptions[rxGetx] = rxGetx.listen((data) {
     281           4 :       subject.add(data);
     282             :     });
     283             :   }
     284             : 
     285           6 :   List<E> get value => v as List<E>;
     286             : 
     287           0 :   set value(List<E> va) => assignAll(va);
     288             : 
     289           3 :   @override
     290             :   get v {
     291           3 :     if (Get.obs != null) {
     292          12 :       Get.obs.addListener(subject.stream);
     293             :     }
     294           3 :     return _list;
     295             :   }
     296             : 
     297           0 :   set v(E val) {
     298           0 :     assign(val);
     299             :   }
     300             : 
     301           0 :   @override
     302           0 :   Stream<E> get stream => onChange.map((c) => c.item);
     303             : 
     304           0 :   @override
     305             :   void bind(RxInterface<E> reactive) {
     306           0 :     v = reactive.v;
     307           0 :     reactive.stream.listen((va) => v = va);
     308             :   }
     309             : 
     310           0 :   void bindStream(Stream<E> stream) => stream.listen((va) => v = va);
     311             : 
     312           0 :   @override
     313             :   void bindOrSet(/* T | Stream<T> or Rx<T> */ other) {
     314           0 :     if (other is RxInterface<E>) {
     315           0 :       bind(other);
     316           0 :     } else if (other is Stream<E>) {
     317           0 :       bindStream(other.cast<E>());
     318             :     } else {
     319           0 :       v = other;
     320             :     }
     321             :   }
     322             : 
     323           0 :   @override
     324             :   StreamSubscription<E> listen(ValueCallback<E> callback) =>
     325           0 :       stream.listen(callback);
     326             : 
     327           0 :   @override
     328           0 :   void setCast(dynamic val) => v = val;
     329             : 
     330             :   List<E> _list = <E>[];
     331             : }
     332             : 
     333             : // class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> {
     334             : //   /// Create a list similar to `List<T>`
     335             : //   ListX([int length]) : super(length != null ? List<E>(length) : List<E>()) {
     336             : //     _onChange = subject.stream.asBroadcastStream();
     337             : //   }
     338             : 
     339             : //   ListX.filled(int length, E fill, {bool growable: false})
     340             : //       : super(List<E>.filled(length, fill, growable: growable)) {
     341             : //     _onChange = subject.stream.asBroadcastStream();
     342             : //   }
     343             : 
     344             : //   ListX.from(Iterable<E> items, {bool growable: true})
     345             : //       : super(List<E>.from(items, growable: growable)) {
     346             : //     _onChange = subject.stream.asBroadcastStream();
     347             : //   }
     348             : 
     349             : //   ListX.union(Iterable<E> items, [E item]) : super(items?.toList() ?? <E>[]) {
     350             : //     if (item != null) add(item);
     351             : //     _onChange = subject.stream.asBroadcastStream();
     352             : //   }
     353             : 
     354             : //   ListX.of(Iterable<E> items, {bool growable: true})
     355             : //       : super(List<E>.of(items, growable: growable));
     356             : 
     357             : //   ListX.generate(int length, E generator(int index), {bool growable: true})
     358             : //       : super(List<E>.generate(length, generator, growable: growable));
     359             : 
     360             : //   Map<Stream<Change<E>>, StreamSubscription> _subscriptions = Map();
     361             : 
     362             : //   // StreamSubscription _changectl = StreamSubscription();
     363             : 
     364             : //   StreamController<Change<E>> _changeCtl =
     365             : //       StreamController<Change<E>>.broadcast();
     366             : 
     367             : //   @override
     368             : //   StreamController<Change<E>> subject = StreamController<Change<E>>.broadcast();
     369             : 
     370             : //   /// Adds [item] only if [condition] resolves to true.
     371             : //   void addIf(condition, E item) {
     372             : //     if (condition is Condition) condition = condition();
     373             : //     if (condition is bool && condition) add(item);
     374             : //   }
     375             : 
     376             : //   /// Adds all [items] only if [condition] resolves to true.
     377             : //   void addAllIf(condition, Iterable<E> items) {
     378             : //     if (condition is Condition) condition = condition();
     379             : //     if (condition is bool && condition) addAll(items);
     380             : //   }
     381             : 
     382             : //   operator []=(int index, E value) {
     383             : //     super[index] = value;
     384             : //     if (Get.obs != null) {
     385             : //       Get.obs.addListener(subject.stream);
     386             : //     }
     387             : //     subject.add(Change<E>.set(item: value, pos: index));
     388             : //   }
     389             : 
     390             : //   void _add(E item) => super.add(item);
     391             : 
     392             : //   void add(E item) {
     393             : //     super.add(item);
     394             : //     subject.add(Change<E>.insert(item: item, pos: length - 1));
     395             : //   }
     396             : 
     397             : //   /// Adds only if [item] is not null.
     398             : //   void addNonNull(E item) {
     399             : //     if (item != null) add(item);
     400             : //   }
     401             : 
     402             : //   void insert(int index, E item) {
     403             : //     super.insert(index, item);
     404             : //     subject.add(Change<E>.insert(item: item, pos: index));
     405             : //   }
     406             : 
     407             : //   bool remove(Object item) {
     408             : //     int pos = indexOf(item);
     409             : //     bool hasRemoved = super.remove(item);
     410             : //     if (hasRemoved) {
     411             : //       subject.add(Change<E>.remove(item: item, pos: pos));
     412             : //     }
     413             : //     return hasRemoved;
     414             : //   }
     415             : 
     416             : //   void clear() {
     417             : //     super.clear();
     418             : //     subject.add(Change<E>.clear());
     419             : //   }
     420             : 
     421             : //   close() {
     422             : //     clear();
     423             : //     _subscriptions.forEach((observable, subscription) {
     424             : //       subscription.cancel();
     425             : //     });
     426             : //     _subscriptions.clear();
     427             : //     subject.close();
     428             : //     _changeCtl.close();
     429             : //   }
     430             : 
     431             : //   /// Replaces all existing items of this list with [item]
     432             : //   void assign(E item) {
     433             : //     clear();
     434             : //     add(item);
     435             : //   }
     436             : 
     437             : //   /// Replaces all existing items of this list with [items]
     438             : //   void assignAll(Iterable<E> items) {
     439             : //     clear();
     440             : //     addAll(items);
     441             : //   }
     442             : 
     443             : //   /// A stream of record of changes to this list
     444             : //   Stream<Change<E>> get onChange {
     445             : //     final now = DateTime.now();
     446             : 
     447             : //     _onChange.skipWhile((m) => m.time.isBefore(now));
     448             : //     return _changeCtl.stream.asBroadcastStream();
     449             : //   }
     450             : 
     451             : //   Stream<Change<E>> _onChange;
     452             : 
     453             : //   addListener(Stream<Change<E>> rxGetx) {
     454             : //     if (_subscriptions.containsKey(rxGetx)) {
     455             : //       return;
     456             : //     }
     457             : //     _subscriptions[rxGetx] = rxGetx.listen((data) {
     458             : //       subject.add(data);
     459             : //     });
     460             : //   }
     461             : 
     462             : //   List<E> get value => v as List<E>;
     463             : 
     464             : //   set value(List<E> va) => assignAll(va);
     465             : 
     466             : //   @override
     467             : //   get v {
     468             : //     if (Get.obs != null) {
     469             : //       Get.obs.addListener(subject.stream);
     470             : //     }
     471             : //     return this;
     472             : //   }
     473             : 
     474             : //   set v(E val) {
     475             : //     assign(val);
     476             : //   }
     477             : 
     478             : //   @override
     479             : //   Stream<E> get stream => onChange.map((c) => c.item);
     480             : 
     481             : //   @override
     482             : //   void bind(RxInterface<E> reactive) {
     483             : //     v = reactive.v;
     484             : //     reactive.stream.listen((va) => v = va);
     485             : //   }
     486             : 
     487             : //   void bindStream(Stream<E> stream) => stream.listen((va) => v = va);
     488             : 
     489             : //   @override
     490             : //   void bindOrSet(/* T | Stream<T> or Rx<T> */ other) {
     491             : //     if (other is RxInterface<E>) {
     492             : //       bind(other);
     493             : //     } else if (other is Stream<E>) {
     494             : //       bindStream(other.cast<E>());
     495             : //     } else {
     496             : //       v = other;
     497             : //     }
     498             : //   }
     499             : 
     500             : //   @override
     501             : //   StreamSubscription<E> listen(ValueCallback<E> callback) =>
     502             : //       stream.listen(callback);
     503             : 
     504             : //   @override
     505             : //   void setCast(dynamic val) => v = val;
     506             : // }
     507             : 
     508             : typedef bool Condition();
     509             : 
     510             : typedef E ChildrenListComposer<S, E>(S value);
     511             : 
     512             : // /// An observable list that is bound to another list [binding]
     513             : // class BindingList<S, E> extends ListX<E> {
     514             : //   final ListX<S> binding;
     515             : 
     516             : //   final ChildrenListComposer<S, E> composer;
     517             : 
     518             : //   BindingList(this.binding, this.composer) {
     519             : //     for (S v in binding) _add(composer(v));
     520             : //     binding.onChange.listen((Change<S> n) {
     521             : //       if (n.op == ListChangeOp.add) {
     522             : //         insert(n.pos, composer(n.item));
     523             : //       } else if (n.op == ListChangeOp.remove) {
     524             : //         removeAt(n.pos);
     525             : //       } else if (n.op == ListChangeOp.clear) {
     526             : //         clear();
     527             : //       }
     528             : //     });
     529             : //   }
     530             : // }
     531             : 
     532             : class BoolX<bool> extends _StoredValue<bool> {
     533           3 :   BoolX([bool initial]) {
     534           3 :     _value = initial;
     535          12 :     _onChange = subject.stream.asBroadcastStream();
     536             :   }
     537             : }
     538             : 
     539             : class DoubleX<double> extends _StoredValue<double> {
     540           3 :   DoubleX([double initial]) {
     541           3 :     _value = initial;
     542          12 :     _onChange = subject.stream.asBroadcastStream();
     543             :   }
     544             : }
     545             : 
     546             : class NumX<num> extends _StoredValue<num> {
     547           0 :   NumX([num initial]) {
     548           0 :     _value = initial;
     549           0 :     _onChange = subject.stream.asBroadcastStream();
     550             :   }
     551             : }
     552             : 
     553             : class Rx<T> extends _StoredValue<T> {
     554           1 :   Rx([T initial]) {
     555           1 :     _value = initial;
     556           4 :     _onChange = subject.stream.asBroadcastStream();
     557             :   }
     558             : }
     559             : 
     560             : extension StringExtension on String {
     561           3 :   StringX<String> get obs {
     562             :     if (this != null)
     563           3 :       return StringX(this);
     564             :     else
     565           0 :       return StringX(null);
     566             :   }
     567             : }
     568             : 
     569             : extension IntExtension on int {
     570           4 :   IntX<int> get obs {
     571             :     if (this != null)
     572           4 :       return IntX(this);
     573             :     else
     574           0 :       return IntX(null);
     575             :   }
     576             : }
     577             : 
     578             : extension DoubleExtension on double {
     579           3 :   DoubleX<double> get obs {
     580             :     if (this != null)
     581           3 :       return DoubleX(this);
     582             :     else
     583           0 :       return DoubleX(null);
     584             :   }
     585             : }
     586             : 
     587             : extension MapExtension on Map {
     588           3 :   MapX<Map> get obs {
     589             :     if (this != null)
     590           3 :       return MapX(this);
     591             :     else
     592           0 :       return MapX(null);
     593             :   }
     594             : }
     595             : 
     596             : extension ListExtension<E> on List<E> {
     597           3 :   ListX<E> get obs {
     598             :     if (this != null)
     599           9 :       return ListX<E>([])..addAllNonNull(this);
     600             :     else
     601           0 :       return ListX<E>(null);
     602             :   }
     603             : }
     604             : 
     605             : extension BoolExtension on bool {
     606           3 :   BoolX<bool> get obs {
     607             :     if (this != null)
     608           3 :       return BoolX(this);
     609             :     else
     610           0 :       return BoolX(null);
     611             :   }
     612             : }
     613             : 
     614             : extension ObjectExtension on Object {
     615           0 :   Rx<Object> get obs {
     616             :     if (this != null)
     617           0 :       return Rx(this);
     618             :     else
     619           0 :       return Rx(null);
     620             :   }
     621             : }

Generated by: LCOV version 1.14