- 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