new change to use intaleq_map sdk 04-16-4

This commit is contained in:
Hamza-Ayed
2026-04-16 19:45:03 +03:00
parent 0aa1f15f25
commit a54a7a4189
850 changed files with 83282 additions and 3075 deletions

View File

@@ -0,0 +1,4 @@
export 'src/bindings_interface.dart';
export 'src/extension_instance.dart';
export 'src/get_instance.dart';
export 'src/lifecycle.dart';

View File

@@ -0,0 +1,65 @@
import 'get_instance.dart';
/// [Bindings] should be extended or implemented.
/// When using `GetMaterialApp`, all `GetPage`s and navigation
/// methods (like Get.to()) have a `binding` property that takes an
/// instance of Bindings to manage the
/// dependencies() (via Get.put()) for the Route you are opening.
// ignore: one_member_abstracts
abstract class Bindings {
void dependencies();
}
/// Simplifies Bindings generation from a single callback.
/// To avoid the creation of a custom Binding instance per route.
///
/// Example:
/// ```
/// GetPage(
/// name: '/',
/// page: () => Home(),
/// // This might cause you an error.
/// // binding: BindingsBuilder(() => Get.put(HomeController())),
/// binding: BindingsBuilder(() { Get.put(HomeController(); })),
/// // Using .lazyPut() works fine.
/// // binding: BindingsBuilder(() => Get.lazyPut(() => HomeController())),
/// ),
/// ```
class BindingsBuilder<T> extends Bindings {
/// Register your dependencies in the [builder] callback.
final BindingBuilderCallback builder;
/// Shortcut to register 1 Controller with Get.put(),
/// Prevents the issue of the fat arrow function with the constructor.
/// BindingsBuilder(() => Get.put(HomeController())),
///
/// Sample:
/// ```
/// GetPage(
/// name: '/',
/// page: () => Home(),
/// binding: BindingsBuilder.put(() => HomeController()),
/// ),
/// ```
factory BindingsBuilder.put(InstanceBuilderCallback<T> builder,
{String? tag, bool permanent = false}) {
return BindingsBuilder(
() => GetInstance().put<T>(builder(), tag: tag, permanent: permanent));
}
/// WARNING: don't use `()=> Get.put(Controller())`,
/// if only passing 1 callback use `BindingsBuilder.put(Controller())`
/// or `BindingsBuilder(()=> Get.lazyPut(Controller()))`
BindingsBuilder(this.builder);
@override
void dependencies() {
builder();
}
}
// abstract class INavigation {}
// typedef Snack = Function();
// typedef Modal = Function();
// typedef Route = Function();
typedef BindingBuilderCallback = void Function();

View File

