LCOV - code coverage report
Current view: top level - src/graph - notifier_extension.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 42 42 100.0 %
Date: 2020-07-30 22:52:57 Functions: 0 0 -

          Line data    Source code
       1             : library notifier_extension;
       2             : 
       3             : import 'dart:async';
       4             : 
       5             : import 'package:state_notifier/state_notifier.dart';
       6             : 
       7             : class _FunctionalStateNotifier<S, T> extends StateNotifier<T> {
       8             :   final StateNotifier<S> _source;
       9             :   final String name;
      10           2 :   _FunctionalStateNotifier(this._source, {this.name}) : super(null);
      11             :   RemoveListener _sourceDisposeFn;
      12             :   Timer _timer;
      13             : 
      14           1 :   StateNotifier<T> where(bool Function(S) test) {
      15           4 :     _sourceDisposeFn = _source.addListener((_state) {
      16           1 :       if (test(_state)) {
      17           1 :         state = _state as T;
      18             :       }
      19             :     }, fireImmediately: false);
      20             :     return this;
      21             :   }
      22             : 
      23           1 :   StateNotifier<void> forEach(void Function(S) action) {
      24           3 :     _sourceDisposeFn = _source.addListener(action, fireImmediately: false);
      25             :     return this;
      26             :   }
      27             : 
      28           1 :   StateNotifier<T> map(T Function(S) convert) {
      29           4 :     _sourceDisposeFn = _source.addListener((state) {
      30           2 :       super.state = convert(state);
      31             :     }, fireImmediately: false);
      32             :     return this;
      33             :   }
      34             : 
      35             :   final _bufferedState = <S>[];
      36             : 
      37           1 :   StateNotifier<T> throttle(Duration duration) {
      38           2 :     _timer = _makeTimer(duration);
      39           4 :     _sourceDisposeFn = _source.addListener((model) {
      40           2 :       _bufferedState.add(model);
      41             :     }, fireImmediately: false);
      42             :     return this;
      43             :   }
      44             : 
      45           1 :   Timer _makeTimer(Duration duration) {
      46           2 :     return Timer(duration, () {
      47           1 :       if (mounted) {
      48           2 :         if (_bufferedState.isNotEmpty) {
      49           2 :           super.state = _bufferedState as T; // since T == List<S>;
      50           2 :           _bufferedState.clear(); // clear buffer
      51             :         }
      52           2 :         _timer = _makeTimer(duration); // reset timer
      53             :       }
      54             :     });
      55             :   }
      56             : 
      57           1 :   @override
      58             :   RemoveListener addListener(
      59             :     Listener<T> listener, {
      60             :     bool fireImmediately = true,
      61             :   }) {
      62             :     final dispose =
      63           1 :         super.addListener(listener, fireImmediately: fireImmediately);
      64           1 :     return () {
      65           1 :       dispose.call();
      66           2 :       _timer?.cancel();
      67           2 :       _sourceDisposeFn?.call();
      68             :     };
      69             :   }
      70             : 
      71           1 :   @override
      72             :   void dispose() {
      73           1 :     if (mounted) {
      74           1 :       super.dispose();
      75             :     }
      76           2 :     _source.dispose();
      77           2 :     _timer?.cancel();
      78             :   }
      79             : }
      80             : 
      81             : /// Functional utilities for [StateNotifier]
      82             : extension StateNotifierX<T> on StateNotifier<T> {
      83             :   /// Filters incoming events by [test]
      84           1 :   StateNotifier<T> where(bool Function(T) test) {
      85           2 :     return _FunctionalStateNotifier<T, T>(this, name: 'where').where(test);
      86             :   }
      87             : 
      88             :   /// Maps events of type [T] onto events of type [R] via [convert]
      89           1 :   StateNotifier<R> map<R>(R Function(T) convert) {
      90           2 :     return _FunctionalStateNotifier<T, R>(this, name: 'map').map(convert);
      91             :   }
      92             : 
      93             :   /// Applies a function [action] to every incoming event of type [T]
      94           1 :   StateNotifier<void> forEach(void Function(T) action) {
      95           1 :     return _FunctionalStateNotifier<T, void>(this, name: 'forEach')
      96           1 :         .forEach(action);
      97             :   }
      98             : 
      99             :   /// Buffers all incoming [T] events during [duration] and emits
     100             :   /// them as a [List<T>] (unless there were none)
     101           1 :   StateNotifier<List<T>> throttle(Duration duration) {
     102           1 :     return _FunctionalStateNotifier<T, List<T>>(this, name: 'throttle')
     103           1 :         .throttle(duration);
     104             :   }
     105             : }

Generated by: LCOV version 1.14