Jonny Borges

final fix to controllers is not removed

... ... @@ -100,7 +100,7 @@ class HomeView extends GetView<HomeController> {
color: Colors.black,
),
),
)
),
],
);
},
... ...
... ... @@ -9,7 +9,6 @@ abstract class GetInterface {
SmartManagement smartManagement = SmartManagement.full;
RouterDelegate? routerDelegate;
RouteInformationParser? routeInformationParser;
String? reference;
bool isLogEnable = true;
LogWriterCallback log = defaultLogWriterCallback;
}
... ...
... ... @@ -32,9 +32,9 @@ extension Inst on GetInterface {
GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix);
}
void printInstanceStack() {
GetInstance().printInstanceStack();
}
// void printInstanceStack() {
// GetInstance().printInstanceStack();
// }
/// async version of `Get.put()`.
/// Awaits for the resolution of the Future from `builder()`parameter and
... ... @@ -95,9 +95,14 @@ extension Inst on GetInterface {
/// - [clearFactory] clears the callbacks registered by `Get.lazyPut()`
/// - [clearRouteBindings] clears Instances associated with Routes when using
/// [GetMaterialApp].
bool reset({bool clearFactory = true, bool clearRouteBindings = true}) =>
bool reset(
{@deprecated bool clearFactory = true,
@deprecated bool clearRouteBindings = true}) =>
GetInstance().reset(
clearFactory: clearFactory, clearRouteBindings: clearRouteBindings);
// ignore: deprecated_member_use_from_same_package
clearFactory: clearFactory,
// ignore: deprecated_member_use_from_same_package
clearRouteBindings: clearRouteBindings);
/// Deletes the `Instance<S>`, cleaning the memory and closes any open
/// controllers (`DisposableInterface`).
... ...
import 'dart:async';
import 'dart:collection';
import '../../get_core/get_core.dart';
import '../../get_navigation/src/router_report.dart';
import 'lifecycle.dart';
class InstanceInfo {
... ... @@ -38,20 +37,6 @@ class GetInstance {
/// `Get.lazyPut()`
// static final Map<String, _Lazy> _factory = {};
/// Holds a reference to `Get.reference` when the Instance was
/// created to manage the memory.
static final Map<String, String?> _routesKey = {};
/// Stores the onClose() references of instances created with `Get.create()`
/// using the `Get.reference`.
/// Experimental feature to keep the lifecycle and memory management with
/// non-singleton instances.
static final Map<String?, HashSet<Function>> _routesByCreate = {};
void printInstanceStack() {
Get.log(_routesKey.toString());
}
void injector<S>(
InjectorBuilderCallback<S> fn, {
String? tag,
... ... @@ -189,64 +174,6 @@ class GetInstance {
);
}
/// Clears from memory registered Instances associated with [routeName] when
/// using `Get.smartManagement` as [SmartManagement.full] or
/// [SmartManagement.keepFactory]
/// Meant for internal usage of `GetPageRoute` and `GetDialogRoute`
void removeDependencyByRoute(String routeName) {
final keysToRemove = <String>[];
_routesKey.forEach((key, value) {
if (value == routeName) {
keysToRemove.add(key);
}
});
/// Removes `Get.create()` instances registered in `routeName`.
if (_routesByCreate.containsKey(routeName)) {
for (final onClose in _routesByCreate[routeName]!) {
// assure the [DisposableInterface] instance holding a reference
// to onClose() wasn't disposed.
onClose();
}
_routesByCreate[routeName]!.clear();
_routesByCreate.remove(routeName);
}
for (final element in keysToRemove) {
delete(key: element);
_routesKey.remove(element);
}
keysToRemove.clear();
}
void reloadDependencyByRoute(String routeName) {
final keysToRemove = <String>[];
_routesKey.forEach((key, value) {
if (value == routeName) {
keysToRemove.add(key);
}
});
/// Removes `Get.create()` instances registered in `routeName`.
if (_routesByCreate.containsKey(routeName)) {
for (final onClose in _routesByCreate[routeName]!) {
// assure the [DisposableInterface] instance holding a reference
// to onClose() wasn't disposed.
onClose();
}
_routesByCreate[routeName]!.clear();
_routesByCreate.remove(routeName);
}
for (final element in keysToRemove) {
reload(key: element, closeInstance: false);
//_routesKey.remove(element);
}
keysToRemove.clear();
}
/// Initializes the dependencies for a Class Instance [S] (or tag),
/// If its a Controller, it starts the lifecycle process.
/// Optionally associating the current Route to the lifetime of the instance,
... ... @@ -265,19 +192,13 @@ class GetInstance {
if (_singl[key]!.isSingleton!) {
_singl[key]!.isInit = true;
if (Get.smartManagement != SmartManagement.onlyBuilder) {
_registerRouteInstance<S>(tag: name);
RouterReportManager.reportDependencyLinkedToRoute(_getKey(S, name));
}
}
}
return i;
}
/// Links a Class instance [S] (or [tag]) to the current route.
/// Requires usage of `GetMaterialApp`.
void _registerRouteInstance<S>({String? tag}) {
_routesKey.putIfAbsent(_getKey(S, tag), () => Get.reference);
}
InstanceInfo getInstanceInfo<S>({String? tag}) {
final build = _getDependency<S>(tag: tag);
... ... @@ -313,9 +234,7 @@ class GetInstance {
Get.log('Instance "$S" with tag "$tag" has been initialized');
}
if (!_singl[key]!.isSingleton!) {
_routesByCreate[Get.reference] ??= HashSet<Function>();
// _routesByCreate[Get.reference]!.add(i.onDelete as Function);
_routesByCreate[Get.reference]!.add(i.onDelete);
RouterReportManager.appendRouteByCreate(i);
}
}
return i;
... ... @@ -370,10 +289,13 @@ class GetInstance {
/// [clearFactory] clears the callbacks registered by [lazyPut]
/// [clearRouteBindings] clears Instances associated with routes.
///
bool reset({bool clearFactory = true, bool clearRouteBindings = true}) {
bool reset(
{@deprecated bool clearFactory = true,
@deprecated bool clearRouteBindings = true}) {
// if (clearFactory) _factory.clear();
if (clearRouteBindings) _routesKey.clear();
_singl.clear();
deleteAll(force: true);
// if (clearRouteBindings) clearRouteKeys();
// _singl.clear();
return true;
}
... ...
import 'package:flutter/material.dart';
import '../../../get_core/get_core.dart';
import '../../../get_instance/src/get_instance.dart';
import '../../../get.dart';
import '../router_report.dart';
class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
GetModalBottomSheetRoute({
... ... @@ -20,8 +20,9 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
RouteSettings? settings,
this.enterBottomSheetDuration = const Duration(milliseconds: 250),
this.exitBottomSheetDuration = const Duration(milliseconds: 200),
}) : name = "BOTTOMSHEET: ${builder.hashCode}",
super(settings: settings);
}) : super(settings: settings) {
RouterReportManager.reportCurrentRoute(this);
}
final bool? isPersistent;
final WidgetBuilder? builder;
final ThemeData? theme;
... ... @@ -33,7 +34,7 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
final Color? modalBarrierColor;
final bool isDismissible;
final bool enableDrag;
final String name;
// final String name;
final Duration enterBottomSheetDuration;
final Duration exitBottomSheetDuration;
// remove safearea from top
... ... @@ -55,10 +56,7 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
@override
void dispose() {
if (Get.smartManagement != SmartManagement.onlyBuilder) {
WidgetsBinding.instance!.addPostFrameCallback(
(_) => GetInstance().removeDependencyByRoute(name));
}
RouterReportManager.reportRouteDispose(this);
super.dispose();
}
... ...
import 'package:flutter/widgets.dart';
import '../../../get_core/get_core.dart';
import '../../../get_instance/src/get_instance.dart';
import '../router_report.dart';
class GetDialogRoute<T> extends PopupRoute<T> {
GetDialogRoute({
... ... @@ -12,13 +11,14 @@ class GetDialogRoute<T> extends PopupRoute<T> {
RouteTransitionsBuilder? transitionBuilder,
RouteSettings? settings,
}) : widget = pageBuilder,
name = "DIALOG: ${pageBuilder.hashCode}",
_barrierDismissible = barrierDismissible,
_barrierLabel = barrierLabel,
_barrierColor = barrierColor,
_transitionDuration = transitionDuration,
_transitionBuilder = transitionBuilder,
super(settings: settings);
super(settings: settings) {
RouterReportManager.reportCurrentRoute(this);
}
final RoutePageBuilder widget;
... ... @@ -26,14 +26,9 @@ class GetDialogRoute<T> extends PopupRoute<T> {
bool get barrierDismissible => _barrierDismissible;
final bool _barrierDismissible;
final String name;
@override
void dispose() {
if (Get.smartManagement != SmartManagement.onlyBuilder) {
WidgetsBinding.instance!.addPostFrameCallback(
(_) => GetInstance().removeDependencyByRoute(name));
}
RouterReportManager.reportRouteDispose(this);
super.dispose();
}
... ...
... ... @@ -235,7 +235,7 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
}
bool _canPopHistory() {
return history.length > 0;
return history.length > 1;
}
Future<bool> canPopHistory() {
... ... @@ -347,8 +347,8 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
dynamic arguments,
Map<String, String>? parameters,
}) async {
await popHistory();
await toNamed(page, arguments: arguments, parameters: parameters);
await _unsafeHistoryRemoveAt(history.length - 2);
}
/// Removes routes according to [PopMode]
... ...
import 'dart:collection';
import 'package:flutter/widgets.dart';
import '../../get.dart';
class RouterReportManager<T> {
/// Holds a reference to `Get.reference` when the Instance was
/// created to manage the memory.
static final Map<String, Route?> _routesKey = {};
/// Stores the onClose() references of instances created with `Get.create()`
/// using the `Get.reference`.
/// Experimental feature to keep the lifecycle and memory management with
/// non-singleton instances.
static final Map<Route?, HashSet<Function>> _routesByCreate = {};
void printInstanceStack() {
Get.log(_routesKey.toString());
}
static Route? _current;
// ignore: use_setters_to_change_properties
static void reportCurrentRoute(Route newRoute) {
_current = newRoute;
}
/// Links a Class instance [S] (or [tag]) to the current route.
/// Requires usage of `GetMaterialApp`.
static void reportDependencyLinkedToRoute(String depedencyKey) {
_routesKey.putIfAbsent(depedencyKey, () => _current);
}
void clearRouteKeys() {
_routesKey.clear();
}
static void appendRouteByCreate(GetLifeCycleBase i) {
_routesByCreate[_current] ??= HashSet<Function>();
// _routesByCreate[Get.reference]!.add(i.onDelete as Function);
_routesByCreate[_current]!.add(i.onDelete);
}
static void reportRouteDispose(Route disposed) {
if (Get.smartManagement != SmartManagement.onlyBuilder) {
WidgetsBinding.instance!.addPostFrameCallback((_) {
///TODO: Is necessary this comparator?
if (_current != disposed) {
_removeDependencyByRoute(disposed);
}
});
}
}
static void reportRouteWillDispose(Route disposed) {
final keysToRemove = <String>[];
_routesKey.forEach((key, value) {
if (value == disposed) {
keysToRemove.add(key);
}
});
/// Removes `Get.create()` instances registered in `routeName`.
if (_routesByCreate.containsKey(disposed)) {
for (final onClose in _routesByCreate[disposed]!) {
// assure the [DisposableInterface] instance holding a reference
// to onClose() wasn't disposed.
onClose();
}
_routesByCreate[disposed]!.clear();
_routesByCreate.remove(disposed);
}
for (final element in keysToRemove) {
GetInstance().reload(key: element, closeInstance: false);
//_routesKey.remove(element);
}
keysToRemove.clear();
}
/// Clears from memory registered Instances associated with [routeName] when
/// using `Get.smartManagement` as [SmartManagement.full] or
/// [SmartManagement.keepFactory]
/// Meant for internal usage of `GetPageRoute` and `GetDialogRoute`
static void _removeDependencyByRoute(Route routeName) {
final keysToRemove = <String>[];
_routesKey.forEach((key, value) {
if (value == routeName) {
keysToRemove.add(key);
}
});
/// Removes `Get.create()` instances registered in `routeName`.
if (_routesByCreate.containsKey(routeName)) {
for (final onClose in _routesByCreate[routeName]!) {
// assure the [DisposableInterface] instance holding a reference
// to onClose() wasn't disposed.
onClose();
}
_routesByCreate[routeName]!.clear();
_routesByCreate.remove(routeName);
}
for (final element in keysToRemove) {
GetInstance().delete(key: element);
_routesKey.remove(element);
}
keysToRemove.clear();
}
}
... ...
import 'package:flutter/material.dart';
import '../../../get.dart';
import '../router_report.dart';
import 'custom_transition.dart';
import 'get_transition_mixin.dart';
import 'route_middleware.dart';
... ... @@ -34,14 +35,15 @@ class GetPageRoute<T> extends PageRoute<T> with GetPageRouteTransitionMixin<T> {
this.maintainState = true,
bool fullscreenDialog = false,
this.middlewares,
}) : reference = "$routeName: ${settings?.hashCode ?? page.hashCode}",
super(settings: settings, fullscreenDialog: fullscreenDialog);
}) : super(settings: settings, fullscreenDialog: fullscreenDialog) {
RouterReportManager.reportCurrentRoute(this);
}
@override
final Duration transitionDuration;
final GetPageBuilder? page;
final String? routeName;
final String reference;
//final String reference;
final CustomTransition? customTransition;
final Bindings? binding;
final Map<String, String>? parameter;
... ... @@ -73,13 +75,7 @@ class GetPageRoute<T> extends PageRoute<T> with GetPageRouteTransitionMixin<T> {
@override
void dispose() {
super.dispose();
if (Get.smartManagement != SmartManagement.onlyBuilder) {
WidgetsBinding.instance!.addPostFrameCallback((_) {
if (Get.reference != reference) {
GetInstance().removeDependencyByRoute("$reference");
}
});
}
RouterReportManager.reportRouteDispose(this);
// if (Get.smartManagement != SmartManagement.onlyBuilder) {
// GetInstance().removeDependencyByRoute("$reference");
... ... @@ -91,7 +87,6 @@ class GetPageRoute<T> extends PageRoute<T> with GetPageRouteTransitionMixin<T> {
@override
Widget buildContent(BuildContext context) {
Get.reference = reference;
final middlewareRunner = MiddlewareRunner(middlewares);
final bindingsToBind = middlewareRunner.runOnBindingsStart(bindings);
... ...
... ... @@ -4,6 +4,7 @@ import '../../../../get_core/get_core.dart';
import '../../../../instance_manager.dart';
import '../../../get_navigation.dart';
import '../../dialog/dialog_route.dart';
import '../../router_report.dart';
import '../../snackbar/snack_route.dart';
import '../default_route.dart';
... ... @@ -47,11 +48,11 @@ String? _extractRouteName(Route? route) {
}
if (route is GetDialogRoute) {
return route.name;
return 'DIALOG ${route.hashCode}';
}
if (route is GetModalBottomSheetRoute) {
return route.name;
return 'BOTTOMSHEET ${route.hashCode}';
}
return null;
... ... @@ -105,7 +106,7 @@ class GetObserver extends NavigatorObserver {
Get.log("GOING TO ROUTE ${newRoute.name}");
}
Get.reference = newRoute.name;
RouterReportManager.reportCurrentRoute(route);
_routeSend?.update((value) {
// Only PageRoute is allowed to change current value
if (route is PageRoute) {
... ... @@ -142,8 +143,10 @@ class GetObserver extends NavigatorObserver {
} else if (currentRoute.isGetPageRoute) {
Get.log("CLOSE TO ROUTE ${currentRoute.name}");
}
if (previousRoute != null) {
RouterReportManager.reportCurrentRoute(previousRoute);
}
Get.reference = newRoute.name;
// Here we use a 'inverse didPush set', meaning that we use
// previous route instead of 'route' because this is
// a 'inverse push'
... ... @@ -178,7 +181,10 @@ class GetObserver extends NavigatorObserver {
Get.log("REPLACE ROUTE $oldName");
Get.log("NEW ROUTE $newName");
Get.reference = newName;
if (oldRoute != null) {
RouterReportManager.reportCurrentRoute(oldRoute);
}
_routeSend?.update((value) {
// Only PageRoute is allowed to change current value
if (newRoute is PageRoute) {
... ... @@ -196,7 +202,7 @@ class GetObserver extends NavigatorObserver {
value.isDialog = currentRoute.isDialog ? false : value.isDialog;
});
if (oldRoute is GetPageRoute) {
GetInstance().reloadDependencyByRoute(oldRoute.reference);
RouterReportManager.reportRouteWillDispose(oldRoute);
}
routing?.call(_routeSend);
... ... @@ -222,7 +228,7 @@ class GetObserver extends NavigatorObserver {
});
if (route is GetPageRoute) {
GetInstance().reloadDependencyByRoute(route.reference);
RouterReportManager.reportRouteWillDispose(route);
}
routing?.call(_routeSend);
}
... ...