Showing
10 changed files
with
142 additions
and
80 deletions
@@ -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 | 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 | - }, | ||
15 | - ), | ||
16 | - getPages: AppPages.routes, | ||
17 | - // routeInformationParser: GetInformationParser( | ||
18 | - // // initialRoute: Routes.HOME, | ||
19 | - // ), | ||
20 | - // routerDelegate: GetDelegate( | ||
21 | - // backButtonPopMode: PopMode.History, | ||
22 | - // preventDuplicateHandlingMode: | ||
23 | - // PreventDuplicateHandlingMode.ReorderRoutes, | ||
24 | - // ), | 6 | + GetMaterialApp( |
7 | + home: Home(), | ||
25 | ), | 8 | ), |
26 | ); | 9 | ); |
27 | } | 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 | + // }, | ||
43 | + // ), | ||
44 | + ], | ||
45 | + ), | ||
46 | + ), | ||
47 | + floatingActionButton: FloatingActionButton( | ||
48 | + child: Icon(Icons.add), | ||
49 | + onPressed: controller.increment, | ||
50 | + ), | ||
51 | + ); | ||
52 | + } | ||
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 | } |
-
Please register or login to post a comment