@@ -0,0 +1,160 @@
import '../../route_manager.dart';
import 'get_instance.dart';
extension Inst on GetInterface {
/// Creates a new Instance<S> lazily from the `<S>builder()` callback.
///
/// The first time you call `Get.find()`, the `builder()` callback will create
/// the Instance and persisted as a Singleton (like you would use
/// `Get.put()`).
///
/// Using `Get.smartManagement` as [SmartManagement.keepFactory] has
/// the same outcome
/// as using `fenix:true` :
/// The internal register of `builder()` will remain in memory to recreate
/// the Instance if the Instance has been removed with `Get.delete()`.
/// Therefore, future calls to `Get.find()` will return the same Instance.
///
/// If you need to make use of GetxController's life-cycle
/// (`onInit(), onStart(), onClose()`)
/// [fenix] is a great choice to mix with `GetBuilder` and `GetX` widgets,
/// and/or [GetMaterialApp] Navigation.
///
/// You could use `Get.lazyPut(fenix:true)` in your app's `main()` instead of
/// `Bindings` for each [GetPage].
/// And the memory management will be similar.
///
/// Subsequent calls to `Get.lazyPut` with the same parameters
/// (`<S>` and optionally [tag] will **not** override the original).
void lazyPut<S>(InstanceBuilderCallback<S> builder,
{String? tag, bool fenix = false}) {
GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix);
}
// void printInstanceStack() {
// GetInstance().printInstanceStack();
// }
/// async version of `Get.put()`.
/// Awaits for the resolution of the Future from `builder()`parameter and
/// stores the Instance returned.
Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder,
{String? tag, bool permanent = false}) async =>
GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent);
/// Creates a new Class Instance [S] from the builder callback[S].
/// Every time `find<S>()` is used, it calls the builder method to generate
/// a new Instance [S].
/// It also registers each `instance.onClose()` with the current
/// Route `GetConfig.currentRoute` to keep the lifecycle active.
/// Is important to know that the instances created are only stored per Route.
/// So, if you call `Get.delete<T>()` the "instance factory" used in this
/// method (`Get.create<T>()`) will be removed, but NOT the instances
/// already created by it.
/// Uses `tag` as the other methods.
///
/// Example:
///
/// ```create(() => Repl());
/// Repl a = find();
/// Repl b = find();
/// print(a==b); (false)```
void create<S>(InstanceBuilderCallback<S> builder,
{String? tag, bool permanent = true}) =>
GetInstance().create<S>(builder, tag: tag, permanent: permanent);
/// Finds a Instance of the required Class `<S>`(or [tag])
/// In the case of using `Get.create()`, it will generate an Instance
/// each time you call `Get.find()`.
S find<S>({String? tag}) => GetInstance().find<S>(tag: tag);
/// Injects an `Instance<S>` in memory.
///
/// No need to define the generic type `<[S]>` as it's inferred
/// from the [dependency] parameter.
///
/// - [dependency] The Instance to be injected.
/// - [tag] optionally, use a [tag] as an "id" to create multiple records
/// of the same `Type<S>` the [tag] does **not** conflict with the same tags
/// used by other dependencies Types.
/// - [permanent] keeps the Instance in memory and persist it,
/// not following `Get.smartManagement`
/// rules. Although, can be removed by `GetInstance.reset()`
/// and `Get.delete()`
/// - [builder] If defined, the [dependency] must be returned from here
S put<S>(S dependency,
{String? tag,
bool permanent = false,
InstanceBuilderCallback<S>? builder}) =>
GetInstance().put<S>(dependency, tag: tag, permanent: permanent);
/// Clears all registered instances (and/or tags).
/// Even the persistent ones.
///
/// - `clearFactory` clears the callbacks registered by `Get.lazyPut()`
/// - `clearRouteBindings` clears Instances associated with Routes when using
/// [GetMaterialApp].
// bool reset(
// {@deprecated bool clearFactory = true,
// @deprecated bool clearRouteBindings = true}) =>
// GetInstance().reset(
// // 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`).
///
/// - [tag] Optional "tag" used to register the Instance
/// - [force] Will delete an Instance even if marked as `permanent`.
Future<bool> delete<S>({String? tag, bool force = false}) async =>
GetInstance().delete<S>(tag: tag, force: force);
/// Deletes all Instances, cleaning the memory and closes any open
/// controllers (`DisposableInterface`).
///
/// - [force] Will delete the Instances even if marked as `permanent`.
Future<void> deleteAll({bool force = false}) async =>
GetInstance().deleteAll(force: force);
void reloadAll({bool force = false}) => GetInstance().reloadAll(force: force);
void reload<S>({String? tag, String? key, bool force = false}) =>
GetInstance().reload<S>(tag: tag, key: key, force: force);
/// Checks if a Class `Instance<S>` (or [tag]) is registered in memory.
/// - [tag] optional, if you use a [tag] to register the Instance.
bool isRegistered<S>({String? tag}) =>
GetInstance().isRegistered<S>(tag: tag);
/// Checks if an `Instance<S>` (or [tag]) returned from a factory builder
/// `Get.lazyPut()`, is registered in memory.
/// - [tag] optional, if you use a [tag] to register the Instance.
bool isPrepared<S>({String? tag}) => GetInstance().isPrepared<S>(tag: tag);
/// Replace a parent instance of a class in dependency management
/// with a [child] instance
/// - [tag] optional, if you use a [tag] to register the Instance.
void replace<P>(P child, {String? tag}) {
final info = GetInstance().getInstanceInfo<P>(tag: tag);
final permanent = (info.isPermanent ?? false);
delete<P>(tag: tag, force: permanent);
put(child, tag: tag, permanent: permanent);
}
/// Replaces a parent instance with a new Instance<P> lazily from the
/// `<P>builder()` callback.
/// - [tag] optional, if you use a [tag] to register the Instance.
/// - [fenix] optional
///
/// Note: if fenix is not provided it will be set to true if
/// the parent instance was permanent
void lazyReplace<P>(InstanceBuilderCallback<P> builder,
{String? tag, bool? fenix}) {
final info = GetInstance().getInstanceInfo<P>(tag: tag);
final permanent = (info.isPermanent ?? false);
delete<P>(tag: tag, force: permanent);
lazyPut(builder, tag: tag, fenix: fenix ?? permanent);
}
}

