Jonny Borges

dry

@@ -21,6 +21,6 @@ @@ -21,6 +21,6 @@
21 <key>CFBundleVersion</key> 21 <key>CFBundleVersion</key>
22 <string>1.0</string> 22 <string>1.0</string>
23 <key>MinimumOSVersion</key> 23 <key>MinimumOSVersion</key>
24 - <string>8.0</string> 24 + <string>9.0</string>
25 </dict> 25 </dict>
26 </plist> 26 </plist>
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 archiveVersion = 1; 3 archiveVersion = 1;
4 classes = { 4 classes = {
5 }; 5 };
6 - objectVersion = 46; 6 + objectVersion = 50;
7 objects = { 7 objects = {
8 8
9 /* Begin PBXBuildFile section */ 9 /* Begin PBXBuildFile section */
@@ -127,7 +127,7 @@ @@ -127,7 +127,7 @@
127 97C146E61CF9000F007C117D /* Project object */ = { 127 97C146E61CF9000F007C117D /* Project object */ = {
128 isa = PBXProject; 128 isa = PBXProject;
129 attributes = { 129 attributes = {
130 - LastUpgradeCheck = 1020; 130 + LastUpgradeCheck = 1300;
131 ORGANIZATIONNAME = ""; 131 ORGANIZATIONNAME = "";
132 TargetAttributes = { 132 TargetAttributes = {
133 97C146ED1CF9000F007C117D = { 133 97C146ED1CF9000F007C117D = {
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <Scheme 2 <Scheme
3 - LastUpgradeVersion = "1020" 3 + LastUpgradeVersion = "1300"
4 version = "1.3"> 4 version = "1.3">
5 <BuildAction 5 <BuildAction
6 parallelizeBuildables = "YES" 6 parallelizeBuildables = "YES"
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 import 'package:get/get.dart'; 2 import 'package:get/get.dart';
3 3
4 -import 'app/routes/app_pages.dart';  
5 -import 'services/auth_service.dart';  
6 -  
7 void main() { 4 void main() {
8 runApp( 5 runApp(
9 - GetMaterialApp.router(  
10 - title: "Application",  
11 - initialBinding: BindingsBuilder(  
12 - () {  
13 - Get.put(AuthService());  
14 - }, 6 + GetMaterialApp(
  7 + home: Home(),
15 ), 8 ),
16 - getPages: AppPages.routes,  
17 - // routeInformationParser: GetInformationParser(  
18 - // // initialRoute: Routes.HOME,  
19 - // ),  
20 - // routerDelegate: GetDelegate(  
21 - // backButtonPopMode: PopMode.History,  
22 - // preventDuplicateHandlingMode:  
23 - // PreventDuplicateHandlingMode.ReorderRoutes, 9 + );
  10 +}
  11 +
  12 +class Controller extends GetxController {
  13 + final count = 0.reactive;
  14 + void increment() {
  15 + count.value++;
  16 + update();
  17 + }
  18 +}
  19 +
  20 +class Home extends ObxStatelessWidget {
  21 + const Home({Key? key}) : super(key: key);
  22 + @override
  23 + Widget build(BuildContext context) {
  24 + final controller = Get.put(Controller());
  25 + return Scaffold(
  26 + appBar: AppBar(title: Text("counter")),
  27 + body: Center(
  28 + child: Column(
  29 + mainAxisAlignment: MainAxisAlignment.center,
  30 + children: [
  31 + SimpleBuilder(builder: (context) {
  32 + print('builder');
  33 + return Text(
  34 + '${controller.count.value}',
  35 + style: TextStyle(fontSize: 30),
  36 + );
  37 + }),
  38 + // ElevatedButton(
  39 + // child: Text('Next Route'),
  40 + // onPressed: () {
  41 + // Get.to(() => Second());
  42 + // },
24 // ), 43 // ),
  44 + ],
  45 + ),
  46 + ),
  47 + floatingActionButton: FloatingActionButton(
  48 + child: Icon(Icons.add),
  49 + onPressed: controller.increment,
25 ), 50 ),
26 ); 51 );
  52 + }
27 } 53 }
@@ -6,7 +6,8 @@ import 'package:flutter/material.dart'; @@ -6,7 +6,8 @@ import 'package:flutter/material.dart';
6 import '../../../get.dart'; 6 import '../../../get.dart';
7 import '../../../get_state_manager/src/simple/list_notifier.dart'; 7 import '../../../get_state_manager/src/simple/list_notifier.dart';
8 8
9 -class GetDelegate extends RouterDelegate<GetNavConfig> with ListNotifierMixin { 9 +class GetDelegate extends RouterDelegate<GetNavConfig>
  10 + with ListNotifierSingleMixin {
10 final List<GetNavConfig> history = <GetNavConfig>[]; 11 final List<GetNavConfig> history = <GetNavConfig>[];
11 final PopMode backButtonPopMode; 12 final PopMode backButtonPopMode;
12 final PreventDuplicateHandlingMode preventDuplicateHandlingMode; 13 final PreventDuplicateHandlingMode preventDuplicateHandlingMode;
@@ -106,7 +106,7 @@ class GetStream<T> { @@ -106,7 +106,7 @@ class GetStream<T> {
106 late T _value; 106 late T _value;
107 107
108 T get value { 108 T get value {
109 - RxInterface.proxy?.addListener(this); 109 + // RxInterface.proxy?.addListener(this);
110 return _value; 110 return _value;
111 } 111 }
112 112
@@ -4,6 +4,7 @@ import 'dart:async'; @@ -4,6 +4,7 @@ import 'dart:async';
4 import 'dart:collection'; 4 import 'dart:collection';
5 5
6 import 'package:flutter/foundation.dart'; 6 import 'package:flutter/foundation.dart';
  7 +import 'package:get/get_state_manager/src/simple/list_notifier.dart';
7 8
8 import '../rx_stream/rx_stream.dart'; 9 import '../rx_stream/rx_stream.dart';
9 import '../rx_typedefs/rx_typedefs.dart'; 10 import '../rx_typedefs/rx_typedefs.dart';
@@ -5,7 +5,7 @@ import '../../../instance_manager.dart'; @@ -5,7 +5,7 @@ import '../../../instance_manager.dart';
5 import '../../get_state_manager.dart'; 5 import '../../get_state_manager.dart';
6 import '../simple/list_notifier.dart'; 6 import '../simple/list_notifier.dart';
7 7
8 -mixin StateMixin<T> on ListNotifierMixin { 8 +mixin StateMixin<T> on ListNotifier {
9 late T _value; 9 late T _value;
10 RxStatus? _status; 10 RxStatus? _status;
11 11
@@ -27,7 +27,7 @@ mixin StateMixin<T> on ListNotifierMixin { @@ -27,7 +27,7 @@ mixin StateMixin<T> on ListNotifierMixin {
27 } 27 }
28 28
29 RxStatus get status { 29 RxStatus get status {
30 - notifyChildrens(); 30 + reportRead();
31 return _status ??= _status = RxStatus.loading(); 31 return _status ??= _status = RxStatus.loading();
32 } 32 }
33 33
@@ -35,7 +35,7 @@ mixin StateMixin<T> on ListNotifierMixin { @@ -35,7 +35,7 @@ mixin StateMixin<T> on ListNotifierMixin {
35 35
36 @protected 36 @protected
37 T get value { 37 T get value {
38 - notifyChildrens(); 38 + reportRead();
39 return _value; 39 return _value;
40 } 40 }
41 41
@@ -82,7 +82,7 @@ class Value<T> extends ListNotifier @@ -82,7 +82,7 @@ class Value<T> extends ListNotifier
82 82
83 @override 83 @override
84 T get value { 84 T get value {
85 - notifyChildrens(); 85 + reportRead();
86 return _value; 86 return _value;
87 } 87 }
88 88
@@ -6,8 +6,7 @@ import '../rx_flutter/rx_notifier.dart'; @@ -6,8 +6,7 @@ import '../rx_flutter/rx_notifier.dart';
6 import 'list_notifier.dart'; 6 import 'list_notifier.dart';
7 7
8 // ignore: prefer_mixin 8 // ignore: prefer_mixin
9 -abstract class GetxController extends Listenable  
10 - with GetLifeCycleMixin, ListNotifierMixin { 9 +abstract class GetxController extends ListNotifier with GetLifeCycleMixin {
11 /// Rebuilds `GetBuilder` each time you call `update()`; 10 /// Rebuilds `GetBuilder` each time you call `update()`;
12 /// Can take a List of [ids], that will only update the matching 11 /// Can take a List of [ids], that will only update the matching
13 /// `GetBuilder( id: )`, 12 /// `GetBuilder( id: )`,
1 import 'dart:collection'; 1 import 'dart:collection';
2 2
3 -import 'package:flutter/widgets.dart'; 3 +import 'package:flutter/foundation.dart';
4 4
5 // This callback remove the listener on addListener function 5 // This callback remove the listener on addListener function
6 typedef Disposer = void Function(); 6 typedef Disposer = void Function();
@@ -9,42 +9,50 @@ typedef Disposer = void Function(); @@ -9,42 +9,50 @@ typedef Disposer = void Function();
9 // if it brings overhead the extra call, 9 // if it brings overhead the extra call,
10 typedef GetStateUpdate = void Function(); 10 typedef GetStateUpdate = void Function();
11 11
12 -class ListNotifier extends Listenable with ListNotifierMixin {} 12 +class ListNotifier extends Listenable
  13 + with ListNotifierSingleMixin, ListNotifierGroupMixin {}
13 14
14 -mixin ListNotifierMixin on Listenable { 15 +class ListNotifierSingle = ListNotifier with ListNotifierSingleMixin;
  16 +
  17 +class ListNotifierGroup = ListNotifier with ListNotifierGroupMixin;
  18 +
  19 +mixin ListNotifierSingleMixin on Listenable {
15 List<GetStateUpdate?>? _updaters = <GetStateUpdate?>[]; 20 List<GetStateUpdate?>? _updaters = <GetStateUpdate?>[];
16 21
17 - HashMap<Object?, List<GetStateUpdate>>? _updatersGroupIds =  
18 - HashMap<Object?, List<GetStateUpdate>>(); 22 + @override
  23 + Disposer addListener(GetStateUpdate listener) {
  24 + assert(_debugAssertNotDisposed());
  25 + _updaters!.add(listener);
  26 + return () => _updaters!.remove(listener);
  27 + }
  28 +
  29 + bool containsListener(GetStateUpdate listener) {
  30 + return _updaters?.contains(listener) ?? false;
  31 + }
  32 +
  33 + @override
  34 + void removeListener(VoidCallback listener) {
  35 + assert(_debugAssertNotDisposed());
  36 + _updaters!.remove(listener);
  37 + }
19 38
20 @protected 39 @protected
21 void refresh() { 40 void refresh() {
22 assert(_debugAssertNotDisposed()); 41 assert(_debugAssertNotDisposed());
23 -  
24 _notifyUpdate(); 42 _notifyUpdate();
25 } 43 }
26 44
  45 + @protected
  46 + void reportRead() {
  47 + TaskManager.instance.notify(this);
  48 + }
  49 +
27 void _notifyUpdate() { 50 void _notifyUpdate() {
28 for (var element in _updaters!) { 51 for (var element in _updaters!) {
29 element!(); 52 element!();
30 } 53 }
31 } 54 }
32 55
33 - void _notifyIdUpdate(Object id) {  
34 - if (_updatersGroupIds!.containsKey(id)) {  
35 - final listGroup = _updatersGroupIds![id]!;  
36 - for (var item in listGroup) {  
37 - item();  
38 - }  
39 - }  
40 - }  
41 -  
42 - @protected  
43 - void refreshGroup(Object id) {  
44 - assert(_debugAssertNotDisposed());  
45 - _notifyIdUpdate(id);  
46 - }  
47 -  
48 bool _debugAssertNotDisposed() { 56 bool _debugAssertNotDisposed() {
49 assert(() { 57 assert(() {
50 if (_updaters == null) { 58 if (_updaters == null) {
@@ -56,59 +64,79 @@ mixin ListNotifierMixin on Listenable { @@ -56,59 +64,79 @@ mixin ListNotifierMixin on Listenable {
56 return true; 64 return true;
57 } 65 }
58 66
59 - @protected  
60 - void notifyChildrens() {  
61 - TaskManager.instance.notify(_updaters); 67 + int get listenersLength {
  68 + assert(_debugAssertNotDisposed());
  69 + return _updaters!.length;
62 } 70 }
63 71
64 - bool get hasListeners { 72 + @mustCallSuper
  73 + void dispose() {
65 assert(_debugAssertNotDisposed()); 74 assert(_debugAssertNotDisposed());
66 - return _updaters!.isNotEmpty; 75 + _updaters = null;
67 } 76 }
  77 +}
  78 +
  79 +mixin ListNotifierGroupMixin on Listenable {
  80 + HashMap<Object?, ListNotifierSingleMixin>? _updatersGroupIds =
  81 + HashMap<Object?, ListNotifierSingleMixin>();
68 82
69 - int get listeners { 83 + void _notifyGroupUpdate(Object id) {
  84 + if (_updatersGroupIds!.containsKey(id)) {
  85 + _updatersGroupIds![id]!._notifyUpdate();
  86 + }
  87 + }
  88 +
  89 + @protected
  90 + void notifyGroupChildrens(Object id) {
70 assert(_debugAssertNotDisposed()); 91 assert(_debugAssertNotDisposed());
71 - return _updaters!.length; 92 + TaskManager.instance.notify(_updatersGroupIds![id]!);
72 } 93 }
73 94
74 - @override  
75 - void removeListener(VoidCallback listener) { 95 + bool containsId(Object id) {
  96 + return _updatersGroupIds?.containsKey(id) ?? false;
  97 + }
  98 +
  99 + @protected
  100 + void refreshGroup(Object id) {
76 assert(_debugAssertNotDisposed()); 101 assert(_debugAssertNotDisposed());
77 - _updaters!.remove(listener); 102 + _notifyGroupUpdate(id);
  103 + }
  104 +
  105 + bool _debugAssertNotDisposed() {
  106 + assert(() {
  107 + if (_updatersGroupIds == null) {
  108 + throw FlutterError('''A $runtimeType was used after being disposed.\n
  109 +'Once you have called dispose() on a $runtimeType, it can no longer be used.''');
  110 + }
  111 + return true;
  112 + }());
  113 + return true;
78 } 114 }
79 115
80 void removeListenerId(Object id, VoidCallback listener) { 116 void removeListenerId(Object id, VoidCallback listener) {
81 assert(_debugAssertNotDisposed()); 117 assert(_debugAssertNotDisposed());
82 if (_updatersGroupIds!.containsKey(id)) { 118 if (_updatersGroupIds!.containsKey(id)) {
83 - _updatersGroupIds![id]!.remove(listener); 119 + _updatersGroupIds![id]!.removeListener(listener);
84 } 120 }
85 - _updaters!.remove(listener);  
86 } 121 }
87 122
88 @mustCallSuper 123 @mustCallSuper
89 void dispose() { 124 void dispose() {
90 assert(_debugAssertNotDisposed()); 125 assert(_debugAssertNotDisposed());
91 - _updaters = null; 126 + _updatersGroupIds?.forEach((key, value) => value.dispose());
92 _updatersGroupIds = null; 127 _updatersGroupIds = null;
93 } 128 }
94 129
95 - @override  
96 - Disposer addListener(GetStateUpdate listener) {  
97 - assert(_debugAssertNotDisposed());  
98 - _updaters!.add(listener);  
99 - return () => _updaters!.remove(listener);  
100 - }  
101 -  
102 Disposer addListenerId(Object? key, GetStateUpdate listener) { 130 Disposer addListenerId(Object? key, GetStateUpdate listener) {
103 - _updatersGroupIds![key] ??= <GetStateUpdate>[];  
104 - _updatersGroupIds![key]!.add(listener);  
105 - return () => _updatersGroupIds![key]!.remove(listener); 131 + _updatersGroupIds![key] ??= ListNotifierSingle();
  132 + return _updatersGroupIds![key]!.addListener(listener);
106 } 133 }
107 134
108 /// To dispose an [id] from future updates(), this ids are registered 135 /// To dispose an [id] from future updates(), this ids are registered
109 /// by `GetBuilder()` or similar, so is a way to unlink the state change with 136 /// by `GetBuilder()` or similar, so is a way to unlink the state change with
110 /// the Widget from the Controller. 137 /// the Widget from the Controller.
111 void disposeId(Object id) { 138 void disposeId(Object id) {
  139 + _updatersGroupIds?[id]?.dispose();
112 _updatersGroupIds!.remove(id); 140 _updatersGroupIds!.remove(id);
113 } 141 }
114 } 142 }
@@ -123,11 +151,18 @@ class TaskManager { @@ -123,11 +151,18 @@ class TaskManager {
123 GetStateUpdate? _setter; 151 GetStateUpdate? _setter;
124 List<VoidCallback>? _remove; 152 List<VoidCallback>? _remove;
125 153
126 - void notify(List<GetStateUpdate?>? _updaters) {  
127 - if (_setter != null) {  
128 - if (!_updaters!.contains(_setter)) {  
129 - _updaters.add(_setter);  
130 - _remove!.add(() => _updaters.remove(_setter)); 154 + final listNotifier = ListNotifierGroup();
  155 +
  156 + // void addElement(Object id, GetStateUpdate listener) {
  157 + // _remove?.add(listNotifier.addListenerId(id, listener));
  158 + // }
  159 +
  160 + void notify(ListNotifierSingleMixin _updaters) {
  161 + final listener = _setter;
  162 + if (listener != null) {
  163 + if (!_updaters.containsListener(listener)) {
  164 + _updaters.addListener(listener);
  165 + _remove?.add(() => _updaters.removeListener(listener));
131 } 166 }
132 } 167 }
133 } 168 }