Skip to content

Commit d2f9738

Browse files
committed
add sealed ScopeState
1 parent 64a6847 commit d2f9738

File tree

4 files changed

+263
-174
lines changed

4 files changed

+263
-174
lines changed
Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,34 @@
1-
enum ScopeState {
2-
none,
3-
initializing,
4-
available,
5-
disposing,
1+
abstract class ScopeState<Scope> {
2+
ScopeState._();
3+
4+
factory ScopeState.none() = ScopeStateNone;
5+
factory ScopeState.initializing() = ScopeStateInitializing;
6+
factory ScopeState.available({required Scope scope}) = ScopeStateAvailable;
7+
factory ScopeState.disposing() = ScopeStateDisposing;
8+
9+
bool get none => this is ScopeStateNone;
10+
11+
bool get initializing => this is ScopeStateInitializing;
12+
13+
bool get available => this is ScopeStateAvailable;
14+
15+
bool get disposing => this is ScopeStateDisposing;
616
}
717

8-
extension ScopeStateExt on ScopeState {
9-
bool get none => this == ScopeState.none;
18+
class ScopeStateNone<Scope> extends ScopeState<Scope> {
19+
ScopeStateNone() : super._();
20+
}
21+
22+
class ScopeStateInitializing<Scope> extends ScopeState<Scope> {
23+
ScopeStateInitializing() : super._();
24+
}
25+
26+
class ScopeStateAvailable<Scope> extends ScopeState<Scope> {
27+
final Scope scope;
28+
29+
ScopeStateAvailable({required this.scope}) : super._();
30+
}
1031

11-
bool get available => this == ScopeState.available;
32+
class ScopeStateDisposing<Scope> extends ScopeState<Scope> {
33+
ScopeStateDisposing() : super._();
1234
}

packages/yx_scope/lib/src/core/scope_state_holder.dart

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,31 @@
11
part of '../base_scope_container.dart';
22

3-
typedef StateListener<S> = void Function(S scope);
3+
typedef StateListener<S> = void Function(S? scope);
4+
5+
typedef ScopeStateListener<S> = void Function(ScopeState<S> state);
46

57
typedef RemoveStateListener = void Function();
68

79
class ScopeStateHolder<Scope> {
810
final _listeners = LinkedList<Entry<Scope>>();
9-
Scope _scope;
11+
ScopeState<Scope> _state;
1012

1113
bool _debugCanAddListeners = true;
1214

13-
ScopeStateHolder(Scope state) : _scope = state;
15+
ScopeStateHolder(this._state);
1416

15-
Scope get scope => _scope;
17+
Scope? get scope {
18+
final state = this.state;
19+
if (state is ScopeStateAvailable<Scope>) {
20+
return state.scope;
21+
}
22+
return null;
23+
}
1624

17-
void _setScope(Scope state) {
18-
_scope = state;
25+
ScopeState<Scope> get state => _state;
26+
27+
void _updateState(ScopeState<Scope> state) {
28+
_state = state;
1929

2030
final errors = <Object>[];
2131
final stackTraces = <StackTrace>[];
@@ -50,6 +60,42 @@ class ScopeStateHolder<Scope> {
5060
RemoveStateListener listen(
5161
StateListener<Scope> listener, {
5262
bool emitImmediately = false,
63+
}) =>
64+
_listen(
65+
(state) {
66+
if (state is ScopeStateAvailable<Scope>) {
67+
listener(state.scope);
68+
} else if (state is ScopeStateNone) {
69+
listener(null);
70+
}
71+
},
72+
emitImmediately: emitImmediately,
73+
);
74+
75+
/// Subscribes to the state.
76+
///
77+
/// The [listener] callback will be called immediately on addition and
78+
/// synchronously whenever [state] changes.
79+
///
80+
/// Set [emitImmediately] to true if you want to an immediate execution
81+
/// of the [listener] with the current state.
82+
///
83+
/// To remove this [listener], call the function returned by [listen].
84+
///
85+
/// Listeners cannot add other listeners.
86+
/// Adding and removing listeners has a constant time-complexity.
87+
RemoveStateListener listenState(
88+
ScopeStateListener<Scope> listener, {
89+
bool emitImmediately = false,
90+
}) =>
91+
_listen(
92+
(state) => listener(state),
93+
emitImmediately: emitImmediately,
94+
);
95+
96+
RemoveStateListener _listen(
97+
void Function(ScopeState<Scope> state) listener, {
98+
bool emitImmediately = false,
5399
}) {
54100
assert(() {
55101
if (!_debugCanAddListeners) {
@@ -64,7 +110,7 @@ class ScopeStateHolder<Scope> {
64110
// Intentionally unsafe call of the listener before adding to the [_listeners]
65111
// so that if there is an exception — we throw it back to consumer
66112
// with an original stacktrace without adding to the [_listeners].
67-
listener(scope);
113+
listener(state);
68114
} on Object catch (_) {
69115
rethrow;
70116
} finally {
@@ -93,7 +139,7 @@ class ScopeStateHolder<Scope> {
93139
class Entry<T> extends LinkedListEntry<Entry<T>> {
94140
Entry(this.listener);
95141

96-
final StateListener<T> listener;
142+
final ScopeStateListener<T> listener;
97143
}
98144

99145
/// An error thrown when tried to update the state of a [ScopeStateHolder],

0 commit comments

Comments
 (0)