rx_interface.dart
3.32 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
import 'dart:async';
import 'package:flutter/scheduler.dart';
import 'package:get/src/state_manager/rx/rx_callbacks.dart';
/// This class is the foundation for all reactive (Rx) classes that makes Get
/// so powerful.
/// This interface is the contract that [_RxImpl]<[T]> uses in all it's
/// subclass.
abstract class RxInterface<T> {
RxInterface([T initial]);
StreamController<T> subject;
/// Adds a listener to stream
void addListener(Stream<T> rxGetx);
bool get canUpdate;
/// Closes the stream
void close() => subject?.close();
/// Calls [callback] with current value, when the value changes.
StreamSubscription<T> listen(ValueCallback<T> callback);
}
/// Unlike GetxController, which serves to control events on each of its pages,
/// GetxService is not automatically disposed. It is ideal for situations where,
/// once started, that service will remain in memory, such as Auth control for example.
abstract class GetxService extends DisposableInterface {}
/// Special callable class to keep the contract of a regular method, and avoid
/// overrides if you extend the class that uses it, as Dart has no final methods.
/// Used in [DisposableInterface] to avoid the danger of overriding onStart.
///
class _InternalFinalCallback<T> {
T Function() callback;
_InternalFinalCallback();
T call() => callback.call();
}
abstract class DisposableInterface {
/// Called at the exact moment the widget is allocated in memory.
/// It uses an internal "callable" type, to avoid any @overrides in subclases.
/// This method should be internal and is required to define the lifetime cycle
/// of the subclass.
///
final onStart = _InternalFinalCallback<void>();
DisposableInterface() {
onStart.callback = _onStart;
}
// Internal callback that starts the cycle of this controller.
void _onStart() {
onInit();
SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());
}
/// Called immediately after the widget is allocated in memory.
/// You might use this initialize something for the controller.
void onInit() async {}
/// Called 1 frame after onInit(). It is the perfect place to enter navigation events,
/// like snackbar, dialogs, or a new route, or async request.
void onReady() async {}
/// Called before [onDelete] method. [onClose] might be used to dispose resources
/// used by the controller. Like closing events, or streams before the controller is destroyed.
/// Or dispose objects that can potentially create some memory leaks,
/// like TextEditingControllers, AnimationControllers.
/// Might be useful as well to persist some data on disk.
void onClose() async {}
}
/// Used like [SingleTickerProviderMixin] but only with Get Controllers.
/// Simplifies AnimationController creation inside GetxController.
///
/// Example:
///```
///class SplashController extends GetxController with SingleGetTickerProviderMixin {
/// AnimationController _ac;
///
/// @override
/// void onInit() {
/// final dur = const Duration(seconds: 2);
/// _ac = AnimationController.unbounded(duration: dur, vsync: this);
/// _ac.repeat();
/// _ac.addListener(() => print("Animation Controller value: ${_ac.value}"));
/// }
/// ...
/// ```
mixin SingleGetTickerProviderMixin on DisposableInterface
implements TickerProvider {
Ticker createTicker(TickerCallback onTick) => Ticker(onTick);
}