View File

@@ -0,0 +1,551 @@
import 'dart:async';
import '../../get_core/get_core.dart';
import '../../get_navigation/src/router_report.dart';
import 'lifecycle.dart';
class InstanceInfo {
final bool? isPermanent;
final bool? isSingleton;
bool get isCreate => !isSingleton!;
final bool isRegistered;
final bool isPrepared;
final bool? isInit;
const InstanceInfo({
required this.isPermanent,
required this.isSingleton,
required this.isRegistered,
required this.isPrepared,
required this.isInit,
});
}
class GetInstance {
factory GetInstance() => _getInstance ??= const GetInstance._();
const GetInstance._();
static GetInstance? _getInstance;
T call<T>() => find<T>();
/// Holds references to every registered Instance when using
/// `Get.put()`
static final Map<String, _InstanceBuilderFactory> _singl = {};
/// Holds a reference to every registered callback when using
/// `Get.lazyPut()`
// static final Map<String, _Lazy> _factory = {};
void injector<S>(
InjectorBuilderCallback<S> fn, {
String? tag,
bool fenix = false,
// bool permanent = false,
}) {
lazyPut(
() => fn(this),
tag: tag,
fenix: fenix,
// permanent: permanent,
);
}
/// async version of `Get.put()`.
/// Awaits for the resolution of the Future from `builder()` parameter and
/// stores the Instance returned.
Future<S> putAsync<S>(
AsyncInstanceBuilderCallback<S> builder, {
String? tag,
bool permanent = false,
}) async {
return put<S>(await builder(), tag: tag, permanent: permanent);
}
/// Injects an instance `<S>` in memory to be globally accessible.
///
/// No need to define the generic type `<S>` as it's inferred from
/// the [dependency]
///
/// - [dependency] The Instance to be injected.
/// - [tag] optionally, use a [tag] as an "id" to create multiple records of
/// the same Type<[S]>
/// - [permanent] keeps the Instance in memory, not following
/// `Get.smartManagement` rules.
S put<S>(
S dependency, {
String? tag,
bool permanent = false,
@deprecated InstanceBuilderCallback<S>? builder,
}) {
_insert(
isSingleton: true,
name: tag,
permanent: permanent,
builder: builder ?? (() => dependency));
return find<S>(tag: tag);
}
/// Creates a new Instance<S> lazily from the `<S>builder()` callback.
///
/// The first time you call `Get.find()`, the `builder()` callback will create
/// the Instance and persisted as a Singleton (like you would
/// use `Get.put()`).
///
/// Using `Get.smartManagement` as [SmartManagement.keepFactory] has
/// the same outcome as using `fenix:true` :
/// The internal register of `builder()` will remain in memory to recreate
/// the Instance if the Instance has been removed with `Get.delete()`.
/// Therefore, future calls to `Get.find()` will return the same Instance.
///
/// If you need to make use of GetxController's life-cycle
/// (`onInit(), onStart(), onClose()`) [fenix] is a great choice to mix with
/// `GetBuilder()` and `GetX()` widgets, and/or `GetMaterialApp` Navigation.
///
/// You could use `Get.lazyPut(fenix:true)` in your app's `main()` instead
/// of `Bindings()` for each `GetPage`.
/// And the memory management will be similar.
///
/// Subsequent calls to `Get.lazyPut()` with the same parameters
/// (<[S]> and optionally [tag] will **not** override the original).
void lazyPut<S>(
InstanceBuilderCallback<S> builder, {
String? tag,
bool? fenix,
bool permanent = false,
}) {
_insert(
isSingleton: true,
name: tag,
permanent: permanent,
builder: builder,
fenix: fenix ?? Get.smartManagement == SmartManagement.keepFactory,
);
}
/// Creates a new Class Instance [S] from the builder callback[S].
/// Every time [find]<[S]>() is used, it calls the builder method to generate
/// a new Instance [S].
/// It also registers each `instance.onClose()` with the current
/// Route `Get.reference` to keep the lifecycle active.
/// Is important to know that the instances created are only stored per Route.
/// So, if you call `Get.delete<T>()` the "instance factory" used in this
/// method (`Get.create<T>()`) will be removed, but NOT the instances
/// already created by it.
///
/// Example:
///
/// ```create(() => Repl());
/// Repl a = find();
/// Repl b = find();
/// print(a==b); (false)```
void create<S>(
InstanceBuilderCallback<S> builder, {
String? tag,
bool permanent = true,
}) {
_insert(
isSingleton: false,
name: tag,
builder: builder,
permanent: permanent,
);
}
/// Injects the Instance [S] builder into the `_singleton` HashMap.
void _insert<S>({
bool? isSingleton,
String? name,
bool permanent = false,
required InstanceBuilderCallback<S> builder,
bool fenix = false,
}) {
final key = _getKey(S, name);
if (_singl.containsKey(key)) {
final dep = _singl[key];
if (dep != null && dep.isDirty) {
_singl[key] = _InstanceBuilderFactory<S>(
isSingleton,
builder,
permanent,
false,
fenix,
name,
lateRemove: dep as _InstanceBuilderFactory<S>,
);
}
} else {
_singl[key] = _InstanceBuilderFactory<S>(
isSingleton,
builder,
permanent,
false,
fenix,
name,
);
}
}
/// 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,
/// if `Get.smartManagement` is marked as [SmartManagement.full] or
/// [SmartManagement.keepFactory]
/// Only flags `isInit` if it's using `Get.create()`
/// (not for Singletons access).
/// Returns the instance if not initialized, required for Get.create() to
/// work properly.
S? _initDependencies<S>({String? name}) {
final key = _getKey(S, name);
final isInit = _singl[key]!.isInit;
S? i;
if (!isInit) {
i = _startController<S>(tag: name);
if (_singl[key]!.isSingleton!) {
_singl[key]!.isInit = true;
if (Get.smartManagement != SmartManagement.onlyBuilder) {
RouterReportManager.reportDependencyLinkedToRoute(_getKey(S, name));
}
}
}
return i;
}
InstanceInfo getInstanceInfo<S>({String? tag}) {
final build = _getDependency<S>(tag: tag);
return InstanceInfo(
isPermanent: build?.permanent,
isSingleton: build?.isSingleton,
isRegistered: isRegistered<S>(tag: tag),
isPrepared: !(build?.isInit ?? true),
isInit: build?.isInit,
);
}
_InstanceBuilderFactory? _getDependency<S>({String? tag, String? key}) {
final newKey = key ?? _getKey(S, tag);
if (!_singl.containsKey(newKey)) {
Get.log('Instance "$newKey" is not registered.', isError: true);
return null;
} else {
return _singl[newKey];
}
}
void markAsDirty<S>({String? tag, String? key}) {
final newKey = key ?? _getKey(S, tag);
if (_singl.containsKey(newKey)) {
final dep = _singl[newKey];
if (dep != null && !dep.permanent) {
dep.isDirty = true;
}
}
}
/// Initializes the controller
S _startController<S>({String? tag}) {
final key = _getKey(S, tag);
final i = _singl[key]!.getDependency() as S;
if (i is GetLifeCycleBase) {
i.onStart();
if (tag == null) {
Get.log('Instance "$S" has been initialized');
} else {
Get.log('Instance "$S" with tag "$tag" has been initialized');
}
if (!_singl[key]!.isSingleton!) {
RouterReportManager.appendRouteByCreate(i);
}
}
return i;
}
S putOrFind<S>(InstanceBuilderCallback<S> dep, {String? tag}) {
final key = _getKey(S, tag);
if (_singl.containsKey(key)) {
return _singl[key]!.getDependency() as S;
} else {
return GetInstance().put(dep(), tag: tag);
}
}
/// Finds the registered type <[S]> (or [tag])
/// In case of using Get.[create] to register a type <[S]> or [tag],
/// it will create an instance each time you call [find].
/// If the registered type <[S]> (or [tag]) is a Controller,
/// it will initialize it's lifecycle.
S find<S>({String? tag}) {
final key = _getKey(S, tag);
if (isRegistered<S>(tag: tag)) {
final dep = _singl[key];
if (dep == null) {
if (tag == null) {
throw 'Class "$S" is not registered';
} else {
throw 'Class "$S" with tag "$tag" is not registered';
}
}
// if (dep.lateRemove != null) {
// dep.isDirty = true;
// if(dep.fenix)
// }
/// although dirty solution, the lifecycle starts inside
/// `initDependencies`, so we have to return the instance from there
/// to make it compatible with `Get.create()`.
final i = _initDependencies<S>(name: tag);
return i ?? dep.getDependency() as S;
} else {
// ignore: lines_longer_than_80_chars
throw '"$S" not found. You need to call "Get.put($S())" or "Get.lazyPut(()=>$S())"';
}
}
/// Generates the key based on [type] (and optionally a [name])
/// to register an Instance Builder in the hashmap.
String _getKey(Type type, String? name) {
return name == null ? type.toString() : type.toString() + name;
}
/// Clears all registered instances (and/or tags).
/// Even the persistent ones.
/// This should be used at the end or tearDown of unit tests.
///
/// `clearFactory` clears the callbacks registered by [lazyPut]
/// `clearRouteBindings` clears Instances associated with routes.
///
bool resetInstance(
{@deprecated bool clearFactory = true, bool clearRouteBindings = true}) {
// if (clearFactory) _factory.clear();
// deleteAll(force: true);
if (clearRouteBindings) RouterReportManager.clearRouteKeys();
_singl.clear();
return true;
}
/// Delete registered Class Instance [S] (or [tag]) and, closes any open
/// controllers `DisposableInterface`, cleans up the memory
///
/// /// Deletes the Instance<[S]>, cleaning the memory.
// ///
// /// - [tag] Optional "tag" used to register the Instance
// /// - [key] For internal usage, is the processed key used to register
// /// the Instance. **don't use** it unless you know what you are doing.
/// Deletes the Instance<[S]>, cleaning the memory and closes any open
/// controllers (`DisposableInterface`).
///
/// - [tag] Optional "tag" used to register the Instance
/// - [key] For internal usage, is the processed key used to register
/// the Instance. **don't use** it unless you know what you are doing.
/// - [force] Will delete an Instance even if marked as `permanent`.
bool delete<S>({String? tag, String? key, bool force = false}) {
final newKey = key ?? _getKey(S, tag);
if (!_singl.containsKey(newKey)) {
Get.log('Instance "$newKey" already removed.', isError: true);
return false;
}
final dep = _singl[newKey];
if (dep == null) return false;
final _InstanceBuilderFactory builder;
if (dep.isDirty) {
builder = dep.lateRemove ?? dep;
} else {
builder = dep;
}
if (builder.permanent && !force) {
Get.log(
// ignore: lines_longer_than_80_chars
'"$newKey" has been marked as permanent, SmartManagement is not authorized to delete it.',
isError: true,
);
return false;
}
final i = builder.dependency;
if (i is GetxServiceMixin && !force) {
return false;
}
if (i is GetLifeCycleBase) {
i.onDelete();
Get.log('"$newKey" onDelete() called');
}
if (builder.fenix) {
builder.dependency = null;
builder.isInit = false;
return true;
} else {
if (dep.lateRemove != null) {
dep.lateRemove = null;
Get.log('"$newKey" deleted from memory');
return false;
} else {
_singl.remove(newKey);
if (_singl.containsKey(newKey)) {
Get.log('Error removing object "$newKey"', isError: true);
} else {
Get.log('"$newKey" deleted from memory');
}
return true;
}
}
}
/// Delete all registered Class Instances and, closes any open
/// controllers `DisposableInterface`, cleans up the memory
///
/// - [force] Will delete the Instances even if marked as `permanent`.
void deleteAll({bool force = false}) {
final keys = _singl.keys.toList();
for (final key in keys) {
delete(key: key, force: force);
}
}
void reloadAll({bool force = false}) {
_singl.forEach((key, value) {
if (value.permanent && !force) {
Get.log('Instance "$key" is permanent. Skipping reload');
} else {
value.dependency = null;
value.isInit = false;
Get.log('Instance "$key" was reloaded.');
}
});
}
void reload<S>({
String? tag,
String? key,
bool force = false,
}) {
final newKey = key ?? _getKey(S, tag);
final builder = _getDependency<S>(tag: tag, key: newKey);
if (builder == null) return;
if (builder.permanent && !force) {
Get.log(
'''Instance "$newKey" is permanent. Use [force = true] to force the restart.''',
isError: true,
);
return;
}
final i = builder.dependency;
if (i is GetxServiceMixin && !force) {
return;
}
if (i is GetLifeCycleBase) {
i.onDelete();
Get.log('"$newKey" onDelete() called');
}
builder.dependency = null;
builder.isInit = false;
Get.log('Instance "$newKey" was restarted.');
}
/// Check if a Class Instance<[S]> (or [tag]) is registered in memory.
/// - [tag] is optional, if you used a [tag] to register the Instance.
bool isRegistered<S>({String? tag}) => _singl.containsKey(_getKey(S, tag));
/// Checks if a lazy factory callback `Get.lazyPut()` that returns an
/// Instance<[S]> is registered in memory.
/// - [tag] is optional, if you used a [tag] to register the lazy Instance.
bool isPrepared<S>({String? tag}) {
final newKey = _getKey(S, tag);
final builder = _getDependency<S>(tag: tag, key: newKey);
if (builder == null) {
return false;
}
if (!builder.isInit) {
return true;
}
return false;
}
}
typedef InstanceBuilderCallback<S> = S Function();
typedef InjectorBuilderCallback<S> = S Function(GetInstance);
typedef AsyncInstanceBuilderCallback<S> = Future<S> Function();
/// Internal class to register instances with `Get.put<S>()`.
class _InstanceBuilderFactory<S> {
/// Marks the Builder as a single instance.
/// For reusing [dependency] instead of [builderFunc]
bool? isSingleton;
/// When fenix mode is avaliable, when a new instance is need
/// Instance manager will recreate a new instance of S
bool fenix;
/// Stores the actual object instance when [isSingleton]=true.
S? dependency;
/// Generates (and regenerates) the instance when [isSingleton]=false.
/// Usually used by factory methods
InstanceBuilderCallback<S> builderFunc;
/// Flag to persist the instance in memory,
/// without considering `Get.smartManagement`
bool permanent = false;
bool isInit = false;
_InstanceBuilderFactory<S>? lateRemove;
bool isDirty = false;
String? tag;
_InstanceBuilderFactory(
this.isSingleton,
this.builderFunc,
this.permanent,
this.isInit,
this.fenix,
this.tag, {
this.lateRemove,
});
void _showInitLog() {
if (tag == null) {
Get.log('Instance "$S" has been created');
} else {
Get.log('Instance "$S" has been created with tag "$tag"');
}
}
/// Gets the actual instance by it's [builderFunc] or the persisted instance.
S getDependency() {
if (isSingleton!) {
if (dependency == null) {
_showInitLog();
dependency = builderFunc();
}
return dependency!;
} else {
return builderFunc();
}
}
}

