Rodrigo Lopez Peker

- 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.
@@ -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 }