- Rename typedefs FcBuilderFunc to InstanceBuilderCallback to be more meaningful.
- cleanup more comments. - promote most classes in parse_route.dart (except ParseRouteTree) to be private. I still believe we should use Uri to parse the "url". - Added _RxImpl::refresh() in rx_impl.dart and added some comments/samples. - Some cleanup in rx_interface.dart, added more comments, missing types and move vars to the top.
Showing
5 changed files
with
161 additions
and
85 deletions
@@ -3,11 +3,12 @@ import 'package:get/src/core/get_interface.dart'; | @@ -3,11 +3,12 @@ import 'package:get/src/core/get_interface.dart'; | ||
3 | import 'get_instance.dart'; | 3 | import 'get_instance.dart'; |
4 | 4 | ||
5 | extension Inst on GetInterface { | 5 | extension Inst on GetInterface { |
6 | - void lazyPut<S>(FcBuilderFunc builder, {String tag, bool fenix = false}) { | 6 | + void lazyPut<S>(InstanceBuilderCallback builder, |
7 | + {String tag, bool fenix = false}) { | ||
7 | return GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix); | 8 | return GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix); |
8 | } | 9 | } |
9 | 10 | ||
10 | - Future<S> putAsync<S>(FcBuilderFuncAsync<S> builder, | 11 | + Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder, |
11 | {String tag, bool permanent = false}) async => | 12 | {String tag, bool permanent = false}) async => |
12 | GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent); | 13 | GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent); |
13 | 14 | ||
@@ -21,15 +22,13 @@ extension Inst on GetInterface { | @@ -21,15 +22,13 @@ extension Inst on GetInterface { | ||
21 | /// Repl a = find(); | 22 | /// Repl a = find(); |
22 | /// Repl b = find(); | 23 | /// Repl b = find(); |
23 | /// print(a==b); (false)``` | 24 | /// print(a==b); (false)``` |
24 | - /// | ||
25 | - void create<S>(FcBuilderFunc<S> builder, | 25 | + void create<S>(InstanceBuilderCallback<S> builder, |
26 | {String name, bool permanent = true}) => | 26 | {String name, bool permanent = true}) => |
27 | GetInstance().create<S>(builder, name: name, permanent: permanent); | 27 | GetInstance().create<S>(builder, name: name, permanent: permanent); |
28 | 28 | ||
29 | /// Finds a instance of the required Class<[S]> (or [tag]) | 29 | /// Finds a instance of the required Class<[S]> (or [tag]) |
30 | /// In the case of using Get.[create], it will create an instance | 30 | /// In the case of using Get.[create], it will create an instance |
31 | /// each time you call [find] | 31 | /// each time you call [find] |
32 | - /// | ||
33 | S find<S>({String tag}) => GetInstance().find<S>(tag: tag); | 32 | S find<S>({String tag}) => GetInstance().find<S>(tag: tag); |
34 | 33 | ||
35 | /// Injects a Instance [S] in [GetInstance]. | 34 | /// Injects a Instance [S] in [GetInstance]. |
@@ -40,17 +39,24 @@ extension Inst on GetInterface { | @@ -40,17 +39,24 @@ extension Inst on GetInterface { | ||
40 | /// - [tag] optionally, use a [tag] as an "id" to create multiple records of the same Type<[S]> | 39 | /// - [tag] optionally, use a [tag] as an "id" to create multiple records of the same Type<[S]> |
41 | /// - [permanent] keeps the Instance in memory, not following [GetConfig.smartManagement] | 40 | /// - [permanent] keeps the Instance in memory, not following [GetConfig.smartManagement] |
42 | /// rules | 41 | /// rules |
43 | - /// | 42 | + /// - [builder] If defined, the [dependency] must be returned from here |
44 | S put<S>(S dependency, | 43 | S put<S>(S dependency, |
45 | - {String tag, bool permanent = false, FcBuilderFunc<S> builder}) => | 44 | + {String tag, |
45 | + bool permanent = false, | ||
46 | + InstanceBuilderCallback<S> builder}) => | ||
46 | GetInstance() | 47 | GetInstance() |
47 | .put<S>(dependency, tag: tag, permanent: permanent, builder: builder); | 48 | .put<S>(dependency, tag: tag, permanent: permanent, builder: builder); |
48 | 49 | ||
50 | + /// Clears all registered instances (and/or tags). | ||
51 | + /// Even the persistent ones. | ||
52 | + /// | ||
53 | + /// [clearFactory] clears the callbacks registered by [lazyPut] | ||
54 | + /// [clearRouteBindings] clears Instances associated with routes. | ||
49 | bool reset({bool clearFactory = true, bool clearRouteBindings = true}) => | 55 | bool reset({bool clearFactory = true, bool clearRouteBindings = true}) => |
50 | GetInstance().reset( | 56 | GetInstance().reset( |
51 | clearFactory: clearFactory, clearRouteBindings: clearRouteBindings); | 57 | clearFactory: clearFactory, clearRouteBindings: clearRouteBindings); |
52 | 58 | ||
53 | - /// Delete class instance on [S] and clean memory | 59 | + /// Delete class instance on [S], cleaning the memory |
54 | Future<bool> delete<S>({String tag, String key}) async => | 60 | Future<bool> delete<S>({String tag, String key}) async => |
55 | GetInstance().delete<S>(tag: tag, key: key); | 61 | GetInstance().delete<S>(tag: tag, key: key); |
56 | 62 |
@@ -12,12 +12,14 @@ class GetConfig { | @@ -12,12 +12,14 @@ class GetConfig { | ||
12 | 12 | ||
13 | class GetInstance { | 13 | class GetInstance { |
14 | factory GetInstance() => _getInstance ??= GetInstance._(); | 14 | factory GetInstance() => _getInstance ??= GetInstance._(); |
15 | + | ||
15 | const GetInstance._(); | 16 | const GetInstance._(); |
17 | + | ||
16 | static GetInstance _getInstance; | 18 | static GetInstance _getInstance; |
17 | 19 | ||
18 | /// Holds references to every registered Instance when using | 20 | /// Holds references to every registered Instance when using |
19 | /// Get.[put] | 21 | /// Get.[put] |
20 | - static Map<String, _FcBuilder> _singl = {}; | 22 | + static Map<String, _InstanceBuilderFactory> _singl = {}; |
21 | 23 | ||
22 | /// Holds a reference to every registered callback when using | 24 | /// Holds a reference to every registered callback when using |
23 | /// Get.[lazyPut] | 25 | /// Get.[lazyPut] |
@@ -27,12 +29,13 @@ class GetInstance { | @@ -27,12 +29,13 @@ class GetInstance { | ||
27 | 29 | ||
28 | static GetQueue _queue = GetQueue(); | 30 | static GetQueue _queue = GetQueue(); |
29 | 31 | ||
30 | - void lazyPut<S>(FcBuilderFunc builder, {String tag, bool fenix = false}) { | 32 | + void lazyPut<S>(InstanceBuilderCallback builder, |
33 | + {String tag, bool fenix = false}) { | ||
31 | String key = _getKey(S, tag); | 34 | String key = _getKey(S, tag); |
32 | _factory.putIfAbsent(key, () => _Lazy(builder, fenix)); | 35 | _factory.putIfAbsent(key, () => _Lazy(builder, fenix)); |
33 | } | 36 | } |
34 | 37 | ||
35 | - Future<S> putAsync<S>(FcBuilderFuncAsync<S> builder, | 38 | + Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder, |
36 | {String tag, bool permanent = false}) async { | 39 | {String tag, bool permanent = false}) async { |
37 | return put<S>(await builder(), tag: tag, permanent: permanent); | 40 | return put<S>(await builder(), tag: tag, permanent: permanent); |
38 | } | 41 | } |
@@ -49,7 +52,7 @@ class GetInstance { | @@ -49,7 +52,7 @@ class GetInstance { | ||
49 | S dependency, { | 52 | S dependency, { |
50 | String tag, | 53 | String tag, |
51 | bool permanent = false, | 54 | bool permanent = false, |
52 | - FcBuilderFunc<S> builder, | 55 | + InstanceBuilderCallback<S> builder, |
53 | }) { | 56 | }) { |
54 | _insert( | 57 | _insert( |
55 | isSingleton: true, | 58 | isSingleton: true, |
@@ -70,7 +73,7 @@ class GetInstance { | @@ -70,7 +73,7 @@ class GetInstance { | ||
70 | /// Repl b = find(); | 73 | /// Repl b = find(); |
71 | /// print(a==b); (false)``` | 74 | /// print(a==b); (false)``` |
72 | void create<S>( | 75 | void create<S>( |
73 | - FcBuilderFunc<S> builder, { | 76 | + InstanceBuilderCallback<S> builder, { |
74 | String name, | 77 | String name, |
75 | bool permanent = true, | 78 | bool permanent = true, |
76 | }) { | 79 | }) { |
@@ -83,12 +86,14 @@ class GetInstance { | @@ -83,12 +86,14 @@ class GetInstance { | ||
83 | bool isSingleton, | 86 | bool isSingleton, |
84 | String name, | 87 | String name, |
85 | bool permanent = false, | 88 | bool permanent = false, |
86 | - FcBuilderFunc<S> builder, | 89 | + InstanceBuilderCallback<S> builder, |
87 | }) { | 90 | }) { |
88 | assert(builder != null); | 91 | assert(builder != null); |
89 | final key = _getKey(S, name); | 92 | final key = _getKey(S, name); |
90 | _singl.putIfAbsent( | 93 | _singl.putIfAbsent( |
91 | - key, () => _FcBuilder<S>(isSingleton, builder, permanent, false)); | 94 | + key, |
95 | + () => | ||
96 | + _InstanceBuilderFactory<S>(isSingleton, builder, permanent, false)); | ||
92 | } | 97 | } |
93 | 98 | ||
94 | /// Clears from memory registered Instances associated with [routeName] when | 99 | /// Clears from memory registered Instances associated with [routeName] when |
@@ -180,8 +185,7 @@ class GetInstance { | @@ -180,8 +185,7 @@ class GetInstance { | ||
180 | S find<S>({String tag}) { | 185 | S find<S>({String tag}) { |
181 | String key = _getKey(S, tag); | 186 | String key = _getKey(S, tag); |
182 | if (isRegistered<S>(tag: tag)) { | 187 | if (isRegistered<S>(tag: tag)) { |
183 | - _FcBuilder builder = _singl[key] as _FcBuilder; | ||
184 | - if (builder == null) { | 188 | + if (_singl[key] == null) { |
185 | if (tag == null) { | 189 | if (tag == null) { |
186 | throw 'Class "$S" is not register'; | 190 | throw 'Class "$S" is not register'; |
187 | } else { | 191 | } else { |
@@ -189,7 +193,6 @@ class GetInstance { | @@ -189,7 +193,6 @@ class GetInstance { | ||
189 | } | 193 | } |
190 | } | 194 | } |
191 | _initDependencies<S>(name: tag); | 195 | _initDependencies<S>(name: tag); |
192 | - | ||
193 | return _singl[key].getDependency() as S; | 196 | return _singl[key].getDependency() as S; |
194 | } else { | 197 | } else { |
195 | if (!_factory.containsKey(key)) | 198 | if (!_factory.containsKey(key)) |
@@ -245,11 +248,12 @@ class GetInstance { | @@ -245,11 +248,12 @@ class GetInstance { | ||
245 | return false; | 248 | return false; |
246 | } | 249 | } |
247 | 250 | ||
248 | - _FcBuilder builder = _singl[newKey] as _FcBuilder; | 251 | + final builder = _singl[newKey]; |
249 | if (builder.permanent && !force) { | 252 | if (builder.permanent && !force) { |
250 | GetConfig.log( | 253 | GetConfig.log( |
251 | '"$newKey" has been marked as permanent, SmartManagement is not authorized to delete it.', | 254 | '"$newKey" has been marked as permanent, SmartManagement is not authorized to delete it.', |
252 | - isError: true); | 255 | + isError: true, |
256 | + ); | ||
253 | return false; | 257 | return false; |
254 | } | 258 | } |
255 | final i = builder.dependency; | 259 | final i = builder.dependency; |
@@ -280,12 +284,12 @@ class GetInstance { | @@ -280,12 +284,12 @@ class GetInstance { | ||
280 | bool isPrepared<S>({String tag}) => _factory.containsKey(_getKey(S, tag)); | 284 | bool isPrepared<S>({String tag}) => _factory.containsKey(_getKey(S, tag)); |
281 | } | 285 | } |
282 | 286 | ||
283 | -typedef FcBuilderFunc<S> = S Function(); | 287 | +typedef InstanceBuilderCallback<S> = S Function(); |
284 | 288 | ||
285 | -typedef FcBuilderFuncAsync<S> = Future<S> Function(); | 289 | +typedef AsyncInstanceBuilderCallback<S> = Future<S> Function(); |
286 | 290 | ||
287 | /// Internal class to register instances with Get.[put]<[S]>(). | 291 | /// Internal class to register instances with Get.[put]<[S]>(). |
288 | -class _FcBuilder<S> { | 292 | +class _InstanceBuilderFactory<S> { |
289 | /// Marks the Builder as a single instance. | 293 | /// Marks the Builder as a single instance. |
290 | /// For reusing [dependency] instead of [builderFunc] | 294 | /// For reusing [dependency] instead of [builderFunc] |
291 | bool isSingleton; | 295 | bool isSingleton; |
@@ -295,7 +299,7 @@ class _FcBuilder<S> { | @@ -295,7 +299,7 @@ class _FcBuilder<S> { | ||
295 | 299 | ||
296 | /// Generates (and regenerates) the instance when [isSingleton]=false. | 300 | /// Generates (and regenerates) the instance when [isSingleton]=false. |
297 | /// Usually used by factory methods | 301 | /// Usually used by factory methods |
298 | - FcBuilderFunc<S> builderFunc; | 302 | + InstanceBuilderCallback<S> builderFunc; |
299 | 303 | ||
300 | /// Flag to persist the instance in memory, | 304 | /// Flag to persist the instance in memory, |
301 | /// without considering [GetConfig.smartManagement] | 305 | /// without considering [GetConfig.smartManagement] |
@@ -303,7 +307,8 @@ class _FcBuilder<S> { | @@ -303,7 +307,8 @@ class _FcBuilder<S> { | ||
303 | 307 | ||
304 | bool isInit = false; | 308 | bool isInit = false; |
305 | 309 | ||
306 | - _FcBuilder(this.isSingleton, this.builderFunc, this.permanent, this.isInit); | 310 | + _InstanceBuilderFactory( |
311 | + this.isSingleton, this.builderFunc, this.permanent, this.isInit); | ||
307 | 312 | ||
308 | /// Gets the actual instance by it's [builderFunc] or the persisted instance. | 313 | /// Gets the actual instance by it's [builderFunc] or the persisted instance. |
309 | S getDependency() { | 314 | S getDependency() { |
@@ -315,6 +320,6 @@ class _FcBuilder<S> { | @@ -315,6 +320,6 @@ class _FcBuilder<S> { | ||
315 | /// keeps a reference to the callback to be called. | 320 | /// keeps a reference to the callback to be called. |
316 | class _Lazy { | 321 | class _Lazy { |
317 | bool fenix; | 322 | bool fenix; |
318 | - FcBuilderFunc builder; | 323 | + InstanceBuilderCallback builder; |
319 | _Lazy(this.builder, this.fenix); | 324 | _Lazy(this.builder, this.fenix); |
320 | } | 325 | } |
1 | import 'package:flutter/widgets.dart'; | 1 | import 'package:flutter/widgets.dart'; |
2 | import 'package:get/src/navigation/routes/get_route.dart'; | 2 | import 'package:get/src/navigation/routes/get_route.dart'; |
3 | 3 | ||
4 | -class GetPageMatch { | ||
5 | - GetPageMatch(this.route); | ||
6 | - | ||
7 | - GetPage route; | ||
8 | - Map<String, String> parameters = <String, String>{}; | ||
9 | -} | ||
10 | - | ||
11 | class ParseRouteTree { | 4 | class ParseRouteTree { |
12 | - final List<ParseRouteTreeNode> _nodes = <ParseRouteTreeNode>[]; | 5 | + final List<_ParseRouteTreeNode> _nodes = <_ParseRouteTreeNode>[]; |
13 | 6 | ||
14 | // bool _hasDefaultRoute = false; | 7 | // bool _hasDefaultRoute = false; |
15 | 8 | ||
@@ -20,7 +13,7 @@ class ParseRouteTree { | @@ -20,7 +13,7 @@ class ParseRouteTree { | ||
20 | // if (_hasDefaultRoute) { | 13 | // if (_hasDefaultRoute) { |
21 | // throw ("Default route was already defined"); | 14 | // throw ("Default route was already defined"); |
22 | // } | 15 | // } |
23 | - var node = ParseRouteTreeNode(path, ParseRouteTreeNodeType.component); | 16 | + var node = _ParseRouteTreeNode(path, _ParseRouteTreeNodeType.component); |
24 | node.routes = [route]; | 17 | node.routes = [route]; |
25 | _nodes.add(node); | 18 | _nodes.add(node); |
26 | // _hasDefaultRoute = true; | 19 | // _hasDefaultRoute = true; |
@@ -30,13 +23,13 @@ class ParseRouteTree { | @@ -30,13 +23,13 @@ class ParseRouteTree { | ||
30 | path = path.substring(1); | 23 | path = path.substring(1); |
31 | } | 24 | } |
32 | List<String> pathComponents = path.split('/'); | 25 | List<String> pathComponents = path.split('/'); |
33 | - ParseRouteTreeNode parent; | 26 | + _ParseRouteTreeNode parent; |
34 | for (int i = 0; i < pathComponents.length; i++) { | 27 | for (int i = 0; i < pathComponents.length; i++) { |
35 | String component = pathComponents[i]; | 28 | String component = pathComponents[i]; |
36 | - ParseRouteTreeNode node = _nodeForComponent(component, parent); | 29 | + _ParseRouteTreeNode node = _nodeForComponent(component, parent); |
37 | if (node == null) { | 30 | if (node == null) { |
38 | - ParseRouteTreeNodeType type = _typeForComponent(component); | ||
39 | - node = ParseRouteTreeNode(component, type); | 31 | + _ParseRouteTreeNodeType type = _typeForComponent(component); |
32 | + node = _ParseRouteTreeNode(component, type); | ||
40 | node.parent = parent; | 33 | node.parent = parent; |
41 | if (parent == null) { | 34 | if (parent == null) { |
42 | _nodes.add(node); | 35 | _nodes.add(node); |
@@ -55,7 +48,7 @@ class ParseRouteTree { | @@ -55,7 +48,7 @@ class ParseRouteTree { | ||
55 | } | 48 | } |
56 | } | 49 | } |
57 | 50 | ||
58 | - GetPageMatch matchRoute(String path) { | 51 | + _GetPageMatch matchRoute(String path) { |
59 | String usePath = path; | 52 | String usePath = path; |
60 | if (usePath.startsWith("/")) { | 53 | if (usePath.startsWith("/")) { |
61 | usePath = path.substring(1); | 54 | usePath = path.substring(1); |
@@ -68,14 +61,14 @@ class ParseRouteTree { | @@ -68,14 +61,14 @@ class ParseRouteTree { | ||
68 | if (path == Navigator.defaultRouteName) { | 61 | if (path == Navigator.defaultRouteName) { |
69 | components = ["/"]; | 62 | components = ["/"]; |
70 | } | 63 | } |
71 | - Map<ParseRouteTreeNode, ParseRouteTreeNodeMatch> nodeMatches = | ||
72 | - <ParseRouteTreeNode, ParseRouteTreeNodeMatch>{}; | ||
73 | - List<ParseRouteTreeNode> nodesToCheck = _nodes; | 64 | + Map<_ParseRouteTreeNode, _ParseRouteTreeNodeMatch> nodeMatches = |
65 | + <_ParseRouteTreeNode, _ParseRouteTreeNodeMatch>{}; | ||
66 | + List<_ParseRouteTreeNode> nodesToCheck = _nodes; | ||
74 | for (String checkComponent in components) { | 67 | for (String checkComponent in components) { |
75 | - Map<ParseRouteTreeNode, ParseRouteTreeNodeMatch> currentMatches = | ||
76 | - <ParseRouteTreeNode, ParseRouteTreeNodeMatch>{}; | ||
77 | - List<ParseRouteTreeNode> nextNodes = <ParseRouteTreeNode>[]; | ||
78 | - for (ParseRouteTreeNode node in nodesToCheck) { | 68 | + Map<_ParseRouteTreeNode, _ParseRouteTreeNodeMatch> currentMatches = |
69 | + <_ParseRouteTreeNode, _ParseRouteTreeNodeMatch>{}; | ||
70 | + List<_ParseRouteTreeNode> nextNodes = <_ParseRouteTreeNode>[]; | ||
71 | + for (_ParseRouteTreeNode node in nodesToCheck) { | ||
79 | String pathPart = checkComponent; | 72 | String pathPart = checkComponent; |
80 | Map<String, String> queryMap = {}; | 73 | Map<String, String> queryMap = {}; |
81 | 74 | ||
@@ -104,9 +97,9 @@ class ParseRouteTree { | @@ -104,9 +97,9 @@ class ParseRouteTree { | ||
104 | 97 | ||
105 | bool isMatch = (node.part == pathPart || node.isParameter()); | 98 | bool isMatch = (node.part == pathPart || node.isParameter()); |
106 | if (isMatch) { | 99 | if (isMatch) { |
107 | - ParseRouteTreeNodeMatch parentMatch = nodeMatches[node.parent]; | ||
108 | - ParseRouteTreeNodeMatch match = | ||
109 | - ParseRouteTreeNodeMatch.fromMatch(parentMatch, node); | 100 | + _ParseRouteTreeNodeMatch parentMatch = nodeMatches[node.parent]; |
101 | + _ParseRouteTreeNodeMatch match = | ||
102 | + _ParseRouteTreeNodeMatch.fromMatch(parentMatch, node); | ||
110 | 103 | ||
111 | // TODO: find a way to clean this implementation. | 104 | // TODO: find a way to clean this implementation. |
112 | match.parameters.addAll(uri.queryParameters); | 105 | match.parameters.addAll(uri.queryParameters); |
@@ -131,16 +124,16 @@ class ParseRouteTree { | @@ -131,16 +124,16 @@ class ParseRouteTree { | ||
131 | return null; | 124 | return null; |
132 | } | 125 | } |
133 | } | 126 | } |
134 | - List<ParseRouteTreeNodeMatch> matches = nodeMatches.values.toList(); | 127 | + List<_ParseRouteTreeNodeMatch> matches = nodeMatches.values.toList(); |
135 | if (matches.length > 0) { | 128 | if (matches.length > 0) { |
136 | - ParseRouteTreeNodeMatch match = matches.first; | ||
137 | - ParseRouteTreeNode nodeToUse = match.node; | 129 | + _ParseRouteTreeNodeMatch match = matches.first; |
130 | + _ParseRouteTreeNode nodeToUse = match.node; | ||
138 | 131 | ||
139 | if (nodeToUse != null && | 132 | if (nodeToUse != null && |
140 | nodeToUse.routes != null && | 133 | nodeToUse.routes != null && |
141 | nodeToUse.routes.length > 0) { | 134 | nodeToUse.routes.length > 0) { |
142 | List<GetPage> routes = nodeToUse.routes; | 135 | List<GetPage> routes = nodeToUse.routes; |
143 | - GetPageMatch routeMatch = GetPageMatch(routes[0]); | 136 | + _GetPageMatch routeMatch = _GetPageMatch(routes[0]); |
144 | 137 | ||
145 | routeMatch.parameters = match.parameters; | 138 | routeMatch.parameters = match.parameters; |
146 | 139 | ||
@@ -150,13 +143,13 @@ class ParseRouteTree { | @@ -150,13 +143,13 @@ class ParseRouteTree { | ||
150 | return null; | 143 | return null; |
151 | } | 144 | } |
152 | 145 | ||
153 | - ParseRouteTreeNode _nodeForComponent( | ||
154 | - String component, ParseRouteTreeNode parent) { | ||
155 | - List<ParseRouteTreeNode> nodes = _nodes; | 146 | + _ParseRouteTreeNode _nodeForComponent( |
147 | + String component, _ParseRouteTreeNode parent) { | ||
148 | + List<_ParseRouteTreeNode> nodes = _nodes; | ||
156 | if (parent != null) { | 149 | if (parent != null) { |
157 | nodes = parent.nodes; | 150 | nodes = parent.nodes; |
158 | } | 151 | } |
159 | - for (ParseRouteTreeNode node in nodes) { | 152 | + for (_ParseRouteTreeNode node in nodes) { |
160 | if (node.part == component) { | 153 | if (node.part == component) { |
161 | return node; | 154 | return node; |
162 | } | 155 | } |
@@ -164,10 +157,10 @@ class ParseRouteTree { | @@ -164,10 +157,10 @@ class ParseRouteTree { | ||
164 | return null; | 157 | return null; |
165 | } | 158 | } |
166 | 159 | ||
167 | - ParseRouteTreeNodeType _typeForComponent(String component) { | ||
168 | - ParseRouteTreeNodeType type = ParseRouteTreeNodeType.component; | 160 | + _ParseRouteTreeNodeType _typeForComponent(String component) { |
161 | + _ParseRouteTreeNodeType type = _ParseRouteTreeNodeType.component; | ||
169 | if (_isParameterComponent(component)) { | 162 | if (_isParameterComponent(component)) { |
170 | - type = ParseRouteTreeNodeType.parameter; | 163 | + type = _ParseRouteTreeNodeType.parameter; |
171 | } | 164 | } |
172 | return type; | 165 | return type; |
173 | } | 166 | } |
@@ -190,35 +183,43 @@ class ParseRouteTree { | @@ -190,35 +183,43 @@ class ParseRouteTree { | ||
190 | } | 183 | } |
191 | } | 184 | } |
192 | 185 | ||
193 | -class ParseRouteTreeNodeMatch { | ||
194 | - ParseRouteTreeNodeMatch(this.node); | 186 | +class _ParseRouteTreeNodeMatch { |
187 | + _ParseRouteTreeNodeMatch(this.node); | ||
195 | 188 | ||
196 | - ParseRouteTreeNodeMatch.fromMatch(ParseRouteTreeNodeMatch match, this.node) { | 189 | + _ParseRouteTreeNodeMatch.fromMatch( |
190 | + _ParseRouteTreeNodeMatch match, this.node) { | ||
197 | parameters = <String, String>{}; | 191 | parameters = <String, String>{}; |
198 | if (match != null) { | 192 | if (match != null) { |
199 | parameters.addAll(match.parameters); | 193 | parameters.addAll(match.parameters); |
200 | } | 194 | } |
201 | } | 195 | } |
202 | 196 | ||
203 | - ParseRouteTreeNode node; | 197 | + _ParseRouteTreeNode node; |
204 | Map<String, String> parameters = <String, String>{}; | 198 | Map<String, String> parameters = <String, String>{}; |
205 | } | 199 | } |
206 | 200 | ||
207 | -class ParseRouteTreeNode { | ||
208 | - ParseRouteTreeNode(this.part, this.type); | 201 | +class _ParseRouteTreeNode { |
202 | + _ParseRouteTreeNode(this.part, this.type); | ||
209 | 203 | ||
210 | String part; | 204 | String part; |
211 | - ParseRouteTreeNodeType type; | 205 | + _ParseRouteTreeNodeType type; |
212 | List<GetPage> routes = <GetPage>[]; | 206 | List<GetPage> routes = <GetPage>[]; |
213 | - List<ParseRouteTreeNode> nodes = <ParseRouteTreeNode>[]; | ||
214 | - ParseRouteTreeNode parent; | 207 | + List<_ParseRouteTreeNode> nodes = <_ParseRouteTreeNode>[]; |
208 | + _ParseRouteTreeNode parent; | ||
215 | 209 | ||
216 | bool isParameter() { | 210 | bool isParameter() { |
217 | - return type == ParseRouteTreeNodeType.parameter; | 211 | + return type == _ParseRouteTreeNodeType.parameter; |
218 | } | 212 | } |
219 | } | 213 | } |
220 | 214 | ||
221 | -enum ParseRouteTreeNodeType { | 215 | +class _GetPageMatch { |
216 | + _GetPageMatch(this.route); | ||
217 | + | ||
218 | + GetPage route; | ||
219 | + Map<String, String> parameters = <String, String>{}; | ||
220 | +} | ||
221 | + | ||
222 | +enum _ParseRouteTreeNodeType { | ||
222 | component, | 223 | component, |
223 | parameter, | 224 | parameter, |
224 | } | 225 | } |
@@ -38,11 +38,69 @@ class _RxImpl<T> implements RxInterface<T> { | @@ -38,11 +38,69 @@ class _RxImpl<T> implements RxInterface<T> { | ||
38 | 38 | ||
39 | bool get canUpdate => _subscriptions.isNotEmpty; | 39 | bool get canUpdate => _subscriptions.isNotEmpty; |
40 | 40 | ||
41 | + /// Makes this Rx looks like a function so you can update a new | ||
42 | + /// value using [rx(someOtherValue)]. Practical to assign the Rx directly | ||
43 | + /// to some Widget that has a signature ::onChange( value ) | ||
44 | + /// | ||
45 | + /// Example: | ||
46 | + /// ``` | ||
47 | + /// final myText = 'GetX rocks!'.obs; | ||
48 | + /// | ||
49 | + /// // in your Constructor, just to check it works :P | ||
50 | + /// ever( myText, print ) ; | ||
51 | + /// | ||
52 | + /// // in your build(BuildContext) { | ||
53 | + /// TextField( | ||
54 | + // onChanged: myText, | ||
55 | + // ), | ||
56 | + ///``` | ||
41 | T call([T v]) { | 57 | T call([T v]) { |
42 | if (v != null) this.value = v; | 58 | if (v != null) this.value = v; |
43 | return this.value; | 59 | return this.value; |
44 | } | 60 | } |
45 | 61 | ||
62 | + /// Makes a direct update of [value] adding it to the Stream | ||
63 | + /// useful when you make use of Rx for custom Types to referesh your UI. | ||
64 | + /// | ||
65 | + /// Sample: | ||
66 | + /// ``` | ||
67 | + /// class Person { | ||
68 | + /// String name, last; | ||
69 | + /// int age; | ||
70 | + /// Person({this.name, this.last, this.age}); | ||
71 | + /// @override | ||
72 | + /// String toString() => '$name $last, $age years old'; | ||
73 | + /// } | ||
74 | + /// | ||
75 | + /// final person = Person(name: 'John', last: 'Doe', age: 18).obs; | ||
76 | + /// person.value.name = 'Roi'; | ||
77 | + /// person.refresh(); | ||
78 | + /// print( person ); | ||
79 | + /// ``` | ||
80 | + void refresh() { | ||
81 | + subject.add(value); | ||
82 | + } | ||
83 | + | ||
84 | + /// Uses a callback to update [value] internally, similar to [refresh], but provides | ||
85 | + /// the current value as the argument. | ||
86 | + /// Makes sense for custom Rx types (like Models). | ||
87 | + /// | ||
88 | + /// Sample: | ||
89 | + /// ``` | ||
90 | + /// class Person { | ||
91 | + /// String name, last; | ||
92 | + /// int age; | ||
93 | + /// Person({this.name, this.last, this.age}); | ||
94 | + /// @override | ||
95 | + /// String toString() => '$name $last, $age years old'; | ||
96 | + /// } | ||
97 | + /// | ||
98 | + /// final person = Person(name: 'John', last: 'Doe', age: 18).obs; | ||
99 | + /// person.update((person) { | ||
100 | + /// person.name = 'Roi'; | ||
101 | + /// }); | ||
102 | + /// print( person ); | ||
103 | + /// ``` | ||
46 | void update(void fn(T value)) { | 104 | void update(void fn(T value)) { |
47 | fn(value); | 105 | fn(value); |
48 | subject.add(value); | 106 | subject.add(value); |
@@ -3,20 +3,22 @@ import 'dart:async'; | @@ -3,20 +3,22 @@ import 'dart:async'; | ||
3 | import 'package:flutter/scheduler.dart'; | 3 | import 'package:flutter/scheduler.dart'; |
4 | import 'package:get/src/state_manager/rx/rx_callbacks.dart'; | 4 | import 'package:get/src/state_manager/rx/rx_callbacks.dart'; |
5 | 5 | ||
6 | +/// This class is the foundation for all reactive (Rx) classes that makes Get | ||
7 | +/// so powerful. | ||
8 | +/// This interface is the contract that [_RxImpl]<[T]> uses in all it's | ||
9 | +/// subclass. | ||
6 | abstract class RxInterface<T> { | 10 | abstract class RxInterface<T> { |
7 | RxInterface([T initial]); | 11 | RxInterface([T initial]); |
8 | 12 | ||
9 | - /// add listener to stream | 13 | + StreamController<T> subject; |
14 | + | ||
15 | + /// Adds a listener to stream | ||
10 | void addListener(Stream<T> rxGetx); | 16 | void addListener(Stream<T> rxGetx); |
11 | 17 | ||
12 | bool get canUpdate; | 18 | bool get canUpdate; |
13 | 19 | ||
14 | - /// close stream | ||
15 | - void close() { | ||
16 | - subject?.close(); | ||
17 | - } | ||
18 | - | ||
19 | - StreamController<T> subject; | 20 | + /// Closes the stream |
21 | + void close() => subject?.close(); | ||
20 | 22 | ||
21 | /// Calls [callback] with current value, when the value changes. | 23 | /// Calls [callback] with current value, when the value changes. |
22 | StreamSubscription<T> listen(ValueCallback<T> callback); | 24 | StreamSubscription<T> listen(ValueCallback<T> callback); |
@@ -55,14 +57,18 @@ abstract class DisposableInterface { | @@ -55,14 +57,18 @@ abstract class DisposableInterface { | ||
55 | SchedulerBinding.instance?.addPostFrameCallback((_) => onReady()); | 57 | SchedulerBinding.instance?.addPostFrameCallback((_) => onReady()); |
56 | } | 58 | } |
57 | 59 | ||
58 | - /// Called Called immediately after the widget is allocated in memory. | 60 | + /// Called immediately after the widget is allocated in memory. |
61 | + /// You might use this initialize something for the controller. | ||
59 | void onInit() async {} | 62 | void onInit() async {} |
60 | 63 | ||
61 | - /// Called after rendering the screen. It is the perfect place to enter navigation events, | ||
62 | - /// be it snackbar, dialogs, or a new route. | 64 | + /// Called 1 frame after onInit(). It is the perfect place to enter navigation events, |
65 | + /// like snackbar, dialogs, or a new route, or async request. | ||
63 | void onReady() async {} | 66 | void onReady() async {} |
64 | 67 | ||
65 | - /// Called before the onDelete method. onClose is used to close events | ||
66 | - /// before the controller is destroyed, such as closing streams, for example. | ||
67 | - onClose() async {} | 68 | + /// Called before [onDelete] method. [onClose] might be used to dispose resources |
69 | + /// used by the controller. Like closing events, or streams before the controller is destroyed. | ||
70 | + /// Or dispose objects that can potentially create some memory leaks, | ||
71 | + /// like TextEditingControllers, AnimationControllers. | ||
72 | + /// Might be useful as well to persist some data on disk. | ||
73 | + void onClose() async {} | ||
68 | } | 74 | } |
-
Please register or login to post a comment