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.Retention; |
@ -1,4 +1,4 @@ |
||||
package com.otaliastudios.cameraview.runner; |
||||
package com.otaliastudios.cameraview.tools; |
||||
|
||||
|
||||
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