Showing
8 changed files
with
268 additions
and
210 deletions
| @@ -749,7 +749,7 @@ class Get { | @@ -749,7 +749,7 @@ class Get { | ||
| 749 | final i = Get()._singl[key].getSependency(); | 749 | final i = Get()._singl[key].getSependency(); | 
| 750 | 750 | ||
| 751 | if (i is DisposableInterface) { | 751 | if (i is DisposableInterface) { | 
| 752 | - i.onInit(); | 752 | + i.onStart(); | 
| 753 | if (isLogEnable) print('[GET] $key has been initialized'); | 753 | if (isLogEnable) print('[GET] $key has been initialized'); | 
| 754 | } | 754 | } | 
| 755 | } | 755 | } | 
| @@ -58,11 +58,11 @@ class _GetXState<T extends DisposableInterface> extends State<GetX<T>> { | @@ -58,11 +58,11 @@ class _GetXState<T extends DisposableInterface> extends State<GetX<T>> { | ||
| 58 | } else { | 58 | } else { | 
| 59 | controller = widget.init; | 59 | controller = widget.init; | 
| 60 | isCreator = true; | 60 | isCreator = true; | 
| 61 | - controller?.onInit(); | 61 | + controller?.onStart(); | 
| 62 | } | 62 | } | 
| 63 | if (widget.initState != null) widget.initState(this); | 63 | if (widget.initState != null) widget.initState(this); | 
| 64 | if (isCreator && Get().smartManagement == SmartManagement.onlyBuilder) { | 64 | if (isCreator && Get().smartManagement == SmartManagement.onlyBuilder) { | 
| 65 | - controller?.onInit(); | 65 | + controller?.onStart(); | 
| 66 | } | 66 | } | 
| 67 | _observer.subject.stream.listen((data) => setState(() {})); | 67 | _observer.subject.stream.listen((data) => setState(() {})); | 
| 68 | super.initState(); | 68 | super.initState(); | 
| 1 | import 'dart:async'; | 1 | import 'dart:async'; | 
| 2 | -import 'rx_callbacks.dart'; | ||
| 3 | import 'rx_interface.dart'; | 2 | import 'rx_interface.dart'; | 
| 4 | -import 'rx_model.dart'; | ||
| 5 | 3 | ||
| 6 | class _RxImpl<T> implements RxInterface<T> { | 4 | class _RxImpl<T> implements RxInterface<T> { | 
| 7 | - StreamController<Change<T>> subject = StreamController<Change<T>>.broadcast(); | ||
| 8 | - StreamController<Change<T>> _changeCtl = StreamController<Change<T>>(); | ||
| 9 | - Map<Stream<Change<T>>, StreamSubscription> _subscriptions = Map(); | 5 | + StreamController<T> subject = StreamController<T>.broadcast(); | 
| 6 | + Map<Stream<T>, StreamSubscription> _subscriptions = Map(); | ||
| 10 | 7 | ||
| 11 | T _value; | 8 | T _value; | 
| 12 | - T get v { | 9 | + T get value { | 
| 13 | if (getObs != null) { | 10 | if (getObs != null) { | 
| 14 | getObs.addListener(subject.stream); | 11 | getObs.addListener(subject.stream); | 
| 15 | } | 12 | } | 
| 16 | return _value; | 13 | return _value; | 
| 17 | } | 14 | } | 
| 18 | 15 | ||
| 19 | - T get value => v; | ||
| 20 | - set value(T va) => v = va; | ||
| 21 | - | ||
| 22 | - String get string => v.toString(); | 16 | + String get string => value.toString(); | 
| 23 | 17 | ||
| 24 | close() { | 18 | close() { | 
| 25 | _subscriptions.forEach((observable, subscription) { | 19 | _subscriptions.forEach((observable, subscription) { | 
| 26 | subscription.cancel(); | 20 | subscription.cancel(); | 
| 27 | }); | 21 | }); | 
| 28 | _subscriptions.clear(); | 22 | _subscriptions.clear(); | 
| 29 | - _changeCtl.close(); | 23 | + subject.close(); | 
| 30 | } | 24 | } | 
| 31 | 25 | ||
| 32 | - addListener(Stream<Change<T>> rxGetx) { | 26 | + addListener(Stream<T> rxGetx) { | 
| 33 | if (_subscriptions.containsKey(rxGetx)) { | 27 | if (_subscriptions.containsKey(rxGetx)) { | 
| 34 | return; | 28 | return; | 
| 35 | } | 29 | } | 
| 36 | - | ||
| 37 | _subscriptions[rxGetx] = rxGetx.listen((data) { | 30 | _subscriptions[rxGetx] = rxGetx.listen((data) { | 
| 38 | subject.add(data); | 31 | subject.add(data); | 
| 39 | }); | 32 | }); | 
| 40 | } | 33 | } | 
| 41 | 34 | ||
| 42 | - set v(T val) { | 35 | + set value(T val) { | 
| 43 | if (_value == val) return; | 36 | if (_value == val) return; | 
| 44 | - T old = _value; | ||
| 45 | _value = val; | 37 | _value = val; | 
| 46 | - subject.add(Change<T>($new: val, $old: old, batch: _cb)); | 38 | + subject.add(_value); | 
| 39 | + } | ||
| 40 | + | ||
| 41 | + Stream<T> get stream => subject.stream; | ||
| 42 | + | ||
| 43 | + StreamSubscription<T> listen(void Function(T) onData, | ||
| 44 | + {Function onError, void Function() onDone, bool cancelOnError}) => | ||
| 45 | + stream.listen(onData, onError: onError, onDone: onDone); | ||
| 46 | + | ||
| 47 | + void bindStream(Stream<T> stream) => stream.listen((va) => value = va); | ||
| 48 | + Stream<R> map<R>(R mapper(T data)) => stream.map(mapper); | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +class StringX<String> extends _RxImpl<String> { | ||
| 52 | + StringX([String initial]) { | ||
| 53 | + _value = initial; | ||
| 54 | + } | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +class IntX<int> extends _RxImpl<int> { | ||
| 58 | + IntX([int initial]) { | ||
| 59 | + _value = initial; | ||
| 60 | + } | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +class MapX<K, V> extends RxInterface implements Map<K, V> { | ||
| 64 | + MapX([Map<K, V> initial]) { | ||
| 65 | + _value = initial; | ||
| 47 | } | 66 | } | 
| 48 | 67 | ||
| 49 | - int _cb = 0; | 68 | + StreamController subject = StreamController<Map<K, V>>.broadcast(); | 
| 69 | + Map<Stream<Map<K, V>>, StreamSubscription> _subscriptions = Map(); | ||
| 50 | 70 | ||
| 51 | - _RxImpl([T initial]) : _value = initial { | ||
| 52 | - _onChange = subject.stream.asBroadcastStream(); | 71 | + Map<K, V> _value; | 
| 72 | + Map<K, V> get value { | ||
| 73 | + if (getObs != null) { | ||
| 74 | + getObs.addListener(subject.stream); | ||
| 75 | + } | ||
| 76 | + return _value; | ||
| 53 | } | 77 | } | 
| 54 | 78 | ||
| 55 | - void setCast(dynamic /* T */ val) => v = val; | 79 | + String get string => value.toString(); | 
| 56 | 80 | ||
| 57 | - Stream<Change<T>> _onChange; | 81 | + close() { | 
| 82 | + _subscriptions.forEach((observable, subscription) { | ||
| 83 | + subscription.cancel(); | ||
| 84 | + }); | ||
| 85 | + _subscriptions.clear(); | ||
| 86 | + subject.close(); | ||
| 87 | + } | ||
| 58 | 88 | ||
| 59 | - Stream<Change<T>> get onChange { | ||
| 60 | - _cb++; | 89 | + addListener(Stream rxGetx) { | 
| 90 | + if (_subscriptions.containsKey(rxGetx)) { | ||
| 91 | + return; | ||
| 92 | + } | ||
| 93 | + _subscriptions[rxGetx] = rxGetx.listen((data) { | ||
| 94 | + subject.add(data); | ||
| 95 | + }); | ||
| 96 | + } | ||
| 61 | 97 | ||
| 62 | - _changeCtl.add(Change<T>($new: v, $old: null, batch: _cb)); | ||
| 63 | - _changeCtl.addStream(_onChange.skipWhile((v) => v.batch < _cb)); | ||
| 64 | - return _changeCtl.stream.asBroadcastStream(); | 98 | + set value(Map<K, V> val) { | 
| 99 | + if (_value == val) return; | ||
| 100 | + _value = val; | ||
| 101 | + subject.add(_value); | ||
| 65 | } | 102 | } | 
| 66 | 103 | ||
| 67 | - Stream<T> get stream => onChange.map((c) => c.$new); | 104 | + Stream<Map<K, V>> get stream => subject.stream; | 
| 105 | + | ||
| 106 | + StreamSubscription<Map<K, V>> listen(void Function(Map<K, V>) onData, | ||
| 107 | + {Function onError, void Function() onDone, bool cancelOnError}) => | ||
| 108 | + stream.listen(onData, onError: onError, onDone: onDone); | ||
| 109 | + | ||
| 110 | + void bindStream(Stream<Map<K, V>> stream) => | ||
| 111 | + stream.listen((va) => value = va); | ||
| 68 | 112 | ||
| 69 | - void bind(RxInterface<T> reactive) { | ||
| 70 | - v = reactive.v; | ||
| 71 | - reactive.stream.listen((va) => v = va); | 113 | + void add(K key, V value) { | 
| 114 | + _value[key] = value; | ||
| 115 | + subject.add(_value); | ||
| 72 | } | 116 | } | 
| 73 | 117 | ||
| 74 | - void bindStream(Stream<T> stream) => stream.listen((va) => v = va); | 118 | + void addIf(/* bool | Condition */ condition, K key, V value) { | 
| 119 | + if (condition is Condition) condition = condition(); | ||
| 120 | + if (condition is bool && condition) { | ||
| 121 | + _value[key] = value; | ||
| 122 | + subject.add(_value); | ||
| 123 | + } | ||
| 124 | + } | ||
| 75 | 125 | ||
| 76 | - void bindOrSet(/* T | Stream<T> | Reactive<T> */ other) { | ||
| 77 | - if (other is RxInterface<T>) { | ||
| 78 | - bind(other); | ||
| 79 | - } else if (other is Stream<T>) { | ||
| 80 | - bindStream(other.cast<T>()); | ||
| 81 | - } else { | ||
| 82 | - v = other; | 126 | + void addAllIf(/* bool | Condition */ condition, Map<K, V> values) { | 
| 127 | + if (condition is Condition) condition = condition(); | ||
| 128 | + if (condition is bool && condition) addAll(values); | ||
| 83 | } | 129 | } | 
| 130 | + | ||
| 131 | + @override | ||
| 132 | + V operator [](Object key) { | ||
| 133 | + return value[key]; | ||
| 84 | } | 134 | } | 
| 85 | 135 | ||
| 86 | - StreamSubscription<T> listen(ValueCallback<T> callback) => | ||
| 87 | - stream.listen(callback); | 136 | + @override | 
| 137 | + void operator []=(K key, V value) { | ||
| 138 | + _value[key] = value; | ||
| 139 | + subject.add(_value); | ||
| 140 | + } | ||
| 88 | 141 | ||
| 89 | - Stream<R> map<R>(R mapper(T data)) => stream.map(mapper); | ||
| 90 | -} | 142 | + @override | 
| 143 | + void addAll(Map<K, V> other) { | ||
| 144 | + _value.addAll(other); | ||
| 145 | + subject.add(_value); | ||
| 146 | + } | ||
| 91 | 147 | ||
| 92 | -class StringX<String> extends _RxImpl<String> { | ||
| 93 | - StringX([String initial]) { | ||
| 94 | - _value = initial; | ||
| 95 | - _onChange = subject.stream.asBroadcastStream(); | 148 | + @override | 
| 149 | + void addEntries(Iterable<MapEntry<K, V>> entries) { | ||
| 150 | + _value.addEntries(entries); | ||
| 151 | + subject.add(_value); | ||
| 96 | } | 152 | } | 
| 97 | -} | ||
| 98 | 153 | ||
| 99 | -class IntX<int> extends _RxImpl<int> { | ||
| 100 | - IntX([int initial]) { | ||
| 101 | - _value = initial; | ||
| 102 | - _onChange = subject.stream.asBroadcastStream(); | 154 | + @override | 
| 155 | + void clear() { | ||
| 156 | + _value.clear(); | ||
| 157 | + subject.add(_value); | ||
| 103 | } | 158 | } | 
| 104 | -} | ||
| 105 | 159 | ||
| 106 | -class MapX<Map> extends _RxImpl<Map> { | ||
| 107 | - MapX([Map initial]) { | ||
| 108 | - _value = initial; | ||
| 109 | - _onChange = subject.stream.asBroadcastStream(); | 160 | + @override | 
| 161 | + Map<K2, V2> cast<K2, V2>() => _value.cast<K2, V2>(); | ||
| 162 | + | ||
| 163 | + @override | ||
| 164 | + bool containsKey(Object key) => _value.containsKey(key); | ||
| 165 | + | ||
| 166 | + @override | ||
| 167 | + bool containsValue(Object value) => _value.containsValue(value); | ||
| 168 | + | ||
| 169 | + @override | ||
| 170 | + Iterable<MapEntry<K, V>> get entries => _value.entries; | ||
| 171 | + | ||
| 172 | + @override | ||
| 173 | + void forEach(void Function(K, V) f) { | ||
| 174 | + _value.forEach(f); | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + @override | ||
| 178 | + bool get isEmpty => _value.isEmpty; | ||
| 179 | + | ||
| 180 | + @override | ||
| 181 | + bool get isNotEmpty => _value.isNotEmpty; | ||
| 182 | + | ||
| 183 | + @override | ||
| 184 | + Iterable<K> get keys => _value.keys; | ||
| 185 | + | ||
| 186 | + @override | ||
| 187 | + int get length => value.length; | ||
| 188 | + | ||
| 189 | + @override | ||
| 190 | + Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> Function(K, V) transform) => | ||
| 191 | + value.map(transform); | ||
| 192 | + | ||
| 193 | + @override | ||
| 194 | + V putIfAbsent(K key, V Function() ifAbsent) { | ||
| 195 | + final val = _value.putIfAbsent(key, ifAbsent); | ||
| 196 | + subject.add(_value); | ||
| 197 | + return val; | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + @override | ||
| 201 | + V remove(Object key) { | ||
| 202 | + final val = _value.remove(key); | ||
| 203 | + subject.add(_value); | ||
| 204 | + return val; | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + @override | ||
| 208 | + void removeWhere(bool Function(K, V) test) { | ||
| 209 | + _value.removeWhere(test); | ||
| 210 | + subject.add(_value); | ||
| 211 | + } | ||
| 212 | + | ||
| 213 | + @override | ||
| 214 | + Iterable<V> get values => value.values; | ||
| 215 | + | ||
| 216 | + @override | ||
| 217 | + String toString() => _value.toString(); | ||
| 218 | + | ||
| 219 | + @override | ||
| 220 | + V update(K key, V Function(V) update, {V Function() ifAbsent}) { | ||
| 221 | + final val = _value.update(key, update, ifAbsent: ifAbsent); | ||
| 222 | + subject.add(_value); | ||
| 223 | + return val; | ||
| 224 | + } | ||
| 225 | + | ||
| 226 | + @override | ||
| 227 | + void updateAll(V Function(K, V) update) { | ||
| 228 | + _value.updateAll(update); | ||
| 229 | + subject.add(_value); | ||
| 110 | } | 230 | } | 
| 111 | } | 231 | } | 
| 112 | 232 | ||
| @@ -114,7 +234,6 @@ class MapX<Map> extends _RxImpl<Map> { | @@ -114,7 +234,6 @@ class MapX<Map> extends _RxImpl<Map> { | ||
| 114 | class ListX<E> extends Iterable<E> implements RxInterface<E> { | 234 | class ListX<E> extends Iterable<E> implements RxInterface<E> { | 
| 115 | ListX([List<E> initial]) { | 235 | ListX([List<E> initial]) { | 
| 116 | _list = initial; | 236 | _list = initial; | 
| 117 | - _onChange = subject.stream.asBroadcastStream(); | ||
| 118 | } | 237 | } | 
| 119 | 238 | ||
| 120 | @override | 239 | @override | 
| @@ -126,15 +245,8 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | @@ -126,15 +245,8 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | ||
| 126 | @override | 245 | @override | 
| 127 | bool get isNotEmpty => _list.isNotEmpty; | 246 | bool get isNotEmpty => _list.isNotEmpty; | 
| 128 | 247 | ||
| 129 | - Map<Stream<Change<E>>, StreamSubscription> _subscriptions = Map(); | ||
| 130 | - | ||
| 131 | - // StreamSubscription _changectl = StreamSubscription(); | ||
| 132 | - | ||
| 133 | - StreamController<Change<E>> _changeCtl = | ||
| 134 | - StreamController<Change<E>>.broadcast(); | ||
| 135 | - | ||
| 136 | - @override | ||
| 137 | - StreamController<Change<E>> subject = StreamController<Change<E>>.broadcast(); | 248 | + StreamController<E> subject = StreamController<E>.broadcast(); | 
| 249 | + Map<Stream<E>, StreamSubscription> _subscriptions = Map(); | ||
| 138 | 250 | ||
| 139 | /// Adds [item] only if [condition] resolves to true. | 251 | /// Adds [item] only if [condition] resolves to true. | 
| 140 | void addIf(condition, E item) { | 252 | void addIf(condition, E item) { | 
| @@ -150,7 +262,7 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | @@ -150,7 +262,7 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | ||
| 150 | 262 | ||
| 151 | operator []=(int index, E val) { | 263 | operator []=(int index, E val) { | 
| 152 | _list[index] = val; | 264 | _list[index] = val; | 
| 153 | - subject.add(Change<E>.set($new: val, pos: index)); | 265 | + subject.add(val); | 
| 154 | } | 266 | } | 
| 155 | 267 | ||
| 156 | E operator [](int index) { | 268 | E operator [](int index) { | 
| @@ -159,12 +271,12 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | @@ -159,12 +271,12 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | ||
| 159 | 271 | ||
| 160 | void add(E item) { | 272 | void add(E item) { | 
| 161 | _list.add(item); | 273 | _list.add(item); | 
| 162 | - subject.add(Change<E>.insert($new: item, pos: _list.length - 1)); | 274 | + subject.add(item); | 
| 163 | } | 275 | } | 
| 164 | 276 | ||
| 165 | - void addAll(List<E> item) { | 277 | + void addAll(Iterable<E> item) { | 
| 166 | _list.addAll(item); | 278 | _list.addAll(item); | 
| 167 | - subject.add(Change<E>.insert($new: _list, pos: _list.length - 1)); | 279 | + subject.add(null); | 
| 168 | } | 280 | } | 
| 169 | 281 | ||
| 170 | /// Adds only if [item] is not null. | 282 | /// Adds only if [item] is not null. | 
| @@ -179,12 +291,12 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | @@ -179,12 +291,12 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | ||
| 179 | 291 | ||
| 180 | void insert(int index, E item) { | 292 | void insert(int index, E item) { | 
| 181 | _list.insert(index, item); | 293 | _list.insert(index, item); | 
| 182 | - subject.add(Change<E>.insert($new: item, pos: index)); | 294 | + subject.add(item); | 
| 183 | } | 295 | } | 
| 184 | 296 | ||
| 185 | void insertAll(int index, Iterable<E> iterable) { | 297 | void insertAll(int index, Iterable<E> iterable) { | 
| 186 | _list.insertAll(index, iterable); | 298 | _list.insertAll(index, iterable); | 
| 187 | - subject.add(Change<E>.insert($new: iterable.last, pos: index)); | 299 | + subject.add(iterable.last); | 
| 188 | } | 300 | } | 
| 189 | 301 | ||
| 190 | int get length => value.length; | 302 | int get length => value.length; | 
| @@ -195,40 +307,38 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | @@ -195,40 +307,38 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | ||
| 195 | /// | 307 | /// | 
| 196 | /// Returns whether the item was present in the list. | 308 | /// Returns whether the item was present in the list. | 
| 197 | bool remove(Object item) { | 309 | bool remove(Object item) { | 
| 198 | - int pos = _list.indexOf(item); | ||
| 199 | bool hasRemoved = _list.remove(item); | 310 | bool hasRemoved = _list.remove(item); | 
| 200 | if (hasRemoved) { | 311 | if (hasRemoved) { | 
| 201 | - subject.add(Change<E>.remove($new: item, pos: pos)); | 312 | + subject.add(item); | 
| 202 | } | 313 | } | 
| 203 | return hasRemoved; | 314 | return hasRemoved; | 
| 204 | } | 315 | } | 
| 205 | 316 | ||
| 206 | E removeAt(int index) { | 317 | E removeAt(int index) { | 
| 207 | E item = _list.removeAt(index); | 318 | E item = _list.removeAt(index); | 
| 208 | - subject.add(Change<E>.remove($new: item, pos: index)); | 319 | + subject.add(item); | 
| 209 | return item; | 320 | return item; | 
| 210 | } | 321 | } | 
| 211 | 322 | ||
| 212 | E removeLast() { | 323 | E removeLast() { | 
| 213 | - int pos = _list.indexOf(_list.last); | ||
| 214 | E item = _list.removeLast(); | 324 | E item = _list.removeLast(); | 
| 215 | - subject.add(Change<E>.remove($new: item, pos: pos)); | 325 | + subject.add(item); | 
| 216 | return item; | 326 | return item; | 
| 217 | } | 327 | } | 
| 218 | 328 | ||
| 219 | void removeRange(int start, int end) { | 329 | void removeRange(int start, int end) { | 
| 220 | _list.removeRange(start, end); | 330 | _list.removeRange(start, end); | 
| 221 | - subject.add(Change<E>.remove($new: null, pos: null)); | 331 | + subject.add(null); | 
| 222 | } | 332 | } | 
| 223 | 333 | ||
| 224 | void removeWhere(bool Function(E) test) { | 334 | void removeWhere(bool Function(E) test) { | 
| 225 | _list.removeWhere(test); | 335 | _list.removeWhere(test); | 
| 226 | - subject.add(Change<E>.remove($new: null, pos: null)); | 336 | + subject.add(null); | 
| 227 | } | 337 | } | 
| 228 | 338 | ||
| 229 | void clear() { | 339 | void clear() { | 
| 230 | _list.clear(); | 340 | _list.clear(); | 
| 231 | - subject.add(Change<E>.clear()); | 341 | + subject.add(null); | 
| 232 | } | 342 | } | 
| 233 | 343 | ||
| 234 | close() { | 344 | close() { | 
| @@ -237,7 +347,6 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | @@ -237,7 +347,6 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | ||
| 237 | }); | 347 | }); | 
| 238 | _subscriptions.clear(); | 348 | _subscriptions.clear(); | 
| 239 | subject.close(); | 349 | subject.close(); | 
| 240 | - _changeCtl.close(); | ||
| 241 | } | 350 | } | 
| 242 | 351 | ||
| 243 | /// Replaces all existing items of this list with [item] | 352 | /// Replaces all existing items of this list with [item] | 
| @@ -252,17 +361,17 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | @@ -252,17 +361,17 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | ||
| 252 | addAll(items); | 361 | addAll(items); | 
| 253 | } | 362 | } | 
| 254 | 363 | ||
| 255 | - /// A stream of record of changes to this list | ||
| 256 | - Stream<Change<E>> get onChange { | ||
| 257 | - final now = DateTime.now(); | ||
| 258 | - | ||
| 259 | - _onChange.skipWhile((m) => m.time.isBefore(now)); | ||
| 260 | - return _changeCtl.stream.asBroadcastStream(); | 364 | + List<E> _value; | 
| 365 | + List<E> get value { | ||
| 366 | + if (getObs != null) { | ||
| 367 | + getObs.addListener(subject.stream); | ||
| 368 | + } | ||
| 369 | + return _value; | ||
| 261 | } | 370 | } | 
| 262 | 371 | ||
| 263 | - Stream<Change<E>> _onChange; | 372 | + String get string => value.toString(); | 
| 264 | 373 | ||
| 265 | - addListener(Stream<Change<E>> rxGetx) { | 374 | + addListener(Stream<E> rxGetx) { | 
| 266 | if (_subscriptions.containsKey(rxGetx)) { | 375 | if (_subscriptions.containsKey(rxGetx)) { | 
| 267 | return; | 376 | return; | 
| 268 | } | 377 | } | 
| @@ -271,50 +380,20 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | @@ -271,50 +380,20 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> { | ||
| 271 | }); | 380 | }); | 
| 272 | } | 381 | } | 
| 273 | 382 | ||
| 274 | - List<E> get value => v as List<E>; | ||
| 275 | - | ||
| 276 | - set value(List<E> va) => assignAll(va); | ||
| 277 | - | ||
| 278 | - @override | ||
| 279 | - get v { | ||
| 280 | - if (getObs != null) { | ||
| 281 | - getObs.addListener(subject.stream); | ||
| 282 | - } | ||
| 283 | - return _list; | ||
| 284 | - } | ||
| 285 | - | ||
| 286 | - set v(E val) { | ||
| 287 | - assign(val); | ||
| 288 | - } | ||
| 289 | - | ||
| 290 | - @override | ||
| 291 | - Stream<E> get stream => onChange.map((c) => c.$new); | ||
| 292 | - | ||
| 293 | - @override | ||
| 294 | - void bind(RxInterface<E> reactive) { | ||
| 295 | - v = reactive.v; | ||
| 296 | - reactive.stream.listen((va) => v = va); | 383 | + set value(Iterable<E> val) { | 
| 384 | + if (_value == val) return; | ||
| 385 | + _value = val; | ||
| 386 | + subject.add(null); | ||
| 297 | } | 387 | } | 
| 298 | 388 | ||
| 299 | - void bindStream(Stream<E> stream) => stream.listen((va) => v = va); | ||
| 300 | - | ||
| 301 | - @override | ||
| 302 | - void bindOrSet(/* T | Stream<T> or Rx<T> */ other) { | ||
| 303 | - if (other is RxInterface<E>) { | ||
| 304 | - bind(other); | ||
| 305 | - } else if (other is Stream<E>) { | ||
| 306 | - bindStream(other.cast<E>()); | ||
| 307 | - } else { | ||
| 308 | - v = other; | ||
| 309 | - } | ||
| 310 | - } | 389 | + Stream<E> get stream => subject.stream; | 
| 311 | 390 | ||
| 312 | - @override | ||
| 313 | - StreamSubscription<E> listen(ValueCallback<E> callback) => | ||
| 314 | - stream.listen(callback); | 391 | + StreamSubscription<E> listen(void Function(E) onData, | 
| 392 | + {Function onError, void Function() onDone, bool cancelOnError}) => | ||
| 393 | + stream.listen(onData, onError: onError, onDone: onDone); | ||
| 315 | 394 | ||
| 316 | - @override | ||
| 317 | - void setCast(dynamic val) => v = val; | 395 | + void bindStream(Stream<Iterable<E>> stream) => | 
| 396 | + stream.listen((va) => value = va); | ||
| 318 | 397 | ||
| 319 | List<E> _list = <E>[]; | 398 | List<E> _list = <E>[]; | 
| 320 | } | 399 | } | 
| @@ -328,64 +407,49 @@ typedef E ChildrenListComposer<S, E>(S value); | @@ -328,64 +407,49 @@ typedef E ChildrenListComposer<S, E>(S value); | ||
| 328 | class BoolX<bool> extends _RxImpl<bool> { | 407 | class BoolX<bool> extends _RxImpl<bool> { | 
| 329 | BoolX([bool initial]) { | 408 | BoolX([bool initial]) { | 
| 330 | _value = initial; | 409 | _value = initial; | 
| 331 | - _onChange = subject.stream.asBroadcastStream(); | ||
| 332 | } | 410 | } | 
| 333 | } | 411 | } | 
| 334 | 412 | ||
| 335 | class DoubleX<double> extends _RxImpl<double> { | 413 | class DoubleX<double> extends _RxImpl<double> { | 
| 336 | DoubleX([double initial]) { | 414 | DoubleX([double initial]) { | 
| 337 | _value = initial; | 415 | _value = initial; | 
| 338 | - _onChange = subject.stream.asBroadcastStream(); | ||
| 339 | } | 416 | } | 
| 340 | } | 417 | } | 
| 341 | 418 | ||
| 342 | class NumX<num> extends _RxImpl<num> { | 419 | class NumX<num> extends _RxImpl<num> { | 
| 343 | NumX([num initial]) { | 420 | NumX([num initial]) { | 
| 344 | _value = initial; | 421 | _value = initial; | 
| 345 | - _onChange = subject.stream.asBroadcastStream(); | ||
| 346 | } | 422 | } | 
| 347 | } | 423 | } | 
| 348 | 424 | ||
| 349 | class Rx<T> extends _RxImpl<T> { | 425 | class Rx<T> extends _RxImpl<T> { | 
| 350 | Rx([T initial]) { | 426 | Rx([T initial]) { | 
| 351 | _value = initial; | 427 | _value = initial; | 
| 352 | - _onChange = subject.stream.asBroadcastStream(); | ||
| 353 | } | 428 | } | 
| 354 | } | 429 | } | 
| 355 | 430 | ||
| 356 | extension StringExtension on String { | 431 | extension StringExtension on String { | 
| 357 | - StringX<String> get obs { | ||
| 358 | - if (this != null) | ||
| 359 | - return StringX(this); | ||
| 360 | - else | ||
| 361 | - return StringX(null); | ||
| 362 | - } | 432 | + StringX<String> get obs => StringX(this); | 
| 363 | } | 433 | } | 
| 364 | 434 | ||
| 365 | extension IntExtension on int { | 435 | extension IntExtension on int { | 
| 366 | - IntX<int> get obs { | ||
| 367 | - if (this != null) | ||
| 368 | - return IntX(this); | ||
| 369 | - else | ||
| 370 | - return IntX(null); | ||
| 371 | - } | 436 | + IntX<int> get obs => IntX(this); | 
| 372 | } | 437 | } | 
| 373 | 438 | ||
| 374 | extension DoubleExtension on double { | 439 | extension DoubleExtension on double { | 
| 375 | - DoubleX<double> get obs { | ||
| 376 | - if (this != null) | ||
| 377 | - return DoubleX(this); | ||
| 378 | - else | ||
| 379 | - return DoubleX(null); | ||
| 380 | - } | 440 | + DoubleX<double> get obs => DoubleX(this); | 
| 441 | +} | ||
| 442 | + | ||
| 443 | +extension BoolExtension on bool { | ||
| 444 | + BoolX<bool> get obs => BoolX(this); | ||
| 381 | } | 445 | } | 
| 382 | 446 | ||
| 383 | -extension MapExtension on Map { | ||
| 384 | - MapX<Map> get obs { | 447 | +extension MapExtension<K, V> on Map<K, V> { | 
| 448 | + MapX<K, V> get obs { | ||
| 385 | if (this != null) | 449 | if (this != null) | 
| 386 | - return MapX(this); | 450 | + return MapX<K, V>({})..addAll(this); | 
| 387 | else | 451 | else | 
| 388 | - return MapX(null); | 452 | + return MapX<K, V>(null); | 
| 389 | } | 453 | } | 
| 390 | } | 454 | } | 
| 391 | 455 | ||
| @@ -398,20 +462,6 @@ extension ListExtension<E> on List<E> { | @@ -398,20 +462,6 @@ extension ListExtension<E> on List<E> { | ||
| 398 | } | 462 | } | 
| 399 | } | 463 | } | 
| 400 | 464 | ||
| 401 | -extension BoolExtension on bool { | ||
| 402 | - BoolX<bool> get obs { | ||
| 403 | - if (this != null) | ||
| 404 | - return BoolX(this); | ||
| 405 | - else | ||
| 406 | - return BoolX(null); | ||
| 407 | - } | ||
| 408 | -} | ||
| 409 | - | ||
| 410 | extension ObjectExtension on Object { | 465 | extension ObjectExtension on Object { | 
| 411 | - Rx<Object> get obs { | ||
| 412 | - if (this != null) | ||
| 413 | - return Rx(this); | ||
| 414 | - else | ||
| 415 | - return Rx(null); | ||
| 416 | - } | 466 | + Rx<Object> get obs => Rx(this); | 
| 417 | } | 467 | } | 
| 1 | import 'dart:async'; | 1 | import 'dart:async'; | 
| 2 | +import 'package:flutter/scheduler.dart'; | ||
| 2 | import 'package:get/src/rx/rx_callbacks.dart'; | 3 | import 'package:get/src/rx/rx_callbacks.dart'; | 
| 3 | -import 'package:get/src/rx/rx_model.dart'; | ||
| 4 | 4 | ||
| 5 | abstract class RxInterface<T> { | 5 | abstract class RxInterface<T> { | 
| 6 | RxInterface([T initial]); | 6 | RxInterface([T initial]); | 
| 7 | 7 | ||
| 8 | - /// Get current value | ||
| 9 | - get v; | ||
| 10 | - | ||
| 11 | - /// Set value | ||
| 12 | - set v(T val); | ||
| 13 | - | ||
| 14 | - /// Cast [val] to [T] before setting | ||
| 15 | - void setCast(dynamic /* T */ val); | ||
| 16 | - | ||
| 17 | - /// Stream of record of [Change]s of value | ||
| 18 | - // Stream<Change<T>> get onChange; | ||
| 19 | - | ||
| 20 | /// add listener to stream | 8 | /// add listener to stream | 
| 21 | - addListener(Stream<Change<T>> rxGetx); | 9 | + addListener(Stream<T> rxGetx); | 
| 22 | 10 | ||
| 23 | /// close stream | 11 | /// close stream | 
| 24 | close() { | 12 | close() { | 
| 25 | subject?.close(); | 13 | subject?.close(); | 
| 26 | } | 14 | } | 
| 27 | 15 | ||
| 28 | - StreamController<Change<T>> subject; | ||
| 29 | - | ||
| 30 | - /// Stream of changes of value | ||
| 31 | - Stream<T> get stream; | 16 | + StreamController<T> subject; | 
| 32 | 17 | ||
| 33 | /// Convert value on string | 18 | /// Convert value on string | 
| 34 | // String get string; | 19 | // String get string; | 
| 35 | 20 | ||
| 36 | - /// Binds if [other] is [Stream] or [RxInterface] of type [T]. Sets if [other] is | ||
| 37 | - /// instance of [T] | ||
| 38 | - void bindOrSet(/* T | Stream<T> | Reactive<T> */ other); | ||
| 39 | - | ||
| 40 | - /// Binds [other] to this | ||
| 41 | - void bind(RxInterface<T> other); | ||
| 42 | - | ||
| 43 | - /// Binds the [stream] to this | ||
| 44 | - void bindStream(Stream<T> stream); | ||
| 45 | - | ||
| 46 | /// Calls [callback] with current value, when the value changes. | 21 | /// Calls [callback] with current value, when the value changes. | 
| 47 | StreamSubscription<T> listen(ValueCallback<T> callback); | 22 | StreamSubscription<T> listen(ValueCallback<T> callback); | 
| 48 | 23 | ||
| @@ -50,12 +25,33 @@ abstract class RxInterface<T> { | @@ -50,12 +25,33 @@ abstract class RxInterface<T> { | ||
| 50 | // Stream<S> map<S>(S mapper(T data)); | 25 | // Stream<S> map<S>(S mapper(T data)); | 
| 51 | } | 26 | } | 
| 52 | 27 | ||
| 53 | -class RxController implements DisposableInterface { | 28 | +class RxController extends DisposableInterface { | 
| 29 | + @override | ||
| 54 | void onInit() async {} | 30 | void onInit() async {} | 
| 31 | + | ||
| 32 | + @override | ||
| 33 | + void onReady() async {} | ||
| 34 | + | ||
| 35 | + @override | ||
| 55 | void onClose() async {} | 36 | void onClose() async {} | 
| 56 | } | 37 | } | 
| 57 | 38 | ||
| 58 | abstract class DisposableInterface { | 39 | abstract class DisposableInterface { | 
| 59 | - void onClose() async {} | 40 | + /// Called at the exact moment that the widget is allocated in memory. | 
| 41 | + /// Do not overwrite this method. | ||
| 42 | + void onStart() { | ||
| 43 | + onInit(); | ||
| 44 | + SchedulerBinding.instance.addPostFrameCallback((_) => onReady()); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + /// Called Called immediately after the widget is allocated in memory. | ||
| 60 | void onInit() async {} | 48 | void onInit() async {} | 
| 49 | + | ||
| 50 | + /// Called after rendering the screen. It is the perfect place to enter navigation events, | ||
| 51 | + /// be it snackbar, dialogs, or a new route. | ||
| 52 | + void onReady() async {} | ||
| 53 | + | ||
| 54 | + /// Called before the onDelete method. onClose is used to close events | ||
| 55 | + /// before the controller is destroyed, such as closing streams, for example. | ||
| 56 | + void onClose() async {} | ||
| 61 | } | 57 | } | 
| @@ -5,10 +5,17 @@ import 'package:get/src/rx/rx_interface.dart'; | @@ -5,10 +5,17 @@ import 'package:get/src/rx/rx_interface.dart'; | ||
| 5 | import '../get_main.dart'; | 5 | import '../get_main.dart'; | 
| 6 | 6 | ||
| 7 | class GetController extends DisposableInterface { | 7 | class GetController extends DisposableInterface { | 
| 8 | - void onClose() async {} | ||
| 9 | - void onInit() async {} | ||
| 10 | List<RealState> _allStates = []; | 8 | List<RealState> _allStates = []; | 
| 11 | 9 | ||
| 10 | + @override | ||
| 11 | + void onInit() async {} | ||
| 12 | + | ||
| 13 | + @override | ||
| 14 | + void onReady() async {} | ||
| 15 | + | ||
| 16 | + @override | ||
| 17 | + void onClose() async {} | ||
| 18 | + | ||
| 12 | /// Update GetBuilder with update(); | 19 | /// Update GetBuilder with update(); | 
| 13 | void update([List<String> ids, bool condition = true]) { | 20 | void update([List<String> ids, bool condition = true]) { | 
| 14 | if (!condition) return; | 21 | if (!condition) return; | 
| @@ -93,11 +100,11 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | @@ -93,11 +100,11 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | ||
| 93 | isCreator = true; | 100 | isCreator = true; | 
| 94 | real = RealState(updater: setState, id: widget.id); | 101 | real = RealState(updater: setState, id: widget.id); | 
| 95 | controller._allStates.add(real); | 102 | controller._allStates.add(real); | 
| 96 | - controller?.onInit(); | 103 | + controller?.onStart(); | 
| 97 | } | 104 | } | 
| 98 | if (widget.initState != null) widget.initState(this); | 105 | if (widget.initState != null) widget.initState(this); | 
| 99 | if (isCreator && Get().smartManagement == SmartManagement.onlyBuilder) { | 106 | if (isCreator && Get().smartManagement == SmartManagement.onlyBuilder) { | 
| 100 | - controller?.onInit(); | 107 | + controller?.onStart(); | 
| 101 | } | 108 | } | 
| 102 | } | 109 | } | 
| 103 | 110 | 
| @@ -120,7 +120,7 @@ packages: | @@ -120,7 +120,7 @@ packages: | ||
| 120 | name: test_api | 120 | name: test_api | 
| 121 | url: "https://pub.dartlang.org" | 121 | url: "https://pub.dartlang.org" | 
| 122 | source: hosted | 122 | source: hosted | 
| 123 | - version: "0.2.15" | 123 | + version: "0.2.16" | 
| 124 | typed_data: | 124 | typed_data: | 
| 125 | dependency: transitive | 125 | dependency: transitive | 
| 126 | description: | 126 | description: | 
| @@ -136,4 +136,4 @@ packages: | @@ -136,4 +136,4 @@ packages: | ||
| 136 | source: hosted | 136 | source: hosted | 
| 137 | version: "2.0.8" | 137 | version: "2.0.8" | 
| 138 | sdks: | 138 | sdks: | 
| 139 | - dart: ">=2.6.0 <3.0.0" | 139 | + dart: ">=2.7.0 <3.0.0" | 
| 1 | name: get | 1 | name: get | 
| 2 | description: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get. | 2 | description: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get. | 
| 3 | -version: 2.11.3 | 3 | +version: 2.12.1 | 
| 4 | homepage: https://github.com/jonataslaw/get | 4 | homepage: https://github.com/jonataslaw/get | 
| 5 | 5 | ||
| 6 | environment: | 6 | environment: | 
- 
Please register or login to post a comment