-
Notifications
You must be signed in to change notification settings - Fork 226
Expand file tree
/
Copy pathLifecycleScopes.java
More file actions
147 lines (138 loc) · 6.15 KB
/
Copy pathLifecycleScopes.java
File metadata and controls
147 lines (138 loc) · 6.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
* Copyright (C) 2019. Uber Technologies
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package autodispose2.lifecycle;
import autodispose2.AutoDisposePlugins;
import autodispose2.OutsideScopeException;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.annotations.Nullable;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.core.CompletableSource;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Predicate;
import io.reactivex.rxjava3.functions.Supplier;
import java.util.Comparator;
/**
* Utilities for dealing with {@link LifecycleScopeProvider}s. This includes factories for resolving
* {@link Completable} representations of scopes, corresponding events, etc.
*/
public final class LifecycleScopes {
private static final Comparator<Comparable<Object>> COMPARABLE_COMPARATOR = Comparable::compareTo;
private LifecycleScopes() {
throw new InstantiationError();
}
/**
* Overload for resolving lifecycle providers that defaults to checking start and end boundaries
* of lifecycles. That is, they will ensure that the lifecycle has both started and not ended.
*
* <p><em>Note:</em> This resolves the scope immediately, so consider deferring execution as
* needed, such as using {@link Completable#defer(Supplier) defer}.
*
* @param provider the {@link LifecycleScopeProvider} to resolve.
* @param <E> the lifecycle event type
* @return a resolved {@link CompletableSource} representation of a given provider
* @throws OutsideScopeException if the {@link LifecycleScopeProvider#correspondingEvents()}
* throws an {@link OutsideScopeException} during resolution.
*/
public static <E extends @NonNull Object> CompletableSource resolveScopeFromLifecycle(
final LifecycleScopeProvider<E> provider) throws OutsideScopeException {
return resolveScopeFromLifecycle(provider, true);
}
/**
* Overload for resolving lifecycle providers allows configuration of checking "end" boundaries of
* lifecycles. That is, they will ensure that the lifecycle has both started and not ended, and
* otherwise will throw one of {@link LifecycleNotStartedException} (if {@link
* LifecycleScopeProvider#peekLifecycle() peekLifecycle} returns {@code null}) or {@link
* LifecycleEndedException} if the lifecycle is ended. To configure the runtime behavior of these
* exceptions, see {@link AutoDisposePlugins}.
*
* <p><em>Note:</em> This resolves the scope immediately, so consider deferring execution as
* needed, such as using {@link Completable#defer(Supplier) defer}.
*
* @param provider the {@link LifecycleScopeProvider} to resolve.
* @param checkEndBoundary whether or not to check that the lifecycle has ended
* @param <E> the lifecycle event type
* @return a resolved {@link CompletableSource} representation of a given provider
* @throws OutsideScopeException if the {@link LifecycleScopeProvider#correspondingEvents()}
* throws an {@link OutsideScopeException} during resolution.
*/
public static <E extends @NonNull Object> CompletableSource resolveScopeFromLifecycle(
final LifecycleScopeProvider<E> provider, final boolean checkEndBoundary)
throws OutsideScopeException {
E lastEvent = provider.peekLifecycle();
CorrespondingEventsFunction<E> eventsFunction = provider.correspondingEvents();
if (lastEvent == null) {
throw new LifecycleNotStartedException();
}
E endEvent;
try {
endEvent = eventsFunction.apply(lastEvent);
} catch (Exception e) {
if (checkEndBoundary && e instanceof LifecycleEndedException) {
Consumer<? super OutsideScopeException> handler =
AutoDisposePlugins.getOutsideScopeHandler();
if (handler != null) {
try {
handler.accept((LifecycleEndedException) e);
// Swallowed the end exception, just silently dispose immediately.
return Completable.complete();
} catch (Throwable e1) {
return Completable.error(e1);
}
}
throw e;
}
return Completable.error(e);
}
return resolveScopeFromLifecycle(provider.lifecycle(), endEvent);
}
/**
* Returns a resolved {@link Completable} representation of a given lifecycle, targeting the given
* event
*
* @param lifecycle the stream of lifecycle events
* @param endEvent the target end event
* @param <E> the lifecycle event type
*/
public static <E extends @NonNull Object> CompletableSource resolveScopeFromLifecycle(
Observable<E> lifecycle, final E endEvent) {
@Nullable Comparator<E> comparator = null;
if (endEvent instanceof Comparable) {
//noinspection unchecked
comparator = (Comparator<E>) COMPARABLE_COMPARATOR;
}
return resolveScopeFromLifecycle(lifecycle, endEvent, comparator);
}
/**
* Returns a resolved {@link Completable} representation of a given lifecycle, targeting the given
* event
*
* @param lifecycle the stream of lifecycle events
* @param endEvent the target end event
* @param comparator an optional comparator for checking event equality.
* @param <E> the lifecycle event type
*/
public static <E extends @NonNull Object> CompletableSource resolveScopeFromLifecycle(
Observable<E> lifecycle, final E endEvent, @Nullable final Comparator<E> comparator) {
Predicate<E> equalityPredicate;
if (comparator != null) {
equalityPredicate = e -> comparator.compare(e, endEvent) >= 0;
} else {
equalityPredicate = e -> e.equals(endEvent);
}
return lifecycle.skip(1).takeUntil(equalityPredicate).ignoreElements();
}
}