package org.threadly.concurrent;
import java.util.Collections;
import java.util.Iterator;
import org.threadly.util.ExceptionUtils;
/**
* A class to chain multiple runnables to later be run together, within the same thread.
*
* @since 1.0.0
*/
public class RunnableChain implements Runnable {
protected final boolean exceptionStopsChain;
private final Iterable<? extends Runnable> toRun;
/**
* Constructs a runnable chain with a provided list of runnables to iterate over.
*
* @param exceptionStopsChain {@code true} for uncaught exception stops the execution of the chain
* @param toRun Iterable collection of runnables to run
*/
public RunnableChain(boolean exceptionStopsChain,
Iterable<? extends Runnable> toRun) {
if (toRun == null) {
toRun = Collections.emptyList();
}
this.exceptionStopsChain = exceptionStopsChain;
this.toRun = toRun;
}
@Override
public void run() {
if (exceptionStopsChain) {
runExceptionsCascade();
} else {
runIsolated();
}
}
/**
* Iterates through the toRun list, executing along the way. If any exceptions are thrown, they
* will be propagated out of this call.
*/
protected void runExceptionsCascade() {
Iterator<? extends Runnable> it = toRun.iterator();
while (it.hasNext()) {
it.next().run();
}
}
/**
* Iterates through the toRun list, executing along the way. If any exceptions are thrown, they
* will be handled to {@link ExceptionUtils} and will not stop future executions.
*/
protected void runIsolated() {
Iterator<? extends Runnable> it = toRun.iterator();
while (it.hasNext()) {
ExceptionUtils.runRunnable(it.next());
}
}
}