LCOV - code coverage report
Current view: top level - src/notifiers - list_change_notifier.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 88 88 100.0 %
Date: 2020-08-02 01:39:25 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:collection';
       2             : import 'dart:math';
       3             : 
       4             : import 'package:flutter/foundation.dart';
       5             : import 'package:collection_providers/collection_providers.dart';
       6             : 
       7             : /// An implementation of [ChangeNotifier] that allows implementers to interact
       8             : /// with this provider as if it were a [Map] and be notified when any changes
       9             : /// to the map have been made
      10             : ///
      11             : /// Like [ChangeNotifier], this is optimized for small numbers of listeners.
      12             : /// It is O(N) for adding and removing listeners.
      13             : ///
      14             : /// [K] is the type of the Key to be used by this map. It is usually a [String],
      15             : /// but can be any subclass of [Object]. It must implement `operator==` and
      16             : /// `hashCode`
      17             : ///
      18             : /// [T] is the type of the Value to be used by this map. It can be any subclass
      19             : /// of [Object] and has no special requirements.
      20             : class ListChangeNotifier<T> extends CollectionChangeNotifier with ListMixin<T> {
      21             :   List<T> _list;
      22             : 
      23           2 :   ListChangeNotifier([List<T> backingList]) {
      24           6 :     _list = List<T>.from(backingList ?? []);
      25             :   }
      26             : 
      27             :   /// The number of objects in this list.
      28             :   ///
      29             :   /// The valid indices for a list are `0` through `length - 1`
      30           1 :   @override
      31             :   int get length {
      32           1 :     assert(_debugAssertNotDisposed());
      33           2 :     return _list.length;
      34             :   }
      35             : 
      36             :   /// Changes the length of this list.
      37             :   /// Does not notify listeners.
      38             :   ///
      39             :   /// If [newLength] is greater than the current length, entries are initialized to `null`.
      40           1 :   @override
      41             :   set length(int newLength) {
      42           1 :     assert(_debugAssertNotDisposed());
      43           2 :     _list.length = newLength;
      44             :   }
      45             : 
      46             :   /// Returns the object at the given [index] in the list
      47             :   /// or throws a [RangeError] if [index] is out of bounds.
      48           1 :   @override
      49             :   T operator [](int index) {
      50           1 :     assert(_debugAssertNotDisposed());
      51           2 :     return _list[index];
      52             :   }
      53             : 
      54             :   /// Sets the value at the given [index] in the list to [value]
      55             :   /// or throws a [RangeError] if [index] is out of bounds.
      56           1 :   @override
      57             :   void operator []=(int index, T value) {
      58           1 :     assert(_debugAssertNotDisposed());
      59           2 :     _list[index] = value;
      60           1 :     notifyListeners();
      61             :   }
      62             : 
      63             :   /// Clear all objects from the list.
      64             :   /// Listeners are notified after the list is cleared.
      65           1 :   @override
      66             :   void clear() {
      67           1 :     assert(_debugAssertNotDisposed());
      68           1 :     super.clear();
      69           1 :     notifyListeners();
      70             :   }
      71             : 
      72             :   /// Appends all objects of [iterable] to the end of the list.
      73             :   /// Listeners are notified after all objects have been added.
      74             :   ///
      75             :   /// Extends the length of the list by the number of objects in [iterable].
      76           1 :   @override
      77             :   void addAll(Iterable<T> iterable) {
      78           1 :     assert(_debugAssertNotDisposed());
      79           1 :     assert(iterable != null);
      80           2 :     _list.addAll(iterable);
      81           1 :     notifyListeners();
      82             :   }
      83             : 
      84             :   /// Removes all objects from this list that satisfy [test].
      85             :   /// Listeners are notified after all objects have been removed.
      86             :   ///
      87             :   /// An object [:o:] satisfies [test] if [:test(o):] is true.
      88           1 :   @override
      89             :   void removeWhere(bool Function(T element) test) {
      90           1 :     assert(_debugAssertNotDisposed());
      91           1 :     assert(test != null);
      92           2 :     _list.removeWhere(test);
      93           1 :     notifyListeners();
      94             :   }
      95             : 
      96             :   /// Removes all objects from the list that fail to satisfy [test].
      97             :   /// Listeners are notified after all objects have been removed.
      98             :   ///
      99             :   /// An object [:o:] satisfies [test] if [:test(o):] is true.
     100           1 :   @override
     101             :   void retainWhere(bool Function(T element) test) {
     102           1 :     assert(_debugAssertNotDisposed());
     103           1 :     assert(test != null);
     104           2 :     _list.retainWhere(test);
     105           1 :     notifyListeners();
     106             :   }
     107             : 
     108             :   /// Sorts this list according to the order specified by the [compare] function.
     109             :   /// Listeners are notified after sorting is completed.
     110             :   ///
     111             :   /// The [compare] function must act as a [Comparator].
     112             :   /// The default List implementations use [Comparable.compare] if [compare] is omitted.
     113           1 :   @override
     114             :   void sort([int Function(T a, T b) compare]) {
     115           1 :     assert(_debugAssertNotDisposed());
     116           2 :     _list.sort(compare);
     117           1 :     notifyListeners();
     118             :   }
     119             : 
     120             :   /// Shuffles the elements of this list randomly.
     121             :   /// Listeners are notified after shuffling is completed.
     122           1 :   @override
     123             :   void shuffle([Random random]) {
     124           1 :     assert(_debugAssertNotDisposed());
     125           2 :     _list.shuffle(random);
     126           1 :     notifyListeners();
     127             :   }
     128             : 
     129             :   /// Removes the objects in the range [start] inclusive to [end] exclusive.
     130             :   /// Listeners are notified after all objects are removed.
     131             :   ///
     132             :   /// The provided range, given by [start] to [end], must be valid.
     133             :   /// A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
     134             :   /// `len` ist he list's `length`. The range starts at `start` and has length
     135             :   /// `end - start`. An empty range (with `end == start`) is valid.
     136           1 :   @override
     137             :   void removeRange(int start, int end) {
     138           1 :     assert(_debugAssertNotDisposed());
     139           2 :     _list.removeRange(start, end);
     140           1 :     notifyListeners();
     141             :   }
     142             : 
     143             :   /// Sets the objects in the range [start] inclusive to [end] exclusive to the
     144             :   /// given [fill]
     145             :   /// Listeners are notified after all objects are updated.
     146             :   ///
     147             :   /// The provided range, given by [start] to [end], must be valid.
     148             :   /// A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
     149             :   /// `len` ist he list's `length`. The range starts at `start` and has length
     150             :   /// `end - start`. An empty range (with `end == start`) is valid.
     151           1 :   @override
     152             :   void fillRange(int start, int end, [T fill]) {
     153           1 :     assert(_debugAssertNotDisposed());
     154           2 :     _list.fillRange(start, end, fill);
     155           1 :     notifyListeners();
     156             :   }
     157             : 
     158             :   /// Copies the objects of [iterable], skipping [skipCount] object first, into
     159             :   /// the range [start] inclusive to [end] exclusive of the list.
     160             :   /// Listeners are notified after all the values have been set.
     161             :   ///
     162             :   /// The provided range, given by [start] to [end], must be valid.
     163             :   /// A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
     164             :   /// `len` ist he list's `length`. The range starts at `start` and has length
     165             :   /// `end - start`. An empty range (with `end == start`) is valid.
     166             :   ///
     167             :   /// The [iterable] must have enough objects to fill the range from [start] to
     168             :   /// [end] after skipping [skipCount] objects.
     169             :   ///
     170             :   /// If [iterable] is this list, the operation copies the elements originally
     171             :   /// in the range from `skipCount` to `skipCount + (end - start)` to the range
     172             :   /// `start` to `end`, even if the two ranges overlap.
     173             :   ///
     174             :   /// If [iterable] depends on this list in some other way, no guarantees are made.
     175           1 :   @override
     176             :   void setRange(int start, int end, Iterable<T> iterable, [int skipCount = 0]) {
     177           1 :     assert(_debugAssertNotDisposed());
     178           1 :     assert(iterable != null);
     179           2 :     _list.setRange(start, end, iterable, skipCount);
     180           1 :     notifyListeners();
     181             :   }
     182             : 
     183             :   /// Removes the objects in the range [start] inclusive to [end] exclusive and
     184             :   /// inserts the contents of [newContents] in its place.
     185             :   /// Listeners are notified after all the objects have been replaced.
     186             :   ///
     187             :   /// The provided range, given by [start] to [end], must be valid.
     188             :   /// A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
     189             :   /// `len` is the list's `length`. The range starts at `start` and has length
     190             :   /// `end - start`. An empty range (with `end == start`) is valid.
     191           1 :   @override
     192             :   void replaceRange(int start, int end, Iterable<T> newContents) {
     193           1 :     assert(_debugAssertNotDisposed());
     194           1 :     assert(newContents != null);
     195           2 :     _list.replaceRange(start, end, newContents);
     196           1 :     notifyListeners();
     197             :   }
     198             : 
     199             :   /// Insert [element] at the position [index] in this list.
     200             :   /// Listeners are notified after all objects have been repositioned.
     201             :   ///
     202             :   /// This increases the length of the list by one and shifts all objects at or
     203             :   /// after the index towards the end of the list.
     204             :   ///
     205             :   /// The [index] value must be non-negative and no greater than [length].
     206           1 :   @override
     207             :   void insert(int index, T element) {
     208           1 :     assert(_debugAssertNotDisposed());
     209           2 :     _list.insert(index, element);
     210           1 :     notifyListeners();
     211             :   }
     212             : 
     213             :   /// Removes the object at position [index] from the list.
     214             :   /// Listeners are notified after all objects have been repositioned.
     215             :   ///
     216             :   /// This method reduces the length of `this` by one and moves all later objects
     217             :   /// down by one position.
     218             :   ///
     219             :   /// Returns the removed object.
     220             :   ///
     221             :   /// The [index] must be in the range `0 ≤ index < length`.
     222           1 :   @override
     223             :   T removeAt(int index) {
     224           1 :     assert(_debugAssertNotDisposed());
     225           2 :     final result = _list.removeAt(index);
     226           1 :     notifyListeners();
     227             :     return result;
     228             :   }
     229             : 
     230             :   /// Inserts all objects of [iterable] at position [index] in this list.
     231             :   /// Listeners are notified after all objects have been inserted.
     232             :   ///
     233             :   /// This increases the length of the list by the length of [iterable] and
     234             :   /// shifts all later objects towards the end of the list.
     235             :   ///
     236             :   /// The [index] value must be non-negative and no greater than [length].
     237           1 :   @override
     238             :   void insertAll(int index, Iterable<T> iterable) {
     239           1 :     assert(_debugAssertNotDisposed());
     240           1 :     assert(iterable != null);
     241           2 :     _list.insertAll(index, iterable);
     242           1 :     notifyListeners();
     243             :   }
     244             : 
     245             :   /// Overwrites objects of `this` with the objects of [iterable] start at
     246             :   /// positions [index] in this list.
     247             :   /// Listeners are notified after all objects have been set.
     248             :   ///
     249             :   /// This operation does not icrease the length of `this`.
     250             :   ///
     251             :   /// The [index] must be non-negative and no greater than [length].
     252             :   ///
     253             :   /// The [iterable] must not have more elements than what can fit from [index]
     254             :   /// to [length].
     255             :   ///
     256             :   /// if `iterable` is based on this list, its values may change /during/ the
     257             :   /// `setAll` operation.
     258           1 :   @override
     259             :   void setAll(int index, Iterable<T> iterable) {
     260           1 :     assert(_debugAssertNotDisposed());
     261           1 :     assert(iterable != null);
     262           2 :     _list.setAll(index, iterable);
     263           1 :     notifyListeners();
     264             :   }
     265             : 
     266             :   /// Discards the internal resources used by the object.
     267             :   /// After this is called, the object is not in a usable state and should be discarded.
     268             :   ///
     269             :   /// This method should only be called by the object's owner.
     270           2 :   @override
     271             :   @mustCallSuper
     272             :   void dispose() {
     273           2 :     assert(_debugAssertNotDisposed());
     274           2 :     _list = null;
     275           2 :     super.dispose();
     276             :   }
     277             : 
     278             :   /// Reimplemented from [ChangeNotifier]
     279           2 :   bool _debugAssertNotDisposed() {
     280           2 :     assert(() {
     281           2 :       if (_list == null) {
     282           3 :         throw FlutterError('A $runtimeType was used after being disposed\n'
     283           1 :             'Once you have called dispose() on a $runtimeType it can no longer by used.');
     284             :       }
     285             :       return true;
     286           2 :     }());
     287             :     return true;
     288             :   }
     289             : }

Generated by: LCOV version 1.13