View File

@@ -0,0 +1,104 @@
import '../../get_core/get_core.dart';
/// 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> {
ValueUpdater<T>? _callback;
InternalFinalCallback({ValueUpdater<T>? callback}) : _callback = callback;
T call() => _callback!.call();
}
/// The [GetLifeCycle]
///
/// ```dart
/// class SomeController with GetLifeCycle {
/// SomeController() {
/// configureLifeCycle();
/// }
/// }
/// ```
mixin GetLifeCycleBase {
/// 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>();
// /// The `configureLifeCycle` works as a constructor for the [GetLifeCycle]
// ///
// /// This method must be invoked in the constructor of the implementation
// void configureLifeCycle() {
// if (_initialized) return;
// }
/// Internal callback that starts the cycle of this controller.
final onDelete = InternalFinalCallback<void>();
/// Called immediately after the widget is allocated in memory.
/// You might use this to initialize something for the controller.
void onInit() {}
/// 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() {}
/// 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() {}
bool _initialized = false;
/// Checks whether the controller has already been initialized.
bool get initialized => _initialized;
// Internal callback that starts the cycle of this controller.
void _onStart() {
if (_initialized) return;
onInit();
_initialized = true;
}
bool _isClosed = false;
/// Checks whether the controller has already been closed.
bool get isClosed => _isClosed;
// Internal callback that starts the cycle of this controller.
void _onDelete() {
if (_isClosed) return;
_isClosed = true;
onClose();
}
void $configureLifeCycle() {
_checkIfAlreadyConfigured();
onStart._callback = _onStart;
onDelete._callback = _onDelete;
}
void _checkIfAlreadyConfigured() {
if (_initialized) {
throw """You can only call configureLifeCycle once.
The proper place to insert it is in your class's constructor
that inherits GetLifeCycle.""";
}
}
}
abstract class GetLifeCycle with GetLifeCycleBase {
GetLifeCycle() {
$configureLifeCycle();
}
}
/// Allow track difference between GetxServices and GetxControllers
mixin GetxServiceMixin {}