Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
fluttertpc_get
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Jonny Borges
2020-08-28 18:12:39 -0300
Browse Files
Options
Browse Files
Download
Plain Diff
Committed by
GitHub
2020-08-28 18:12:39 -0300
Commit
cb43cd6dada17a74623673dc747852fb69367650
cb43cd6d
2 parents
71078c8d
619d90da
Merge pull request #519 from roipeker/master
GetInstance cleanup
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
329 additions
and
94 deletions
lib/src/instance/extension_instance.dart
lib/src/instance/get_instance.dart
lib/src/navigation/root/parse_route.dart
lib/src/navigation/routes/bindings_interface.dart
lib/src/state_manager/rx/rx_impl.dart
lib/src/state_manager/rx/rx_interface.dart
lib/src/instance/extension_instance.dart
View file @
cb43cd6
import
'package:get/src/core/get_interface.dart'
;
import
'get_instance.dart'
;
extension
Inst
on
GetInterface
{
...
...
@@ -10,13 +11,36 @@ extension Inst on GetInterface {
{
String
tag
,
bool
permanent
=
false
})
async
=>
GetInstance
().
putAsync
<
S
>(
builder
,
tag:
tag
,
permanent:
permanent
);
/// Creates a new Instance<[S]> from the <[S]>[builder] callback.
/// Every time [find]<[S]>() is used, it calls the builder method to generate
/// a new Instance [S].
///
/// Example:
///
/// ```create(() => Repl());
/// Repl a = find();
/// Repl b = find();
/// print(a==b); (false)```
///
void
create
<
S
>(
FcBuilderFunc
<
S
>
builder
,
{
String
name
,
bool
permanent
=
true
})
=>
GetInstance
().
create
<
S
>(
builder
,
name:
name
,
permanent:
permanent
);
S
find
<
S
>({
String
tag
,
FcBuilderFunc
<
S
>
instance
})
=>
GetInstance
().
find
<
S
>(
tag:
tag
,
instance:
instance
);
/// Finds a instance of the required Class<[S]> (or [tag])
/// In the case of using Get.[create], it will create an instance
/// each time you call [find]
///
S
find
<
S
>({
String
tag
})
=>
GetInstance
().
find
<
S
>(
tag:
tag
);
/// Injects a Instance [S] in [GetInstance].
///
/// 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 [GetConfig.smartManagement]
/// rules
///
S
put
<
S
>(
S
dependency
,
{
String
tag
,
bool
permanent
=
false
,
FcBuilderFunc
<
S
>
builder
})
=>
GetInstance
()
...
...
lib/src/instance/get_instance.dart
View file @
cb43cd6
import
'package:flutter/cupertino.dart'
;
import
'package:get/src/core/log.dart'
;
import
'package:get/src/navigation/root/smart_management.dart'
;
import
'package:get/src/state_manager/rx/rx_interface.dart'
;
...
...
@@ -11,28 +10,26 @@ class GetConfig {
static
String
currentRoute
;
}
class
Lazy
{
Lazy
(
this
.
builder
,
this
.
fenix
);
bool
fenix
;
FcBuilderFunc
builder
;
}
class
GetInstance
{
factory
GetInstance
()
{
if
(
_getInstance
==
null
)
_getInstance
=
GetInstance
.
_
();
return
_getInstance
;
}
factory
GetInstance
()
=>
_getInstance
??=
GetInstance
.
_
();
const
GetInstance
.
_
();
static
GetInstance
_getInstance
;
static
Map
<
dynamic
,
dynamic
>
_singl
=
{};
static
Map
<
dynamic
,
Lazy
>
_factory
=
{};
/// Holds references to every registered Instance when using
/// Get.[put]
static
Map
<
String
,
_FcBuilder
>
_singl
=
{};
/// Holds a reference to every registered callback when using
/// Get.[lazyPut]
static
Map
<
String
,
_Lazy
>
_factory
=
{};
static
Map
<
String
,
String
>
_routesKey
=
{};
static
GetQueue
_queue
=
GetQueue
();
void
lazyPut
<
S
>(
FcBuilderFunc
builder
,
{
String
tag
,
bool
fenix
=
false
})
{
String
key
=
_getKey
(
S
,
tag
);
_factory
.
putIfAbsent
(
key
,
()
=>
Lazy
(
builder
,
fenix
));
_factory
.
putIfAbsent
(
key
,
()
=>
_Lazy
(
builder
,
fenix
));
}
Future
<
S
>
putAsync
<
S
>(
FcBuilderFuncAsync
<
S
>
builder
,
...
...
@@ -40,7 +37,14 @@ class GetInstance {
return
put
<
S
>(
await
builder
(),
tag:
tag
,
permanent:
permanent
);
}
/// Inject class on Get Instance Manager
/// 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 [GetConfig.smartManagement]
/// rules.
S
put
<
S
>(
S
dependency
,
{
String
tag
,
...
...
@@ -55,12 +59,16 @@ class GetInstance {
return
find
<
S
>(
tag:
tag
);
}
/// Create a new instance from builder class
/// Example
/// create(() => Repl());
/// 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].
///
/// Example:
///
/// ```create(() => Repl());
/// Repl a = find();
/// Repl b = find();
/// print(a==b); (false)
/// print(a==b); (false)
```
void
create
<
S
>(
FcBuilderFunc
<
S
>
builder
,
{
String
name
,
...
...
@@ -70,6 +78,7 @@ class GetInstance {
isSingleton:
false
,
name:
name
,
builder:
builder
,
permanent:
permanent
);
}
/// Injects the Instance [S] builder into the [_singleton] HashMap.
void
_insert
<
S
>({
bool
isSingleton
,
String
name
,
...
...
@@ -77,14 +86,16 @@ class GetInstance {
FcBuilderFunc
<
S
>
builder
,
})
{
assert
(
builder
!=
null
);
String
key
=
_getKey
(
S
,
name
);
final
key
=
_getKey
(
S
,
name
);
_singl
.
putIfAbsent
(
key
,
()
=>
FcBuilder
<
S
>(
isSingleton
,
builder
,
permanent
,
false
));
key
,
()
=>
_
FcBuilder
<
S
>(
isSingleton
,
builder
,
permanent
,
false
));
}
/// Clears from memory registered Instances associated with [routeName] when
/// using [GetConfig.smartManagement] as [SmartManagement.full] or [SmartManagement.keepFactory]
/// Meant for internal usage of [GetPageRoute] and [GetDialogRoute]
Future
<
void
>
removeDependencyByRoute
(
String
routeName
)
async
{
List
<
String
>
keysToRemove
=
[];
final
keysToRemove
=
<
String
>
[];
_routesKey
.
forEach
((
key
,
value
)
{
if
(
value
==
routeName
)
{
keysToRemove
.
add
(
key
);
...
...
@@ -100,35 +111,43 @@ class GetInstance {
keysToRemove
.
clear
();
}
bool
initDependencies
<
S
>({
String
name
})
{
String
key
=
_getKey
(
S
,
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 [GetConfig.smartManagement] is marked as [SmartManagement.full] or
/// [GetConfig.keepFactory]
bool
_initDependencies
<
S
>({
String
name
})
{
final
key
=
_getKey
(
S
,
name
);
bool
isInit
=
_singl
[
key
].
isInit
;
if
(!
isInit
)
{
startController
<
S
>(
tag:
name
);
_
startController
<
S
>(
tag:
name
);
_singl
[
key
].
isInit
=
true
;
if
(
GetConfig
.
smartManagement
!=
SmartManagement
.
onlyBuilder
)
{
registerRouteInstance
<
S
>(
tag:
name
);
_
registerRouteInstance
<
S
>(
tag:
name
);
}
}
return
true
;
}
void
registerRouteInstance
<
S
>({
String
tag
})
{
/// 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
),
()
=>
GetConfig
.
currentRoute
);
}
/// Finds and returns a Instance<[S]> (or [tag]) without further processing.
S
findByType
<
S
>(
Type
type
,
{
String
tag
})
{
String
key
=
_getKey
(
type
,
tag
);
return
_singl
[
key
].
getDependency
()
as
S
;
}
void
startController
<
S
>({
String
tag
})
{
String
key
=
_getKey
(
S
,
tag
);
/// Initializes the controller
void
_startController
<
S
>({
String
tag
})
{
final
key
=
_getKey
(
S
,
tag
);
final
i
=
_singl
[
key
].
getDependency
();
if
(
i
is
DisposableInterface
)
{
i
.
onStart
();
GetConfig
.
log
(
'
$key
has been initialized'
);
GetConfig
.
log
(
'
"
$key
"
has been initialized'
);
}
}
...
...
@@ -153,30 +172,35 @@ class GetInstance {
// }
// }
/// Find a instance from required class
S
find
<
S
>({
String
tag
,
FcBuilderFunc
<
S
>
instance
})
{
/// 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
})
{
String
key
=
_getKey
(
S
,
tag
);
if
(
isRegistered
<
S
>(
tag:
tag
))
{
FcBuilder
builder
=
_singl
[
key
]
as
FcBuilder
;
_FcBuilder
builder
=
_singl
[
key
]
as
_
FcBuilder
;
if
(
builder
==
null
)
{
if
(
tag
==
null
)
{
throw
"class
${S.toString()}
is not register"
;
throw
'Class "
$S
" is not register'
;
}
else
{
throw
"class
${S.toString()}
with tag '
$tag
' is not register"
;
throw
'Class "
$S
" with tag "
$tag
" is not register'
;
}
}
initDependencies
<
S
>(
name:
tag
);
_
initDependencies
<
S
>(
name:
tag
);
return
_singl
[
key
].
getDependency
()
as
S
;
}
else
{
if
(!
_factory
.
containsKey
(
key
))
throw
"
$S
not found. You need call put<
$S
>(
$S
()) before"
;
throw
'"
$S
" not found. You need to call "Get.put<
$S
>(
$S
())"'
;
// TODO: This message is not clear
GetConfig
.
log
(
'"
$S
" instance was created at that time'
);
GetConfig
.
log
(
'
$S
instance was created at that time'
);
S
_value
=
put
<
S
>(
_factory
[
key
].
builder
()
as
S
);
initDependencies
<
S
>(
name:
tag
);
_
initDependencies
<
S
>(
name:
tag
);
if
(
GetConfig
.
smartManagement
!=
SmartManagement
.
keepFactory
&&
!
_factory
[
key
].
fenix
)
{
...
...
@@ -191,6 +215,12 @@ class GetInstance {
return
name
==
null
?
type
.
toString
()
:
type
.
toString
()
+
name
;
}
/// Clears all registered instances (and/or tags).
/// Even the persistent ones.
///
/// [clearFactory] clears the callbacks registered by [lazyPut]
/// [clearRouteBindings] clears Instances associated with routes.
///
bool
reset
({
bool
clearFactory
=
true
,
bool
clearRouteBindings
=
true
})
{
if
(
clearFactory
)
_factory
.
clear
();
if
(
clearRouteBindings
)
_routesKey
.
clear
();
...
...
@@ -198,33 +228,27 @@ class GetInstance {
return
true
;
}
static
GetQueue
queue
=
GetQueue
();
// Future<bool> delete<S>({String tag, String key, bool force = false}) async {
// final s = await queue
// .add<bool>(() async => dele<S>(tag: tag, key: key, force: force));
// return s;
// }
/// Delete class instance on [S] and clean memory
/// Delete registered Class Instance [S] (or [tag]) and, closes any open
/// controllers [DisposableInterface], cleans up the memory
Future
<
bool
>
delete
<
S
>({
String
tag
,
String
key
,
bool
force
=
false
})
async
{
String
newKey
;
if
(
key
==
null
)
{
newKey
=
_getKey
(
S
,
tag
);
}
else
{
newKey
=
key
;
}
final
newKey
=
key
??
_getKey
(
S
,
tag
);
return
queue
.
add
<
bool
>(()
async
{
return
_
queue
.
add
<
bool
>(()
async
{
if
(!
_singl
.
containsKey
(
newKey
))
{
GetConfig
.
log
(
'Instance
$newKey
already been
removed.'
,
isError:
true
);
GetConfig
.
log
(
'Instance
"
$newKey
" already
removed.'
,
isError:
true
);
return
false
;
}
FcBuilder
builder
=
_singl
[
newKey
]
as
FcBuilder
;
_FcBuilder
builder
=
_singl
[
newKey
]
as
_
FcBuilder
;
if
(
builder
.
permanent
&&
!
force
)
{
GetConfig
.
log
(
'
[
$newKey
]
has been marked as permanent, SmartManagement is not authorized to delete it.'
,
'
"
$newKey
"
has been marked as permanent, SmartManagement is not authorized to delete it.'
,
isError:
true
);
return
false
;
}
...
...
@@ -235,24 +259,24 @@ class GetInstance {
}
if
(
i
is
DisposableInterface
)
{
await
i
.
onClose
();
GetConfig
.
log
(
'
onClose of
$newKey
called'
);
GetConfig
.
log
(
'
"
$newKey
" onClose()
called'
);
}
_singl
.
removeWhere
((
oldKey
,
value
)
=>
(
oldKey
==
newKey
));
if
(
_singl
.
containsKey
(
newKey
))
{
GetConfig
.
log
(
'
error on remove object
$newKey
'
,
isError:
true
);
GetConfig
.
log
(
'
Error removing object "
$newKey
"
'
,
isError:
true
);
}
else
{
GetConfig
.
log
(
'
$newKey
deleted from memory'
);
GetConfig
.
log
(
'
"
$newKey
"
deleted from memory'
);
}
// _routesKey?.remove(key);
return
true
;
});
}
///
check if instance is registered
///
Check if a Class instance [S] (or [tag]) is registered.
bool
isRegistered
<
S
>({
String
tag
})
=>
_singl
.
containsKey
(
_getKey
(
S
,
tag
));
///
check if instance is prepared
///
Check if Class instance [S] (or [tag]) is prepared to be used.
bool
isPrepared
<
S
>({
String
tag
})
=>
_factory
.
containsKey
(
_getKey
(
S
,
tag
));
}
...
...
@@ -260,23 +284,37 @@ typedef FcBuilderFunc<S> = S Function();
typedef
FcBuilderFuncAsync
<
S
>
=
Future
<
S
>
Function
();
class
FcBuilder
<
S
>
{
/// Internal class to register instances with Get.[put]<[S]>().
class
_FcBuilder
<
S
>
{
/// Marks the Builder as a single instance.
/// For reusing [dependency] instead of [builderFunc]
bool
isSingleton
;
FcBuilderFunc
builderFunc
;
/// Stores the actual object instance when [isSingleton]=true.
S
dependency
;
/// Generates (and regenerates) the instance when [isSingleton]=false.
/// Usually used by factory methods
FcBuilderFunc
<
S
>
builderFunc
;
/// Flag to persist the instance in memory,
/// without considering [GetConfig.smartManagement]
bool
permanent
=
false
;
bool
isInit
=
false
;
FcBuilder
(
this
.
isSingleton
,
this
.
builderFunc
,
this
.
permanent
,
this
.
isInit
);
_
FcBuilder
(
this
.
isSingleton
,
this
.
builderFunc
,
this
.
permanent
,
this
.
isInit
);
/// Gets the actual instance by it's [builderFunc] or the persisted instance.
S
getDependency
()
{
if
(
isSingleton
)
{
if
(
dependency
==
null
)
{
dependency
=
builderFunc
()
as
S
;
}
return
dependency
;
}
else
{
return
builderFunc
()
as
S
;
}
return
isSingleton
?
dependency
??=
builderFunc
()
:
builderFunc
();
}
}
/// Internal class to register a future instance with [lazyPut],
/// keeps a reference to the callback to be called.
class
_Lazy
{
bool
fenix
;
FcBuilderFunc
builder
;
_Lazy
(
this
.
builder
,
this
.
fenix
);
}
...
...
lib/src/navigation/root/parse_route.dart
View file @
cb43cd6
...
...
@@ -10,6 +10,7 @@ class GetPageMatch {
class
ParseRouteTree
{
final
List
<
ParseRouteTreeNode
>
_nodes
=
<
ParseRouteTreeNode
>[];
// bool _hasDefaultRoute = false;
void
addRoute
(
GetPage
route
)
{
...
...
@@ -59,11 +60,14 @@ class ParseRouteTree {
if
(
usePath
.
startsWith
(
"/"
))
{
usePath
=
path
.
substring
(
1
);
}
List
<
String
>
components
=
usePath
.
split
(
"/"
);
// should take off url parameters first..
final
uri
=
Uri
.
tryParse
(
usePath
);
// List<String> components = usePath.split("/");
List
<
String
>
components
=
uri
.
pathSegments
;
if
(
path
==
Navigator
.
defaultRouteName
)
{
components
=
[
"/"
];
}
Map
<
ParseRouteTreeNode
,
ParseRouteTreeNodeMatch
>
nodeMatches
=
<
ParseRouteTreeNode
,
ParseRouteTreeNodeMatch
>{};
List
<
ParseRouteTreeNode
>
nodesToCheck
=
_nodes
;
...
...
@@ -103,6 +107,10 @@ class ParseRouteTree {
ParseRouteTreeNodeMatch
parentMatch
=
nodeMatches
[
node
.
parent
];
ParseRouteTreeNodeMatch
match
=
ParseRouteTreeNodeMatch
.
fromMatch
(
parentMatch
,
node
);
// TODO: find a way to clean this implementation.
match
.
parameters
.
addAll
(
uri
.
queryParameters
);
if
(
node
.
isParameter
())
{
String
paramKey
=
node
.
part
.
substring
(
1
);
match
.
parameters
[
paramKey
]
=
pathPart
;
...
...
lib/src/navigation/routes/bindings_interface.dart
View file @
cb43cd6
/// [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.
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(),
/// binding: BindingsBuilder(() => Get.put(HomeController())),
/// ),
/// ````
class
BindingsBuilder
extends
Bindings
{
/// Register your dependencies in the [builder] callback.
final
Function
()
builder
;
BindingsBuilder
(
this
.
builder
);
@override
void
dependencies
()
{
builder
();
}
}
// abstract class INavigation {}
// typedef Snack = Function();
// typedef Modal = Function();
...
...
lib/src/state_manager/rx/rx_impl.dart
View file @
cb43cd6
import
'dart:async'
;
import
'dart:collection'
;
import
'rx_interface.dart'
;
RxInterface
getObs
;
typedef
bool
Condition
(
);
class
_RxImpl
<
T
>
implements
RxInterface
<
T
>
{
StreamController
<
T
>
subject
=
StreamController
<
T
>.
broadcast
();
HashMap
<
Stream
<
T
>,
StreamSubscription
>
_subscriptions
=
...
...
@@ -15,14 +20,26 @@ class _RxImpl<T> implements RxInterface<T> {
return
_value
;
}
bool
get
canUpdate
{
return
_subscriptions
.
length
>
0
;
/// Common to all Types [T], this operator overloading is using for
/// assignment, same as rx.value
///
/// Example:
/// ```
/// var counter = 0.obs ;
/// counter >>= 3; // same as counter.value=3;
/// print(counter); // calls .toString() now
/// ```
///
/// WARNING: still WIP, needs testing!
_RxImpl
<
T
>
operator
>>(
T
val
)
{
subject
.
add
(
value
=
val
);
return
this
;
}
bool
get
canUpdate
=>
_subscriptions
.
isNotEmpty
;
T
call
([
T
v
])
{
if
(
v
!=
null
)
{
this
.
value
=
v
;
}
if
(
v
!=
null
)
this
.
value
=
v
;
return
this
.
value
;
}
...
...
@@ -33,15 +50,24 @@ class _RxImpl<T> implements RxInterface<T> {
String
get
string
=>
value
.
toString
();
close
()
{
_subscriptions
.
forEach
((
observable
,
subscription
)
{
subscription
.
cancel
();
});
@override
String
toString
()
=>
value
.
toString
();
/// This equality override works for _RxImpl instances and the internal values.
bool
operator
==(
o
)
{
// Todo, find a common implementation for the hashCode of different Types.
if
(
o
is
T
)
return
_value
==
o
;
if
(
o
is
_RxImpl
<
T
>)
return
_value
==
o
.
value
;
return
false
;
}
void
close
()
{
_subscriptions
.
forEach
((
observable
,
subscription
)
=>
subscription
.
cancel
());
_subscriptions
.
clear
();
subject
.
close
();
}
addListener
(
Stream
<
T
>
rxGetx
)
{
void
addListener
(
Stream
<
T
>
rxGetx
)
{
if
(
_subscriptions
.
containsKey
(
rxGetx
))
{
return
;
}
...
...
@@ -286,6 +312,16 @@ class RxList<E> extends Iterable<E> implements RxInterface<List<E>> {
subject
.
add
(
_list
);
}
/// Special override to push() element(s) in a reactive way
/// inside the List,
RxList
<
E
>
operator
+(
val
)
{
if
(
val
is
Iterable
)
subject
.
add
(
_list
..
addAll
(
val
));
else
subject
.
add
(
_list
..
add
(
val
));
return
this
;
}
E
operator
[](
int
index
)
{
return
value
[
index
];
}
...
...
@@ -428,10 +464,6 @@ class RxList<E> extends Iterable<E> implements RxInterface<List<E>> {
List
<
E
>
_list
=
<
E
>[];
}
RxInterface
getObs
;
typedef
bool
Condition
(
);
class
RxBool
extends
_RxImpl
<
bool
>
{
RxBool
([
bool
initial
])
{
_value
=
initial
;
...
...
@@ -442,24 +474,109 @@ class RxDouble extends _RxImpl<double> {
RxDouble
([
double
initial
])
{
_value
=
initial
;
}
RxDouble
operator
+(
double
val
)
{
subject
.
add
(
value
+=
val
);
return
this
;
}
RxDouble
operator
-(
double
val
)
{
subject
.
add
(
value
-=
val
);
return
this
;
}
RxDouble
operator
/(
double
val
)
{
subject
.
add
(
value
/=
val
);
return
this
;
}
RxDouble
operator
*(
double
val
)
{
subject
.
add
(
value
*=
val
);
return
this
;
}
}
class
RxNum
extends
_RxImpl
<
num
>
{
RxNum
([
num
initial
])
{
_value
=
initial
;
}
RxNum
operator
>>(
num
val
)
{
subject
.
add
(
value
=
val
);
return
this
;
}
RxNum
operator
+(
num
val
)
{
subject
.
add
(
value
+=
val
);
return
this
;
}
RxNum
operator
-(
num
val
)
{
subject
.
add
(
value
-=
val
);
return
this
;
}
RxNum
operator
/(
num
val
)
{
subject
.
add
(
value
/=
val
);
return
this
;
}
RxNum
operator
*(
num
val
)
{
subject
.
add
(
value
*=
val
);
return
this
;
}
}
class
RxString
extends
_RxImpl
<
String
>
{
RxString
([
String
initial
])
{
_value
=
initial
;
}
RxString
operator
>>(
String
val
)
{
subject
.
add
(
value
=
val
);
return
this
;
}
RxString
operator
+(
String
val
)
{
subject
.
add
(
value
+=
val
);
return
this
;
}
RxString
operator
*(
int
val
)
{
subject
.
add
(
value
*=
val
);
return
this
;
}
}
class
RxInt
extends
_RxImpl
<
int
>
{
RxInt
([
int
initial
])
{
_value
=
initial
;
}
RxInt
operator
>>(
int
val
)
{
subject
.
add
(
value
=
val
);
return
this
;
}
RxInt
operator
+(
int
val
)
{
subject
.
add
(
value
+=
val
);
return
this
;
}
RxInt
operator
-(
int
val
)
{
subject
.
add
(
value
-=
val
);
return
this
;
}
RxInt
operator
/(
int
val
)
{
subject
.
add
(
value
~/=
val
);
return
this
;
}
RxInt
operator
*(
int
val
)
{
subject
.
add
(
value
*=
val
);
return
this
;
}
}
class
Rx
<
T
>
extends
_RxImpl
<
T
>
{
...
...
lib/src/state_manager/rx/rx_interface.dart
View file @
cb43cd6
import
'dart:async'
;
import
'package:flutter/scheduler.dart'
;
import
'package:get/src/state_manager/rx/rx_callbacks.dart'
;
...
...
@@ -26,10 +27,30 @@ abstract class RxInterface<T> {
/// 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 that the widget is allocated in memory.
/// Do not overwrite this method.
void
onStart
()
{
/// 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
());
}
...
...
Please
register
or
login
to post a comment