Line data Source code
1 : // ignore_for_file: hash_and_equals 2 : 3 : import 'package:meta/meta.dart'; 4 : 5 : typedef CreatorCallback<E, A> = E Function(Ref<A> ref); 6 : 7 : class Creator<E, A> { 8 4 : Creator(this._callback, this._autoDispose); 9 : 10 : final CreatorCallback<E, A> _callback; 11 : 12 : /// callback to override the main creator callback 13 : CreatorCallback<E, A>? _overriddenCallback; 14 : 15 : final bool _autoDispose; 16 : 17 : /// boolean to override the main autoDispose 18 : bool? _overriddenAutoDispose; 19 : 20 12 : CreatorCallback<E, A> get callback => _overriddenCallback ?? _callback; 21 12 : bool get autoDispose => _overriddenAutoDispose ?? _autoDispose; 22 : 23 1 : @protected 24 : void overrideCreator( 25 : CreatorCallback<E, A> callback, { 26 : bool? autoDispose, 27 : }) { 28 1 : _overriddenCallback = callback; 29 1 : _overriddenAutoDispose = autoDispose; 30 : } 31 : 32 1 : void resetCreator() { 33 1 : _overriddenCallback = null; 34 1 : _overriddenAutoDispose = null; 35 : } 36 : 37 : @override // coverage:ignore-line 38 : int get hashCode => _cachedHash; // coverage:ignore-line 39 : final int _cachedHash = _nextHashCode = (_nextHashCode + 1) % 0xffffff; 40 : static int _nextHashCode = 1; 41 : } 42 : 43 : /// Base class uses to represents the Element created by a provider 44 : class Element<E> { 45 4 : Element({ 46 : required this.ref, 47 : }); 48 : 49 : final Ref ref; 50 : E? _value; 51 8 : E? get value => _value; 52 : 53 8 : void set(E value) => _value = value; 54 : } 55 : 56 : class FactoryElement<E, A> extends Element<E> { 57 1 : FactoryElement({required super.ref}); 58 : 59 1 : @override 60 1 : E get value => _value!; 61 : 62 3 : void dispose() => ref.dispose(); 63 : } 64 : 65 : /// Reference use to store arguments before create an [Element] 66 : /// and listen when an [Element] has been disposed 67 : class Ref<A> { 68 4 : Ref({ 69 : required this.tag, 70 : }); 71 : 72 : final String? tag; 73 : 74 : A? _arguments; 75 2 : A get arguments { 76 : assert( 77 2 : _arguments != null, 78 : 'arguments not initialized, make sure to call to ypurProvoder.setArguments(...) before', 79 : ); 80 2 : return _arguments!; 81 : } 82 : 83 : void Function()? _onDisposeCallback; 84 : 85 4 : void setArguments(A args) => _arguments = args; 86 : 87 2 : void onDispose(void Function() callback) => _onDisposeCallback = callback; 88 : 89 4 : @protected 90 5 : void dispose() => _onDisposeCallback?.call(); 91 : } 92 : 93 : class ProvidersContainer { 94 4 : ProvidersContainer._(); 95 : 96 : /// SINGLETON 97 12 : static final _instance = ProvidersContainer._(); 98 8 : static ProvidersContainer get instance => _instance; 99 : 100 : /// store the elements 101 : final _elements = <String, Element>{}; 102 8 : Map<String, Element> get elements => _elements; 103 : 104 : final _overriddenCreators = <int, Creator>{}; 105 2 : Map<int, Creator> get overriddenCreators => _overriddenCreators; 106 : 107 : /// use this function for testing in your 108 : /// setUp or tearDown 109 4 : @visibleForTesting 110 : static void clear() { 111 13 : for (final e in _instance.elements.values) { 112 2 : e.ref.dispose(); 113 : } 114 : 115 13 : for (final creator in _instance._overriddenCreators.values) { 116 1 : creator.resetCreator(); 117 : } 118 : 119 12 : _instance._overriddenCreators.clear(); 120 12 : _instance.elements.clear(); 121 : } 122 : }