• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.base.supplier;
6 
7 import androidx.annotation.NonNull;
8 
9 import org.chromium.base.Callback;
10 
11 import java.lang.ref.WeakReference;
12 
13 /**
14  * Helper class to handle safely querying a single instance of an object from an
15  * {@link ObservableSupplier}.
16  *
17  * Assuming the underlying {@link Supplier} gets set with a
18  * value, this class will guarantee only a single call makes it back to the passed in
19  * {@link Callback}.
20  *
21  * For {@link ObservableSupplier}s that already have a valid value set, this will have the same
22  * underlying behavior as {@link ObservableSupplierImpl}, which asynchronously triggers the callback
23  * when {@link ObservableSupplier#addObserver(Callback)} is called.
24  *
25  * This class does not hold a strong reference to the {@link ObservableSupplier}, but does hold a
26  * strong reference to the {@link Callback}.
27  *
28  * @param <E> The type of the wrapped object.
29  */
30 public class OneShotCallback<E> {
31     private final Callback<E> mCallbackWrapper = new CallbackWrapper();
32     private final WeakReference<ObservableSupplier<E>> mWeakSupplier;
33     private final Callback<E> mCallback;
34 
35     /**
36      * Creates a {@link OneShotCallback} instance, automatically registering as an observer to
37      * {@code supplier} and waiting to trigger {@code callback}.
38      * @param supplier The {@link ObservableSupplier} to wait for.
39      * @param callback The {@link Callback} to notify with a valid value.
40      */
OneShotCallback(@onNull ObservableSupplier<E> supplier, @NonNull Callback<E> callback)41     public OneShotCallback(@NonNull ObservableSupplier<E> supplier, @NonNull Callback<E> callback) {
42         mWeakSupplier = new WeakReference<>(supplier);
43         mCallback = callback;
44 
45         supplier.addObserver(mCallbackWrapper);
46     }
47 
48     private class CallbackWrapper implements Callback<E> {
49         @Override
onResult(E result)50         public void onResult(E result) {
51             mCallback.onResult(result);
52             ObservableSupplier<E> supplier = mWeakSupplier.get();
53             assert supplier != null
54                     : "This can only be called by supplier, which should not be null.";
55             supplier.removeObserver(mCallbackWrapper);
56         }
57     }
58 }
59