parent
57a4cfba80
commit
7502939561
@ -0,0 +1,149 @@ |
|||||||
|
package com.otaliastudios.cameraview.tools; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
|
||||||
|
import com.google.android.gms.tasks.OnSuccessListener; |
||||||
|
import com.google.android.gms.tasks.Task; |
||||||
|
import com.otaliastudios.cameraview.controls.Control; |
||||||
|
|
||||||
|
import org.mockito.Mockito; |
||||||
|
import org.mockito.invocation.InvocationOnMock; |
||||||
|
import org.mockito.stubbing.Answer; |
||||||
|
import org.mockito.stubbing.Stubber; |
||||||
|
|
||||||
|
import java.util.concurrent.CountDownLatch; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
|
||||||
|
/** |
||||||
|
* A naive implementation of {@link java.util.concurrent.CountDownLatch} |
||||||
|
* to help in testing. |
||||||
|
*/ |
||||||
|
public class Op<T> { |
||||||
|
|
||||||
|
public class Controller { |
||||||
|
private int mToBeIgnored; |
||||||
|
|
||||||
|
private Controller() { } |
||||||
|
|
||||||
|
/** Op owner method: notifies the action started. */ |
||||||
|
public void start() { |
||||||
|
if (!isListening()) mToBeIgnored++; |
||||||
|
} |
||||||
|
|
||||||
|
/** Op owner method: notifies the action ended. */ |
||||||
|
public void end(T result) { |
||||||
|
if (mToBeIgnored > 0) { |
||||||
|
mToBeIgnored--; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (isListening()) { // Should be always true.
|
||||||
|
mResult = result; |
||||||
|
mLatch.countDown(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void from(@NonNull Task<T> task) { |
||||||
|
start(); |
||||||
|
task.addOnSuccessListener(new OnSuccessListener<T>() { |
||||||
|
@Override |
||||||
|
public void onSuccess(T result) { |
||||||
|
end(result); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
public Stubber from(final int invocationArgument) { |
||||||
|
return Mockito.doAnswer(new Answer() { |
||||||
|
@Override |
||||||
|
public Object answer(InvocationOnMock invocation) { |
||||||
|
//noinspection unchecked
|
||||||
|
T o = (T) invocation.getArguments()[invocationArgument]; |
||||||
|
start(); |
||||||
|
end(o); |
||||||
|
return null; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private CountDownLatch mLatch; |
||||||
|
private Controller mController = new Controller(); |
||||||
|
private T mResult; |
||||||
|
|
||||||
|
/** |
||||||
|
* Listeners should: |
||||||
|
* - call {@link #listen()} to notify they are interested in the next action |
||||||
|
* - call {@link #await()} to know when the action is performed. |
||||||
|
* |
||||||
|
* Op owners should: |
||||||
|
* - call {@link Controller#start()} when task started |
||||||
|
* - call {@link Controller#end(Object)} when task ends |
||||||
|
*/ |
||||||
|
public Op() { |
||||||
|
this(true); |
||||||
|
} |
||||||
|
|
||||||
|
public Op(boolean startListening) { |
||||||
|
if (startListening) listen(); |
||||||
|
} |
||||||
|
|
||||||
|
public Op(@NonNull Task<T> task) { |
||||||
|
listen(); |
||||||
|
controller().from(task); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isListening() { |
||||||
|
return mLatch != null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Listener method: notifies we are interested in the next action. |
||||||
|
*/ |
||||||
|
public void listen() { |
||||||
|
if (isListening()) throw new RuntimeException("Should not happen."); |
||||||
|
mResult = null; |
||||||
|
mLatch = new CountDownLatch(1); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Listener method: waits for next task action to end. |
||||||
|
* @param millis milliseconds |
||||||
|
* @return the action result |
||||||
|
*/ |
||||||
|
public T await(long millis) { |
||||||
|
return await(millis, TimeUnit.MILLISECONDS); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Listener method: waits 1 minute for next task action to end. |
||||||
|
* @return the action result |
||||||
|
*/ |
||||||
|
public T await() { |
||||||
|
return await(1, TimeUnit.MINUTES); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Listener method: waits for next task action to end. |
||||||
|
* @param time time |
||||||
|
* @param unit the time unit |
||||||
|
* @return the action result |
||||||
|
*/ |
||||||
|
private T await(long time, @NonNull TimeUnit unit) { |
||||||
|
try { |
||||||
|
mLatch.await(time, unit); |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
T result = mResult; |
||||||
|
mResult = null; |
||||||
|
mLatch = null; |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
public Controller controller() { |
||||||
|
return mController; |
||||||
|
} |
||||||
|
} |
@ -1,4 +1,4 @@ |
|||||||
package com.otaliastudios.cameraview.runner; |
package com.otaliastudios.cameraview.tools; |
||||||
|
|
||||||
import java.lang.annotation.ElementType; |
import java.lang.annotation.ElementType; |
||||||
import java.lang.annotation.Retention; |
import java.lang.annotation.Retention; |
@ -1,4 +1,4 @@ |
|||||||
package com.otaliastudios.cameraview.runner; |
package com.otaliastudios.cameraview.tools; |
||||||
|
|
||||||
|
|
||||||
import android.os.Build; |
import android.os.Build; |
@ -1,111 +0,0 @@ |
|||||||
package com.otaliastudios.cameraview.internal.utils; |
|
||||||
|
|
||||||
import androidx.annotation.NonNull; |
|
||||||
|
|
||||||
import java.util.concurrent.CountDownLatch; |
|
||||||
import java.util.concurrent.TimeUnit; |
|
||||||
|
|
||||||
/** |
|
||||||
* A naive implementation of {@link java.util.concurrent.CountDownLatch} |
|
||||||
* to help in testing. |
|
||||||
*/ |
|
||||||
public class Op<T> { |
|
||||||
|
|
||||||
private CountDownLatch mLatch; |
|
||||||
private T mResult; |
|
||||||
private int mCount; |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates an empty task. |
|
||||||
* |
|
||||||
* Listeners should: |
|
||||||
* - call {@link #listen()} to notify they are interested in the next action |
|
||||||
* - call {@link #await()} to know when the action is performed. |
|
||||||
* |
|
||||||
* Op owners should: |
|
||||||
* - call {@link #start()} when task started |
|
||||||
* - call {@link #end(Object)} when task ends |
|
||||||
*/ |
|
||||||
public Op() { } |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates an empty task and starts listening. |
|
||||||
* @param startListening whether to call listen |
|
||||||
*/ |
|
||||||
public Op(boolean startListening) { |
|
||||||
if (startListening) listen(); |
|
||||||
} |
|
||||||
|
|
||||||
private boolean isListening() { |
|
||||||
return mLatch != null; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Op owner method: notifies the action started. |
|
||||||
*/ |
|
||||||
public void start() { |
|
||||||
if (!isListening()) mCount++; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Op owner method: notifies the action ended. |
|
||||||
* @param result the action result |
|
||||||
*/ |
|
||||||
public void end(T result) { |
|
||||||
if (mCount > 0) { |
|
||||||
mCount--; |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (isListening()) { // Should be always true.
|
|
||||||
mResult = result; |
|
||||||
mLatch.countDown(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Listener method: notifies we are interested in the next action. |
|
||||||
*/ |
|
||||||
public void listen() { |
|
||||||
if (isListening()) throw new RuntimeException("Should not happen."); |
|
||||||
mResult = null; |
|
||||||
mLatch = new CountDownLatch(1); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Listener method: waits for next task action to end. |
|
||||||
* @param millis milliseconds |
|
||||||
* @return the action result |
|
||||||
*/ |
|
||||||
public T await(long millis) { |
|
||||||
return await(millis, TimeUnit.MILLISECONDS); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Listener method: waits 1 minute for next task action to end. |
|
||||||
* @return the action result |
|
||||||
*/ |
|
||||||
public T await() { |
|
||||||
return await(1, TimeUnit.MINUTES); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Listener method: waits for next task action to end. |
|
||||||
* @param time time |
|
||||||
* @param unit the time unit |
|
||||||
* @return the action result |
|
||||||
*/ |
|
||||||
private T await(long time, @NonNull TimeUnit unit) { |
|
||||||
try { |
|
||||||
mLatch.await(time, unit); |
|
||||||
} catch (Exception e) { |
|
||||||
e.printStackTrace(); |
|
||||||
} |
|
||||||
T result = mResult; |
|
||||||
mResult = null; |
|
||||||
mLatch = null; |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
Loading…
Reference in new issue