blob: eefb535a8376970ba26d3efcefc240832c96edf0 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base.supplier;
import androidx.annotation.NonNull;
import org.chromium.base.Callback;
import java.lang.ref.WeakReference;
/**
* Helper class to handle safely querying a single instance of an object from an
* {@link ObservableSupplier}.
*
* Assuming the underlying {@link Supplier} gets set with a
* value, this class will guarantee only a single call makes it back to the passed in
* {@link Callback}.
*
* For {@link ObservableSupplier}s that already have a valid value set, this will have the same
* underlying behavior as {@link ObservableSupplierImpl}, which asynchronously triggers the callback
* when {@link ObservableSupplier#addObserver(Callback)} is called.
*
* This class does not hold a strong reference to the {@link ObservableSupplier}, but does hold a
* strong reference to the {@link Callback}.
*
* @param <E> The type of the wrapped object.
*/
public class OneShotCallback<E> {
private final Callback<E> mCallbackWrapper = new CallbackWrapper();
private final WeakReference<ObservableSupplier<E>> mWeakSupplier;
private final Callback<E> mCallback;
/**
* Creates a {@link OneShotCallback} instance, automatically registering as an observer to
* {@code supplier} and waiting to trigger {@code callback}.
* @param supplier The {@link ObservableSupplier} to wait for.
* @param callback The {@link Callback} to notify with a valid value.
*/
public OneShotCallback(@NonNull ObservableSupplier<E> supplier, @NonNull Callback<E> callback) {
mWeakSupplier = new WeakReference<>(supplier);
mCallback = callback;
supplier.addObserver(mCallbackWrapper);
}
private class CallbackWrapper implements Callback<E> {
@Override
public void onResult(E result) {
mCallback.onResult(result);
ObservableSupplier<E> supplier = mWeakSupplier.get();
assert supplier
!= null : "This can only be called by supplier, which should not be null.";
supplier.removeObserver(mCallbackWrapper);
}
}
}