Skip to content

Instantly share code, notes, and snippets.

@wyon
Created September 11, 2017 12:09
Show Gist options
  • Save wyon/6f927d6f24013c9404aa6d56c62ccde7 to your computer and use it in GitHub Desktop.
Save wyon/6f927d6f24013c9404aa6d56c62ccde7 to your computer and use it in GitHub Desktop.
MultiXLCall
public class MultiXLCall<R> {
@SuppressWarnings("unchecked")
public static <T1, T2, R> MultiXLCall<R> wrap(@NonNull XLCall<T1> call1, @NonNull XLCall<T2> call2, @NonNull Zip2<T1, T2, R> zip) {
return new MultiXLCall<>(fromZip2(zip), new XLCall[]{call1, call2});
}
@SuppressWarnings("unchecked")
public static <T1, T2, T3, R> MultiXLCall<R> wrap(@NonNull XLCall<T1> call1, @NonNull XLCall<T2> call2, @NonNull XLCall<T3> call3, @NonNull Zip3<T1, T2, T3, R> zip) {
return new MultiXLCall<>(fromZip3(zip), new XLCall[]{call1, call2, call3});
}
private final MultiXLCallImp<R> mActual;
private MultiXLCall(Zip<R> zip, XLCall<Object>[] xlCalls) {
mActual = new MultiXLCallImp<>(zip, xlCalls);
}
public MultiXLCall<R> requestV2(ReqCallBackV2<R> callback) {
mActual.requestV2(callback);
return this;
}
public void cancel() {
mActual.cancel();
}
public boolean isCanceled() {
return mActual.isCanceled();
}
interface Zip<R> {
R zip(Object... objects);
}
public interface Zip2<T1, T2, R> {
R zip(T1 t1, T2 t2);
}
public interface Zip3<T1, T2, T3, R> {
R zip(T1 t1, T2 t2, T3 t3);
}
private static <T1, T2, R> Zip<R> fromZip2(final Zip2<? super T1, ? super T2, ? extends R> zip2) {
return new Zip<R>() {
@Override
public R zip(Object... objects) {
if (objects.length != 2) {
throw new RuntimeException("unexpected paramater lenght: " + objects.length);
}
//noinspection unchecked
return zip2.zip((T1) objects[0], (T2) objects[1]);
}
};
}
private static <T1, T2, T3, R> Zip<R> fromZip3(final Zip3<? super T1, ? super T2, ? super T3, ? extends R> zip3) {
return new Zip<R>() {
@Override
public R zip(Object... objects) {
if (objects.length != 3) {
throw new RuntimeException("unexpected paramater lenght: " + objects.length);
}
//noinspection unchecked
return zip3.zip((T1) objects[0], (T2) objects[1], (T3) objects[2]);
}
};
}
private static class MultiXLCallImp<R> implements XLCall<R> {
private final AtomicBoolean mRunning = new AtomicBoolean(false);
private final Zip<R> mZip;
private final XLCall<Object>[] mXLCalls;
private final Object[] mResultObj;
private MultiXLCallImp(Zip<R> zip, XLCall<Object>[] xlCalls) {
mZip = zip;
mXLCalls = xlCalls;
mResultObj = new Object[xlCalls.length];
}
@Override
public XLCall<R> request(ReqCallBack<R> callback) {
return null;
}
@Override
public XLCall<R> requestV2(final ReqCallBackV2<R> callback) {
if (mRunning.compareAndSet(false, true)) {
Arrays.fill(mResultObj, null);
final int size = mXLCalls.length;
final MutableInt count = new MutableInt(size);
for (int i = 0; i < size; i++) {
final int index = i;
mXLCalls[index].requestV2(new ReqCallBackV2<Object>() {
@Override
public void onReqSuccess(Object result) {
if (mRunning.get()) {
mResultObj[index] = result;
count.value--;
if (count.value <= 0 && mRunning.compareAndSet(true, false)) {
R r = mZip.zip(mResultObj);
callback.onReqSuccess(r);
}
}
}
@Override
public void onReqFailed(String errorMsg, String errorCode) {
if (cancelInternal()) {
callback.onReqFailed(errorMsg, errorCode);
}
}
});
}
}
return this;
}
@Override
public XLResponse<R> execute() {
return null;
}
@Override
public void enqueue(XLApiCallback<R> callback) {
}
@Override
public boolean isExecuted() {
return false;
}
@Override
public void cancel() {
cancelInternal();
}
private boolean cancelInternal() {
if (mRunning.compareAndSet(true, false)) {
for (XLCall call : mXLCalls) {
call.cancel();
}
return true;
}
return false;
}
@Override
public boolean isCanceled() {
return !mRunning.get();
}
@Override
public Request rawRequest() {
return null;
}
}
private static final class MutableInt {
int value;
MutableInt(int value) {
this.value = value;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment