Jonny Borges
Committed by GitHub

Merge pull request #2093 from jonataslaw/di-refactor

Refactor Bindings, remove disposable interface, create a more composite api
Showing 38 changed files with 600 additions and 364 deletions
import 'package:get/get.dart';
import '../data/home_api_provider.dart';
import '../data/home_api_provider.dart';
import '../data/home_repository.dart';
import '../domain/adapters/repository_adapter.dart';
import '../presentation/controllers/home_controller.dart';
class HomeBinding extends Bindings {
class HomeBinding extends Binding {
@override
void dependencies() {
Get.lazyPut<IHomeProvider>(() => HomeProvider());
Get.lazyPut<IHomeRepository>(() => HomeRepository(provider: Get.find()));
Get.lazyPut(() => HomeController(homeRepository: Get.find()));
List<Bind> dependencies() {
return [
Bind.lazyPut<IHomeProvider>(() => HomeProvider()),
Bind.lazyPut<IHomeRepository>(() => HomeRepository(provider: Get.find())),
Bind.lazyPut(() => HomeController(homeRepository: Get.find())),
];
}
}
... ...
... ... @@ -2,11 +2,13 @@ import 'package:get/get.dart';
import '../controllers/dashboard_controller.dart';
class DashboardBinding extends Bindings {
class DashboardBinding extends Binding {
@override
void dependencies() {
Get.lazyPut<DashboardController>(
List<Bind> dependencies() {
return [
Bind.lazyPut<DashboardController>(
() => DashboardController(),
);
)
];
}
}
... ...
... ... @@ -2,11 +2,13 @@ import 'package:get/get.dart';
import '../controllers/home_controller.dart';
class HomeBinding extends Bindings {
class HomeBinding extends Binding {
@override
void dependencies() {
Get.lazyPut<HomeController>(
List<Bind> dependencies() {
return [
Bind.lazyPut<HomeController>(
() => HomeController(),
);
)
];
}
}
... ...
... ... @@ -2,11 +2,11 @@ import 'package:get/get.dart';
import '../controllers/login_controller.dart';
class LoginBinding extends Bindings {
class LoginBinding extends Binding {
@override
void dependencies() {
Get.lazyPut<LoginController>(
() => LoginController(),
);
List<Bind> dependencies() {
return [
Bind.lazyPut(() => LoginController()),
];
}
}
... ...
... ... @@ -2,13 +2,15 @@ import 'package:get/get.dart';
import '../controllers/product_details_controller.dart';
class ProductDetailsBinding extends Bindings {
class ProductDetailsBinding extends Binding {
@override
void dependencies() {
Get.create<ProductDetailsController>(
List<Bind> dependencies() {
return [
Bind.create<ProductDetailsController>(
() => ProductDetailsController(
Get.parameters['productId'] ?? '',
),
);
)
];
}
}
... ...
... ... @@ -2,11 +2,13 @@ import 'package:get/get.dart';
import '../controllers/products_controller.dart';
class ProductsBinding extends Bindings {
class ProductsBinding extends Binding {
@override
void dependencies() {
Get.lazyPut<ProductsController>(
List<Bind> dependencies() {
return [
Bind.lazyPut<ProductsController>(
() => ProductsController(),
);
)
];
}
}
... ...
... ... @@ -2,11 +2,13 @@ import 'package:get/get.dart';
import '../controllers/profile_controller.dart';
class ProfileBinding extends Bindings {
class ProfileBinding extends Binding {
@override
void dependencies() {
Get.lazyPut<ProfileController>(
List<Bind> dependencies() {
return [
Bind.lazyPut<ProfileController>(
() => ProfileController(),
);
)
];
}
}
... ...
... ... @@ -2,11 +2,13 @@ import 'package:get/get.dart';
import '../controllers/root_controller.dart';
class RootBinding extends Bindings {
class RootBinding extends Binding {
@override
void dependencies() {
Get.lazyPut<RootController>(
List<Bind> dependencies() {
return [
Bind.lazyPut<RootController>(
() => RootController(),
);
)
];
}
}
... ...
... ... @@ -2,11 +2,13 @@ import 'package:get/get.dart';
import '../controllers/settings_controller.dart';
class SettingsBinding extends Bindings {
class SettingsBinding extends Binding {
@override
void dependencies() {
Get.lazyPut<SettingsController>(
List<Bind> dependencies() {
return [
Bind.lazyPut<SettingsController>(
() => SettingsController(),
);
)
];
}
}
... ...
... ... @@ -46,9 +46,7 @@ class AppPages {
preventDuplicates: true,
name: _Paths.HOME,
page: () => HomeView(),
bindings: [
HomeBinding(),
],
binding: HomeBinding(),
title: null,
children: [
GetPage(
... ...
... ... @@ -12,7 +12,7 @@ export 'http/src/multipart/multipart_file.dart';
export 'http/src/response/response.dart';
export 'sockets/sockets.dart';
abstract class GetConnectInterface with GetLifeCycleBase {
abstract class GetConnectInterface with GetLifeCycleMixin {
List<GetSocket>? sockets;
GetHttpClient get httpClient;
... ...
// ignore: one_member_abstracts
import 'get_instance.dart';
// ignore: one_member_abstracts
abstract class BindingsInterface<T> {
T dependencies();
}
/// [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 {
@Deprecated('Use Binding instead')
abstract class Bindings extends BindingsInterface<void> {
@override
void dependencies();
}
... ... @@ -58,8 +66,4 @@ class BindingsBuilder<T> extends Bindings {
}
}
// abstract class INavigation {}
// typedef Snack = Function();
// typedef Modal = Function();
// typedef Route = Function();
typedef BindingBuilderCallback = void Function();
... ...
... ... @@ -250,7 +250,7 @@ class GetInstance {
S _startController<S>({String? tag}) {
final key = _getKey(S, tag);
final i = _singl[key]!.getDependency() as S;
if (i is GetLifeCycleBase) {
if (i is GetLifeCycleMixin) {
i.onStart();
if (tag == null) {
Get.log('Instance "$S" has been initialized');
... ... @@ -379,7 +379,7 @@ class GetInstance {
return false;
}
if (i is GetLifeCycleBase) {
if (i is GetLifeCycleMixin) {
i.onDelete();
Get.log('"$newKey" onDelete() called');
}
... ... @@ -452,7 +452,7 @@ class GetInstance {
return;
}
if (i is GetLifeCycleBase) {
if (i is GetLifeCycleMixin) {
i.onDelete();
Get.log('"$newKey" onDelete() called');
}
... ...
... ... @@ -10,12 +10,14 @@ import 'package:flutter/scheduler.dart';
/// }
/// }
/// ```
mixin GetLifeCycleBase {
mixin GetLifeCycleMixin {
/// Called immediately after the widget is allocated in memory.
/// You might use this to initialize something for the controller.
@protected
@mustCallSuper
void onInit() {}
void onInit() {
SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());
}
/// Called 1 frame after onInit(). It is the perfect place to enter
/// navigation events, like snackbar, dialogs, or a new route, or
... ... @@ -41,6 +43,7 @@ mixin GetLifeCycleBase {
/// lifetime cycle of the subclass.
// @protected
@mustCallSuper
@nonVirtual
void onStart() {
// _checkIfAlreadyConfigured();
if (_initialized) return;
... ... @@ -55,6 +58,7 @@ mixin GetLifeCycleBase {
// Called when the controller is removed from memory.
@mustCallSuper
@nonVirtual
void onDelete() {
if (_isClosed) return;
_isClosed = true;
... ... @@ -70,13 +74,5 @@ mixin GetLifeCycleBase {
// }
}
abstract class GetLifeCycle with GetLifeCycleBase {
@override
void onInit() {
SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());
super.onInit();
}
}
/// Allow track difference between GetxServices and GetxControllers
mixin GetxServiceMixin {}
... ...
... ... @@ -5,6 +5,7 @@ import 'package:flutter/scheduler.dart';
import '../../get_core/get_core.dart';
import '../../get_instance/src/bindings_interface.dart';
import '../../get_state_manager/src/simple/get_state.dart';
import '../../get_utils/get_utils.dart';
import '../get_navigation.dart';
import 'dialog/dialog_route.dart';
... ... @@ -508,7 +509,7 @@ extension GetNavigation on GetInterface {
String? routeName,
bool fullscreenDialog = false,
dynamic arguments,
Bindings? binding,
Binding? binding,
bool preventDuplicates = true,
bool? popGesture,
bool showCupertinoParallax = true,
... ... @@ -894,7 +895,7 @@ you can only use widgets and widget functions here''';
int? id,
String? routeName,
dynamic arguments,
Bindings? binding,
Binding? binding,
bool fullscreenDialog = false,
bool preventDuplicates = true,
Duration? duration,
... ... @@ -960,7 +961,7 @@ you can only use widgets and widget functions here''';
int? id,
String? routeName,
dynamic arguments,
Bindings? binding,
Binding? binding,
bool fullscreenDialog = false,
Transition? transition,
Curve? curve,
... ...
... ... @@ -6,8 +6,7 @@ import 'package:flutter/material.dart';
import '../../../get.dart';
import '../../../get_state_manager/src/simple/list_notifier.dart';
class GetDelegate extends RouterDelegate<GetNavConfig>
with ListenableMixin, ListNotifierMixin {
class GetDelegate extends RouterDelegate<GetNavConfig> with ListNotifierMixin {
final List<GetNavConfig> history = <GetNavConfig>[];
final PopMode backButtonPopMode;
final PreventDuplicateHandlingMode preventDuplicateHandlingMode;
... ...
... ... @@ -51,7 +51,7 @@ class GetCupertinoApp extends StatelessWidget {
final LogWriterCallback? logWriterCallback;
final bool? popGesture;
final SmartManagement smartManagement;
final Bindings? initialBinding;
final BindingsInterface? initialBinding;
final Duration? transitionDuration;
final bool? defaultGlobalState;
final List<GetPage>? getPages;
... ...
... ... @@ -56,7 +56,7 @@ class GetMaterialApp extends StatelessWidget {
final LogWriterCallback? logWriterCallback;
final bool? popGesture;
final SmartManagement smartManagement;
final Bindings? initialBinding;
final BindingsInterface? initialBinding;
final Duration? transitionDuration;
final bool? defaultGlobalState;
final List<GetPage>? getPages;
... ...
... ... @@ -44,7 +44,7 @@ class RouterReportManager<T> {
_routesByCreate.clear();
}
void appendRouteByCreate(GetLifeCycleBase i) {
void appendRouteByCreate(GetLifeCycleMixin i) {
_routesByCreate[_current] ??= HashSet<Function>();
// _routesByCreate[Get.reference]!.add(i.onDelete as Function);
_routesByCreate[_current]!.add(i.onDelete);
... ...
... ... @@ -40,7 +40,7 @@ class GetPageRoute<T> extends PageRoute<T> //MaterialPageRoute<T>
this.barrierDismissible = false,
this.barrierColor,
this.binding,
this.bindings,
this.binds,
this.routeName,
this.page,
this.title,
... ... @@ -61,9 +61,9 @@ class GetPageRoute<T> extends PageRoute<T> //MaterialPageRoute<T>
final String? routeName;
//final String reference;
final CustomTransition? customTransition;
final Bindings? binding;
final BindingsInterface? binding;
final Map<String, String>? parameter;
final List<Bindings>? bindings;
final List<Bind>? binds;
@override
final bool showCupertinoParallax;
... ... @@ -101,19 +101,40 @@ class GetPageRoute<T> extends PageRoute<T> //MaterialPageRoute<T>
if (_child != null) return _child!;
final middlewareRunner = MiddlewareRunner(middlewares);
final localbinds = [
if (binds != null) ...binds!,
];
final localbindings = [
if (bindings != null) ...bindings!,
if (binding != null) ...[binding!]
if (binding != null) ...<BindingsInterface>[binding!],
];
final bindingsToBind = middlewareRunner.runOnBindingsStart(localbindings);
if (bindingsToBind != null) {
final bindingsToBind = middlewareRunner
.runOnBindingsStart(binding != null ? localbindings : localbinds);
/// Retrocompatibility workaround, remove this when Bindings api
/// have been removed
if (bindingsToBind != null &&
bindingsToBind is! List<Bind> &&
bindingsToBind is List<BindingsInterface>) {
for (final binding in bindingsToBind) {
binding.dependencies();
}
}
final pageToBuild = middlewareRunner.runOnPageBuildStart(page)!;
if (bindingsToBind != null &&
bindingsToBind.isNotEmpty &&
bindingsToBind is List<Bind>) {
_child = Binds(
child: middlewareRunner.runOnPageBuilt(pageToBuild()),
binds: bindingsToBind,
);
} else {
_child = middlewareRunner.runOnPageBuilt(pageToBuild());
}
return _child!;
}
... ...
... ... @@ -2,7 +2,8 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../../get_core/src/get_main.dart';
import '../../../get_instance/get_instance.dart';
import '../../../get_instance/src/bindings_interface.dart';
import '../../../get_state_manager/src/simple/get_state.dart';
import '../../get_navigation.dart';
class GetPage<T> extends Page<T> {
... ... @@ -17,8 +18,8 @@ class GetPage<T> extends Page<T> {
final bool maintainState;
final bool opaque;
final double Function(BuildContext context)? gestureWidth;
final Bindings? binding;
final List<Bindings> bindings;
final BindingsInterface? binding;
final List<Bind> binds;
final CustomTransition? customTransition;
final Duration? transitionDuration;
final bool fullscreenDialog;
... ... @@ -56,7 +57,7 @@ class GetPage<T> extends Page<T> {
this.transitionDuration,
this.popGesture,
this.binding,
this.bindings = const [],
this.binds = const [],
this.transition,
this.customTransition,
this.fullscreenDialog = false,
... ... @@ -87,8 +88,8 @@ class GetPage<T> extends Page<T> {
Alignment? alignment,
bool? maintainState,
bool? opaque,
Bindings? binding,
List<Bindings>? bindings,
BindingsInterface? binding,
List<Bind>? binds,
CustomTransition? customTransition,
Duration? transitionDuration,
bool? fullscreenDialog,
... ... @@ -117,7 +118,7 @@ class GetPage<T> extends Page<T> {
maintainState: maintainState ?? this.maintainState,
opaque: opaque ?? this.opaque,
binding: binding ?? this.binding,
bindings: bindings ?? this.bindings,
binds: binds ?? this.binds,
customTransition: customTransition ?? this.customTransition,
transitionDuration: transitionDuration ?? this.transitionDuration,
fullscreenDialog: fullscreenDialog ?? this.fullscreenDialog,
... ...
// import 'package:flutter/material.dart';
// import 'package:get/get_navigation/src/router_report.dart';
// import 'package:get/instance_manager.dart';
// class Dependencies {
// void lazyPut<S>(InstanceBuilderCallback<S> builder,
// {String? tag, bool fenix = false}) {
// GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix);
// }
// S call<S>() {
// return find<S>();
// }
// Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder,
// {String? tag, bool permanent = false}) async =>
// GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent);
// void create<S>(InstanceBuilderCallback<S> builder,
// {String? tag, bool permanent = true}) =>
// GetInstance().create<S>(builder, tag: tag, permanent: permanent);
// S find<S>({String? tag}) => GetInstance().find<S>(tag: tag);
// S put<S>(S dependency,
// {String? tag,
// bool permanent = false,
// InstanceBuilderCallback<S>? builder}) =>
// GetInstance().put<S>(dependency, tag: tag, permanent: permanent);
// Future<bool> delete<S>({String? tag, bool force = false}) async =>
// GetInstance().delete<S>(tag: tag, force: force);
// 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);
// bool isRegistered<S>({String? tag}) =>
// GetInstance().isRegistered<S>(tag: tag);
// bool isPrepared<S>({String? tag}) => GetInstance().isPrepared<S>(tag: tag);
// 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);
// }
// 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);
// }
// }
// abstract class Module extends StatefulWidget {
// Module({Key? key}) : super(key: key);
// Widget view(BuildContext context);
// void dependencies(Dependencies i);
// @override
// _ModuleState createState() => _ModuleState();
// }
// class _ModuleState extends State<Module> {
// @override
// void initState() {
// RouterReportManager.instance.reportCurrentRoute(this);
// widget.dependencies(Dependencies());
// super.initState();
// }
// @override
// void dispose() {
// RouterReportManager.instance.reportRouteDispose(this);
// super.dispose();
// }
// @override
// Widget build(BuildContext context) {
// return widget.view(context);
// }
// }
import 'package:flutter/material.dart';
import '../../../instance_manager.dart';
import '../router_report.dart';
class Dependencies {
void lazyPut<S>(InstanceBuilderCallback<S> builder,
{String? tag, bool fenix = false}) {
GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix);
}
S call<S>() {
return find<S>();
}
Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder,
{String? tag, bool permanent = false}) async =>
GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent);
void create<S>(InstanceBuilderCallback<S> builder,
{String? tag, bool permanent = true}) =>
GetInstance().create<S>(builder, tag: tag, permanent: permanent);
S find<S>({String? tag}) => GetInstance().find<S>(tag: tag);
S put<S>(S dependency,
{String? tag,
bool permanent = false,
InstanceBuilderCallback<S>? builder}) =>
GetInstance().put<S>(dependency, tag: tag, permanent: permanent);
Future<bool> delete<S>({String? tag, bool force = false}) async =>
GetInstance().delete<S>(tag: tag, force: force);
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);
bool isRegistered<S>({String? tag}) =>
GetInstance().isRegistered<S>(tag: tag);
bool isPrepared<S>({String? tag}) => GetInstance().isPrepared<S>(tag: tag);
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);
}
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);
}
}
abstract class Module extends StatefulWidget {
Module({Key? key}) : super(key: key);
Widget view(BuildContext context);
void dependencies(Dependencies i);
@override
_ModuleState createState() => _ModuleState();
}
class _ModuleState extends State<Module> {
@override
void initState() {
RouterReportManager.instance.reportCurrentRoute(this);
widget.dependencies(Dependencies());
super.initState();
}
@override
void dispose() {
RouterReportManager.instance.reportRouteDispose(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
return widget.view(context);
}
}
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import '../../../get.dart';
abstract class _RouteMiddleware {
... ... @@ -77,7 +78,7 @@ abstract class _RouteMiddleware {
/// }
/// ```
/// {@end-tool}
List<Bindings>? onBindingsStart(List<Bindings> bindings);
List<R>? onBindingsStart<R>(List<R> bindings);
/// This function will be called right after the [Bindings] are initialize.
GetPageBuilder? onPageBuildStart(GetPageBuilder page);
... ... @@ -107,7 +108,7 @@ class GetMiddleware implements _RouteMiddleware {
GetPage? onPageCalled(GetPage? page) => page;
@override
List<Bindings>? onBindingsStart(List<Bindings>? bindings) => bindings;
List<R>? onBindingsStart<R>(List<R>? bindings) => bindings;
@override
GetPageBuilder? onPageBuildStart(GetPageBuilder? page) => page;
... ... @@ -155,7 +156,7 @@ class MiddlewareRunner {
return to;
}
List<Bindings>? runOnBindingsStart(List<Bindings>? bindings) {
List<R>? runOnBindingsStart<R>(List<R>? bindings) {
_getMiddlewares().forEach((element) {
bindings = element.onBindingsStart(bindings);
});
... ... @@ -212,7 +213,7 @@ class PageRedirect {
gestureWidth: _r.gestureWidth,
customTransition: _r.customTransition,
binding: _r.binding,
bindings: _r.bindings,
binds: _r.binds,
transitionDuration:
_r.transitionDuration ?? Get.defaultTransitionDuration,
transition: _r.transition,
... ... @@ -241,7 +242,7 @@ class PageRedirect {
opaque: _r.opaque,
customTransition: _r.customTransition,
binding: _r.binding,
bindings: _r.bindings,
binds: _r.binds,
transitionDuration:
_r.transitionDuration ?? Get.defaultTransitionDuration,
transition: _r.transition,
... ...
... ... @@ -2,8 +2,6 @@ library rx_stream;
import 'dart:async';
import 'package:get/get_state_manager/src/simple/list_notifier.dart';
import '../rx_typedefs/rx_typedefs.dart';
import '../rx_types/rx_types.dart';
... ...
... ... @@ -292,12 +292,9 @@ extension RxBoolExt on Rx<bool> {
/// Toggles the bool [value] between false and true.
/// A shortcut for `flag.value = !flag.value;`
/// FIXME: why return this? fluent interface is not
/// not really a dart thing since we have '..' operator
// ignore: avoid_returning_this
Rx<bool> toggle() {
void toggle() {
subject.add(!value);
return this;
// return this;
}
}
... ... @@ -324,13 +321,10 @@ extension RxnBoolExt on Rx<bool?> {
/// Toggles the bool [value] between false and true.
/// A shortcut for `flag.value = !flag.value;`
/// FIXME: why return this? fluent interface is not
/// not really a dart thing since we have '..' operator
// ignore: avoid_returning_this
Rx<bool?>? toggle() {
void toggle() {
if (value != null) {
subject.add(!value!);
return this;
// return this;
}
}
}
... ...
... ... @@ -4,7 +4,7 @@ import 'dart:async';
import 'dart:collection';
import 'package:flutter/foundation.dart';
import 'package:get/get_state_manager/src/simple/list_notifier.dart';
import '../rx_stream/rx_stream.dart';
import '../rx_typedefs/rx_typedefs.dart';
... ... @@ -12,7 +12,6 @@ part 'rx_core/rx_impl.dart';
part 'rx_core/rx_interface.dart';
part 'rx_core/rx_num.dart';
part 'rx_core/rx_string.dart';
part 'rx_iterables/rx_list.dart';
part 'rx_iterables/rx_set.dart';
part 'rx_iterables/rx_map.dart';
part 'rx_iterables/rx_set.dart';
... ...
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import '../../../get_instance/src/lifecycle.dart';
/// Unlike GetxController, which serves to control events on each of its pages,
... ... @@ -8,34 +6,6 @@ import '../../../get_instance/src/lifecycle.dart';
/// It is ideal for situations where, once started, that service will
/// remain in memory, such as Auth control for example. Only way to remove
/// it is Get.reset().
abstract class GetxService extends DisposableInterface with GetxServiceMixin {}
abstract class GetxService with GetLifeCycleMixin, GetxServiceMixin {}
abstract class DisposableInterface extends GetLifeCycle {
/// Called immediately after the widget is allocated in memory.
/// You might use this to initialize something for the controller.
@override
@mustCallSuper
void onInit() {
super.onInit();
SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());
}
/// Called 1 frame after onInit(). It is the perfect place to enter
/// navigation events, like snackbar, dialogs, or a new route, or
/// async request.
@override
void onReady() {
super.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.
@override
void onClose() {
super.onClose();
}
}
// abstract class DisposableInterface with GetLifeCycleMixin {}
... ...
... ... @@ -5,13 +5,13 @@ import 'package:flutter/widgets.dart';
import '../../../get_core/get_core.dart';
import '../../../get_instance/src/get_instance.dart';
import '../../../get_instance/src/lifecycle.dart';
import '../../../get_rx/src/rx_types/rx_types.dart';
import '../../get_state_manager.dart';
typedef GetXControllerBuilder<T extends DisposableInterface> = Widget Function(
typedef GetXControllerBuilder<T extends GetLifeCycleMixin> = Widget Function(
T controller);
class GetX<T extends DisposableInterface> extends StatefulWidget {
class GetX<T extends GetLifeCycleMixin> extends StatefulWidget {
final GetXControllerBuilder<T> builder;
final bool global;
final bool autoRemove;
... ... @@ -54,7 +54,7 @@ class GetX<T extends DisposableInterface> extends StatefulWidget {
GetXState<T> createState() => GetXState<T>();
}
class GetXState<T extends DisposableInterface> extends State<GetX<T>> {
class GetXState<T extends GetLifeCycleMixin> extends State<GetX<T>> {
final _observer = RxNotifier();
T? controller;
bool? _isCreator = false;
... ...
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import '../../../instance_manager.dart';
import '../../get_state_manager.dart';
... ... @@ -118,15 +117,8 @@ extension ReactiveT<T> on T {
typedef Condition = bool Function();
abstract class GetNotifier<T> extends Value<T> with GetLifeCycleBase {
abstract class GetNotifier<T> extends Value<T> with GetLifeCycleMixin {
GetNotifier(T initial) : super(initial);
@override
@mustCallSuper
void onInit() {
super.onInit();
SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());
}
}
extension StateExt<T> on StateMixin<T> {
... ...
... ... @@ -35,7 +35,7 @@ class _ObxState extends State<ObxWidget> {
@override
void initState() {
super.initState();
subs = _observer.listen(_updateTree, cancelOnError: false);
subs = _observer.subject.stream.listen(_updateTree, cancelOnError: false);
}
void _updateTree(_) {
... ... @@ -56,15 +56,6 @@ class _ObxState extends State<ObxWidget> {
RxInterface.notifyChildren(_observer, widget.build);
}
/// The simplest reactive widget in GetX.
///
/// Just pass your Rx variable in the root scope of the callback to have it
... ...
... ... @@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import '../../../get_instance/src/lifecycle.dart';
import '../../get_state_manager.dart';
/// Used like `SingleTickerProviderMixin` but only with Get Controllers.
... ... @@ -196,7 +197,7 @@ class _WidgetTicker extends Ticker {
/// }
/// ...
/// ```
mixin SingleGetTickerProviderMixin on DisposableInterface
mixin SingleGetTickerProviderMixin on GetLifeCycleMixin
implements TickerProvider {
@override
Ticker createTicker(TickerCallback onTick) => Ticker(onTick);
... ...
// ignore: prefer_mixin
import 'package:flutter/widgets.dart';
import '../../../instance_manager.dart';
import '../rx_flutter/rx_disposable.dart';
import '../../../instance_manager.dart';
import '../rx_flutter/rx_notifier.dart';
import 'list_notifier.dart';
// ignore: prefer_mixin
abstract class GetxController extends DisposableInterface
with ListenableMixin, ListNotifierMixin {
abstract class GetxController extends Listenable
with GetLifeCycleMixin, ListNotifierMixin {
/// Rebuilds `GetBuilder` each time you call `update()`;
/// Can take a List of [ids], that will only update the matching
/// `GetBuilder( id: )`,
... ... @@ -28,7 +27,7 @@ abstract class GetxController extends DisposableInterface
}
}
mixin ScrollMixin on GetLifeCycleBase {
mixin ScrollMixin on GetLifeCycleMixin {
final ScrollController scroll = ScrollController();
@override
... ... @@ -72,7 +71,7 @@ mixin ScrollMixin on GetLifeCycleBase {
}
}
abstract class RxController extends DisposableInterface {}
abstract class RxController with GetLifeCycleMixin {}
abstract class SuperController<T> extends FullLifeCycleController
with FullLifeCycleMixin, StateMixin<T> {}
... ...
... ... @@ -67,7 +67,7 @@ class GetResponsiveView<T> extends GetView<T> with GetResponsiveMixin {
super(key: key);
}
class GetResponsiveWidget<T extends GetLifeCycleBase?> extends GetWidget<T>
class GetResponsiveWidget<T extends GetLifeCycleMixin> extends GetWidget<T>
with GetResponsiveMixin {
@override
final bool alwaysUseBuilder;
... ...
import 'package:flutter/material.dart';
import '../../../get_instance/src/get_instance.dart';
import '../../../instance_manager.dart';
import '../../get_state_manager.dart';
typedef GetControllerBuilder<T extends DisposableInterface> = Widget Function(
typedef InitBuilder<T> = T Function();
typedef GetControllerBuilder<T extends GetLifeCycleMixin> = Widget Function(
T controller);
extension WatchExt on BuildContext {
T listen<T extends GetxController>() {
return Scope.of(this, rebuild: true);
return Bind.of(this, rebuild: true);
}
}
extension ReadExt on BuildContext {
T find<T extends GetxController>() {
return Scope.of(this);
T get<T extends GetxController>() {
return Bind.of(this);
}
}
// extension FilterExt on BuildContext {
// T filter<T extends GetxController>(Object Function(T value)? filter) {
// return Scope.of(this, filter: filter, rebuild: true);
// return Bind.of(this, filter: filter, rebuild: true);
// }
// }
... ... @@ -33,10 +34,10 @@ class GetBuilder<T extends GetxController> extends StatelessWidget {
final bool autoRemove;
final bool assignId;
final Object Function(T value)? filter;
final void Function(ScopeElement<T> state)? initState,
final void Function(BindElement<T> state)? initState,
dispose,
didChangeDependencies;
final void Function(Scope<T> oldWidget, ScopeElement<T> state)?
final void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
didUpdateWidget;
final T? init;
... ... @@ -58,8 +59,8 @@ class GetBuilder<T extends GetxController> extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scope<T>(
init: init,
return BindWrapper(
init: init == null ? null : () => init!,
global: global,
autoRemove: autoRemove,
assignId: assignId,
... ... @@ -71,7 +72,7 @@ class GetBuilder<T extends GetxController> extends StatelessWidget {
didChangeDependencies: didChangeDependencies,
didUpdateWidget: didUpdateWidget,
child: Builder(builder: (context) {
final controller = Scope.of<T>(context, rebuild: true);
final controller = Bind.of<T>(context, rebuild: true);
return builder(controller);
}),
);
... ... @@ -79,14 +80,10 @@ class GetBuilder<T extends GetxController> extends StatelessWidget {
}
}
class Scope<T extends GetxController> extends InheritedWidget {
/// Create an inherited widget that updates its dependents when [controller]
/// sends notifications.
///
/// The [child] argument is required
const Scope({
abstract class Bind<T> extends StatelessWidget {
const Bind({
Key? key,
required Widget child,
required this.child,
this.init,
this.global = true,
this.autoRemove = true,
... ... @@ -98,21 +95,9 @@ class Scope<T extends GetxController> extends InheritedWidget {
this.id,
this.didChangeDependencies,
this.didUpdateWidget,
}) : super(key: key, child: child);
}) : super(key: key);
/// The [Listenable] object to which to listen.
///
/// Whenever this object sends change notifications, the dependents of this
/// widget are triggered.
///
/// By default, whenever the [controller] is changed (including when changing to
/// or from null), if the old controller is not equal to the new controller (as
/// determined by the `==` operator), notifications are sent. This behavior
/// can be overridden by overriding [updateShouldNotify].
///
/// While the [controller] is null, no notifications are sent, since the null
/// object cannot itself send notifications.
final T? init;
final InitBuilder<T>? init;
final bool global;
final Object? id;
... ... @@ -120,19 +105,125 @@ class Scope<T extends GetxController> extends InheritedWidget {
final bool autoRemove;
final bool assignId;
final Object Function(T value)? filter;
final void Function(ScopeElement<T> state)? initState,
final void Function(BindElement<T> state)? initState,
dispose,
didChangeDependencies;
final void Function(Scope<T> oldWidget, ScopeElement<T> state)?
final void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
didUpdateWidget;
final Widget? child;
static Bind put<S extends GetxController>(S dependency,
{String? tag,
bool permanent = false,
InstanceBuilderCallback<S>? builder}) {
Get.put<S>(dependency, tag: tag, permanent: permanent, builder: builder);
return _FactoryBind<S>(
autoRemove: permanent,
assignId: true,
tag: tag,
);
}
static Bind lazyPut<S>(
InstanceBuilderCallback<S> builder, {
String? tag,
bool fenix = false,
}) {
Get.lazyPut<S>(builder, tag: tag, fenix: fenix);
return _FactoryBind<S>(
tag: tag,
);
}
static Bind create<S extends GetxController>(
InstanceBuilderCallback<S> builder,
{String? tag,
bool permanent = true}) {
Get.create<S>(builder, tag: tag, permanent: permanent);
return _FactoryBind<S>(
tag: tag,
);
}
static S find<S>({String? tag}) => GetInstance().find<S>(tag: tag);
static Future<bool> delete<S>({String? tag, bool force = false}) async =>
GetInstance().delete<S>(tag: tag, force: force);
static Future<void> deleteAll({bool force = false}) async =>
GetInstance().deleteAll(force: force);
static void reloadAll({bool force = false}) =>
GetInstance().reloadAll(force: force);
static void reload<S>({String? tag, String? key, bool force = false}) =>
GetInstance().reload<S>(tag: tag, key: key, force: force);
static bool isRegistered<S>({String? tag}) =>
GetInstance().isRegistered<S>(tag: tag);
static bool isPrepared<S>({String? tag}) =>
GetInstance().isPrepared<S>(tag: tag);
static 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);
GetInstance().put(child, tag: tag, permanent: permanent);
}
static 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);
GetInstance().lazyPut(builder, tag: tag, fenix: fenix ?? permanent);
}
factory Bind.builder({
Widget? child,
InitBuilder<T>? init,
bool global = true,
bool autoRemove = true,
bool assignId = false,
Object Function(T value)? filter,
String? tag,
Object? id,
void Function(BindElement<T> state)? initState,
void Function(BindElement<T> state)? dispose,
void Function(BindElement<T> state)? didChangeDependencies,
void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
didUpdateWidget,
}) =>
_FactoryBind<T>(
// key: key,
init: init,
global: global,
autoRemove: autoRemove,
assignId: assignId,
initState: initState,
filter: filter,
tag: tag,
dispose: dispose,
id: id,
didChangeDependencies: didChangeDependencies,
didUpdateWidget: didUpdateWidget,
child: child,
);
static T of<T extends GetxController>(
BuildContext context, {
bool rebuild = false,
// Object Function(T value)? filter,
}) {
final inheritedElement = context
.getElementForInheritedWidgetOfExactType<Scope<T>>() as ScopeElement<T>;
final inheritedElement =
context.getElementForInheritedWidgetOfExactType<BindWrapper<T>>()
as BindElement<T>?;
if (inheritedElement == null) {
throw BindError(controller: '$T', tag: null);
}
if (rebuild) {
// var newFilter = filter?.call(inheritedElement.controller!);
... ... @@ -145,15 +236,147 @@ class Scope<T extends GetxController> extends InheritedWidget {
var widget = inheritedElement.controller;
if (widget == null) {
throw 'Error: Could not find the correct dependency.';
} else {
return widget;
}
@factory
Bind<T> _copyWithChild(Widget child);
}
class _FactoryBind<T> extends Bind<T> {
@override
final InitBuilder<T>? init;
@override
final bool global;
@override
final Object? id;
@override
final String? tag;
@override
final bool autoRemove;
@override
final bool assignId;
@override
final Object Function(T value)? filter;
@override
final void Function(BindElement<T> state)? initState,
dispose,
didChangeDependencies;
@override
final void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
didUpdateWidget;
@override
final Widget? child;
const _FactoryBind({
Key? key,
this.child,
this.init,
this.global = true,
this.autoRemove = true,
this.assignId = false,
this.initState,
this.filter,
this.tag,
this.dispose,
this.id,
this.didChangeDependencies,
this.didUpdateWidget,
}) : super(key: key, child: child);
@override
Bind<T> _copyWithChild(Widget child) {
return Bind<T>.builder(
init: init,
global: global,
autoRemove: autoRemove,
assignId: assignId,
initState: initState,
filter: filter,
tag: tag,
dispose: dispose,
id: id,
didChangeDependencies: didChangeDependencies,
didUpdateWidget: didUpdateWidget,
child: child,
);
}
@override
bool updateShouldNotify(Scope<T> oldWidget) {
Widget build(BuildContext context) {
return BindWrapper<T>(
init: init,
global: global,
autoRemove: autoRemove,
assignId: assignId,
initState: initState,
filter: filter,
tag: tag,
dispose: dispose,
id: id,
didChangeDependencies: didChangeDependencies,
didUpdateWidget: didUpdateWidget,
child: child!,
);
}
}
class Binds extends StatelessWidget {
final List<Bind<dynamic>> binds;
final Widget child;
Binds({
Key? key,
required this.binds,
required this.child,
}) : assert(binds.isNotEmpty),
super(key: key);
@override
Widget build(BuildContext context) =>
binds.reversed.fold(child, (acc, e) => e._copyWithChild(acc));
}
class BindWrapper<T> extends InheritedWidget {
/// Create an inherited widget that updates its dependents when [controller]
/// sends notifications.
///
/// The [child] argument is required
const BindWrapper({
Key? key,
required Widget child,
this.init,
this.global = true,
this.autoRemove = true,
this.assignId = false,
this.initState,
this.filter,
this.tag,
this.dispose,
this.id,
this.didChangeDependencies,
this.didUpdateWidget,
}) : super(key: key, child: child);
final InitBuilder<T>? init;
final bool global;
final Object? id;
final String? tag;
final bool autoRemove;
final bool assignId;
final Object Function(T value)? filter;
final void Function(BindElement<T> state)? initState,
dispose,
didChangeDependencies;
final void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
didUpdateWidget;
@override
bool updateShouldNotify(BindWrapper<T> oldWidget) {
return oldWidget.id != id ||
oldWidget.global != global ||
oldWidget.autoRemove != autoRemove ||
... ... @@ -161,18 +384,36 @@ class Scope<T extends GetxController> extends InheritedWidget {
}
@override
InheritedElement createElement() => ScopeElement<T>(this);
InheritedElement createElement() => BindElement<T>(this);
}
/// The ScopeElement is responsible for injecting dependencies into the widget
/// The BindElement is responsible for injecting dependencies into the widget
/// tree so that they can be observed
class ScopeElement<T extends GetxController> extends InheritedElement {
ScopeElement(Scope<T> widget) : super(widget) {
class BindElement<T> extends InheritedElement {
BindElement(BindWrapper<T> widget) : super(widget) {
initState();
}
T? controller;
InitBuilder<T>? _controllerBuilder;
T? _controller;
T get controller {
if (_controller == null) {
_controller = _controllerBuilder?.call();
_subscribeToController();
if (_controller == null) {
throw BindError(controller: T, tag: widget.tag);
}
return _controller!;
} else {
return _controller!;
}
}
bool? _isCreator = false;
bool? _needStart = false;
bool _wasStarted = false;
VoidCallback? _remove;
Object? _filter;
... ... @@ -188,42 +429,50 @@ class ScopeElement<T extends GetxController> extends InheritedElement {
} else {
_isCreator = false;
}
controller = GetInstance().find<T>(tag: widget.tag);
_controllerBuilder = () => GetInstance().find<T>(tag: widget.tag);
} else {
controller = widget.init;
_controllerBuilder = widget.init;
_isCreator = true;
GetInstance().put<T>(controller!, tag: widget.tag);
GetInstance().lazyPut<T>(_controllerBuilder!, tag: widget.tag);
}
} else {
controller = widget.init;
_controllerBuilder = widget.init;
_isCreator = true;
controller?.onStart();
}
if (widget.filter != null) {
_filter = widget.filter!(controller!);
_needStart = true;
}
_subscribeToController();
}
/// Register to listen Controller's events.
/// It gets a reference to the remove() callback, to delete the
/// setState "link" from the Controller.
void _subscribeToController() {
if (widget.filter != null) {
_filter = widget.filter!(_controller!);
}
final filter = _filter != null ? _filterUpdate : getUpdate;
final localController = _controller;
if (_needStart == true && localController is GetLifeCycleMixin) {
localController.onStart();
_needStart = false;
_wasStarted = true;
}
if (localController is GetxController) {
_remove?.call();
_remove = (widget.id == null)
? controller?.addListener(
_filter != null ? _filterUpdate : getUpdate,
)
: controller?.addListenerId(
widget.id,
_filter != null ? _filterUpdate : getUpdate,
);
? localController.addListener(filter)
: localController.addListenerId(widget.id, filter);
} else if (localController is Listenable) {
_remove?.call();
localController.addListener(filter);
_remove = () => localController.removeListener(filter);
}
}
void _filterUpdate() {
var newFilter = widget.filter!(controller!);
var newFilter = widget.filter!(_controller!);
if (newFilter != _filter) {
_filter = newFilter;
getUpdate();
... ... @@ -239,23 +488,25 @@ class ScopeElement<T extends GetxController> extends InheritedElement {
}
_remove?.call();
controller = null;
_controller = null;
_isCreator = null;
_remove = null;
_filter = null;
_needStart = null;
_controllerBuilder = null;
_controller = null;
}
@override
Scope<T> get widget => super.widget as Scope<T>;
BindWrapper<T> get widget => super.widget as BindWrapper<T>;
var _dirty = false;
@override
void update(Scope<T> newWidget) {
void update(BindWrapper<T> newWidget) {
final oldNotifier = widget.id;
final newNotifier = newWidget.id;
if (oldNotifier != newNotifier) {
if (oldNotifier != newNotifier && _wasStarted) {
_subscribeToController();
}
widget.didUpdateWidget?.call(widget, this);
... ... @@ -282,7 +533,7 @@ class ScopeElement<T extends GetxController> extends InheritedElement {
}
@override
void notifyClients(Scope<T> oldWidget) {
void notifyClients(BindWrapper<T> oldWidget) {
super.notifyClients(oldWidget);
_dirty = false;
}
... ... @@ -293,3 +544,33 @@ class ScopeElement<T extends GetxController> extends InheritedElement {
super.unmount();
}
}
class BindError<T> extends Error {
/// The type of the class the user tried to retrieve
final T controller;
final String? tag;
/// Creates a [BindError]
BindError({required this.controller, required this.tag});
@override
String toString() {
if (controller == 'dynamic') {
return '''Error: please specify type [<T>] when calling context.listen<T>() or context.find<T>() method.''';
}
return '''Error: No Bind<$controller> ancestor found. To fix this, please add a Bind<$controller> widget ancestor to the current context.
''';
}
}
/// [Binding] should be extended.
/// 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 Binding extends BindingsInterface<List<Bind>> {
@override
List<Bind> dependencies();
}
... ...
... ... @@ -47,7 +47,7 @@ abstract class GetView<T> extends StatelessWidget {
/// GetWidget is perfect to multiples instance of a same controller. Each
/// GetWidget will have your own controller, and will be call events as `onInit`
/// and `onClose` when the controller get in/get out on memory.
abstract class GetWidget<S extends GetLifeCycleBase?> extends GetWidgetCache {
abstract class GetWidget<S extends GetLifeCycleMixin> extends GetWidgetCache {
const GetWidget({Key? key}) : super(key: key);
@protected
... ... @@ -57,7 +57,7 @@ abstract class GetWidget<S extends GetLifeCycleBase?> extends GetWidgetCache {
// static final _cache = <GetWidget, GetLifeCycleBase>{};
static final _cache = Expando<GetLifeCycleBase>();
static final _cache = Expando<GetLifeCycleMixin>();
@protected
Widget build(BuildContext context);
... ... @@ -66,7 +66,7 @@ abstract class GetWidget<S extends GetLifeCycleBase?> extends GetWidgetCache {
WidgetCache createWidgetCache() => _GetCache<S>();
}
class _GetCache<S extends GetLifeCycleBase?> extends WidgetCache<GetWidget<S>> {
class _GetCache<S extends GetLifeCycleMixin> extends WidgetCache<GetWidget<S>> {
S? _controller;
bool _isCreator = false;
InstanceInfo? info;
... ... @@ -88,7 +88,7 @@ class _GetCache<S extends GetLifeCycleBase?> extends WidgetCache<GetWidget<S>> {
void onClose() {
if (_isCreator) {
Get.asap(() {
widget!.controller!.onDelete();
widget!.controller.onDelete();
Get.log('"${widget!.controller.runtimeType}" onClose() called');
Get.log('"${widget!.controller.runtimeType}" deleted from memory');
GetWidget._cache[widget!] = null;
... ...
... ... @@ -9,16 +9,9 @@ typedef Disposer = void Function();
// if it brings overhead the extra call,
typedef GetStateUpdate = void Function();
class ListNotifier extends Listenable with ListenableMixin, ListNotifierMixin {}
mixin ListenableMixin implements Listenable {}
mixin ListNotifierMixin on ListenableMixin {
// int _version = 0;
// int _microtask = 0;
// int get notifierVersion => _version;
// int get notifierMicrotask => _microtask;
class ListNotifier extends Listenable with ListNotifierMixin {}
mixin ListNotifierMixin on Listenable {
List<GetStateUpdate?>? _updaters = <GetStateUpdate?>[];
HashMap<Object?, List<GetStateUpdate>>? _updatersGroupIds =
... ... @@ -28,16 +21,7 @@ mixin ListNotifierMixin on ListenableMixin {
void refresh() {
assert(_debugAssertNotDisposed());
/// This debounce the call to update.
/// It prevent errors and duplicates builds
// if (_microtask == _version) {
// _microtask++;
// scheduleMicrotask(() {
// _version++;
// _microtask = _version;
_notifyUpdate();
// });
// }
}
void _notifyUpdate() {
... ... @@ -58,17 +42,7 @@ mixin ListNotifierMixin on ListenableMixin {
@protected
void refreshGroup(Object id) {
assert(_debugAssertNotDisposed());
// /// This debounce the call to update.
// /// It prevent errors and duplicates builds
// if (_microtask == _version) {
// _microtask++;
// scheduleMicrotask(() {
// _version++;
// _microtask = _version;
_notifyIdUpdate(id);
// });
// }
}
bool _debugAssertNotDisposed() {
... ... @@ -147,7 +121,6 @@ class TaskManager {
static TaskManager get instance => _instance ??= TaskManager._();
GetStateUpdate? _setter;
List<VoidCallback>? _remove;
void notify(List<GetStateUpdate?>? _updaters) {
... ...
... ... @@ -8,10 +8,10 @@ class MixinBuilder<T extends GetxController> extends StatelessWidget {
final bool global;
final String? id;
final bool autoRemove;
final void Function(ScopeElement<T> state)? initState,
final void Function(BindElement<T> state)? initState,
dispose,
didChangeDependencies;
final void Function(Scope<T> oldWidget, ScopeElement<T> state)?
final void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
didUpdateWidget;
final T? init;
... ...
... ... @@ -12,7 +12,7 @@ class Mock {
}
}
abstract class MyController extends GetLifeCycle {}
abstract class MyController with GetLifeCycleMixin {}
class DisposableController extends MyController {}
... ...