router_report.dart
3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import 'dart:collection';
import '../../get.dart';
class RouterReportManager<T> {
  /// Holds a reference to `Get.reference` when the Instance was
  /// created to manage the memory.
  final Map<T?, List<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.
  final Map<T?, HashSet<Function>> _routesByCreate = {};
  static RouterReportManager? _instance;
  RouterReportManager._();
  static RouterReportManager get instance =>
      _instance ??= RouterReportManager._();
  static void dispose() {
    _instance = null;
  }
  void printInstanceStack() {
    Get.log(_routesKey.toString());
  }
  T? _current;
  // ignore: use_setters_to_change_properties
  void reportCurrentRoute(T newRoute) {
    _current = newRoute;
  }
  /// Links a Class instance [S] (or [tag]) to the current route.
  /// Requires usage of `GetMaterialApp`.
  void reportDependencyLinkedToRoute(String depedencyKey) {
    if (_current == null) return;
    if (_routesKey.containsKey(_current)) {
      _routesKey[_current!]!.add(depedencyKey);
    } else {
      _routesKey[_current] = <String>[depedencyKey];
    }
  }
  void clearRouteKeys() {
    _routesKey.clear();
    _routesByCreate.clear();
  }
  void appendRouteByCreate(GetLifeCycleMixin i) {
    _routesByCreate[_current] ??= HashSet<Function>();
    // _routesByCreate[Get.reference]!.add(i.onDelete as Function);
    _routesByCreate[_current]!.add(i.onDelete);
  }
  void reportRouteDispose(T disposed) {
    if (Get.smartManagement != SmartManagement.onlyBuilder) {
      ambiguate(Engine.instance)!.addPostFrameCallback((_) {
        _removeDependencyByRoute(disposed);
      });
    }
  }
  void reportRouteWillDispose(T disposed) {
    final keysToRemove = <String>[];
    _routesKey[disposed]?.forEach(keysToRemove.add);
    /// 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) {
      Get.markAsDirty(key: element);
      //_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`
  void _removeDependencyByRoute(T routeName) {
    final keysToRemove = <String>[];
    _routesKey[routeName]?.forEach(keysToRemove.add);
    /// 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) {
      final value = Get.delete(key: element);
      if (value) {
        _routesKey[routeName]?.remove(element);
      }
    }
    keysToRemove.clear();
  }
}