Created
September 11, 2017 12:09
-
-
Save wyon/6f927d6f24013c9404aa6d56c62ccde7 to your computer and use it in GitHub Desktop.
MultiXLCall
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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