/* This file is part of Reactive Cascade which is released under The MIT License. See license.md , https://github.com/futurice/cascade and http://reactivecascade.com for details. This is open source for the common good. Please contribute improvements by pull request or contact paulirotta@gmail.com */ package com.reactivecascade.functional; import android.support.annotation.NonNull; import com.reactivecascade.Async; import com.reactivecascade.i.IActionOne; import com.reactivecascade.i.IThreadType; import com.reactivecascade.i.NotCallOrigin; import com.reactivecascade.util.RCLog; /** * The on-cancelled action in a chain will be launched asynchonosly * <p> * Cancelled notifications are not consumed. All downchain items will also receive the * {@link #onCancelled(StateCancelled)} notification call synchronously. * <p> * Cancellation may occur from any thread. In the event of concurrent cancellation, {@link #onCancelled(StateCancelled)} * will be called exactly one time. */ public class OnCancelledAltFuture<T> extends SettableAltFuture<T> { @NonNull private final IActionOne<String> mOnCancelledAction; /** * Constructor * * @param threadType the thread pool to run this command on * @param action a function that receives one input and no return from */ @SuppressWarnings("unchecked") public OnCancelledAltFuture(@NonNull IThreadType threadType, @NonNull IActionOne<String> action) { super(threadType); this.mOnCancelledAction = action; } @NotCallOrigin @Override // IAltFuture public void onCancelled(@NonNull StateCancelled stateCancelled) throws Exception { RCLog.d(this, "Handling onCancelled(): " + stateCancelled); if (!this.stateAR.compareAndSet(VALUE_NOT_AVAILABLE, stateCancelled) || (Async.USE_FORKED_STATE && !this.stateAR.compareAndSet(FORKED, stateCancelled))) { RCLog.i(this, "Will not onCancelled() because IAltFuture state is already determined: " + stateAR.get()); return; } threadType .from(stateCancelled.getReason()) .then(mOnCancelledAction) .fork(); Exception e = forEachThen(af -> { af.onCancelled(stateCancelled); }); if (e != null) { throw e; } } }