|
|
|
@ -6,7 +6,7 @@ import kotlin.coroutines.CoroutineContext |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Coroutine<T>( |
|
|
|
|
scope: CoroutineScope, |
|
|
|
|
val scope: CoroutineScope, |
|
|
|
|
context: CoroutineContext = Dispatchers.IO, |
|
|
|
|
block: suspend CoroutineScope.() -> T |
|
|
|
|
) { |
|
|
|
@ -31,6 +31,7 @@ class Coroutine<T>( |
|
|
|
|
private var success: Callback<T?>? = null |
|
|
|
|
private var error: Callback<Throwable>? = null |
|
|
|
|
private var finally: VoidCallback? = null |
|
|
|
|
private var cancel: VoidCallback? = null |
|
|
|
|
|
|
|
|
|
private var timeMillis: Long? = null |
|
|
|
|
private var errorReturn: Result<T>? = null |
|
|
|
@ -45,7 +46,7 @@ class Coroutine<T>( |
|
|
|
|
get() = job.isCompleted |
|
|
|
|
|
|
|
|
|
init { |
|
|
|
|
this.job = executeInternal(scope, context, block) |
|
|
|
|
this.job = executeInternal(context, block) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun timeout(timeMillis: () -> Long): Coroutine<T> { |
|
|
|
@ -100,9 +101,28 @@ class Coroutine<T>( |
|
|
|
|
return this@Coroutine |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun onCancel( |
|
|
|
|
context: CoroutineContext? = null, |
|
|
|
|
block: suspend CoroutineScope.() -> Unit |
|
|
|
|
): Coroutine<T> { |
|
|
|
|
this.cancel = VoidCallback(context, block) |
|
|
|
|
return this@Coroutine |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//取消当前任务 |
|
|
|
|
fun cancel(cause: CancellationException? = null) { |
|
|
|
|
job.cancel(cause) |
|
|
|
|
cancel?.let { |
|
|
|
|
scope.plus(Dispatchers.Main).launch { |
|
|
|
|
if (null == it.context) { |
|
|
|
|
it.block.invoke(scope) |
|
|
|
|
} else { |
|
|
|
|
withContext(scope.coroutineContext.plus(it.context)) { |
|
|
|
|
it.block.invoke(this) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun invokeOnCompletion(handler: CompletionHandler): DisposableHandle { |
|
|
|
@ -110,7 +130,6 @@ class Coroutine<T>( |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fun executeInternal( |
|
|
|
|
scope: CoroutineScope, |
|
|
|
|
context: CoroutineContext, |
|
|
|
|
block: suspend CoroutineScope.() -> T |
|
|
|
|
): Job { |
|
|
|
@ -118,21 +137,27 @@ class Coroutine<T>( |
|
|
|
|
try { |
|
|
|
|
start?.let { dispatchVoidCallback(this, it) } |
|
|
|
|
val value = executeBlock(scope, context, timeMillis ?: 0L, block) |
|
|
|
|
success?.let { dispatchCallback(this, value, it) } |
|
|
|
|
if (isActive) { |
|
|
|
|
success?.let { dispatchCallback(this, value, it) } |
|
|
|
|
} |
|
|
|
|
} catch (e: Throwable) { |
|
|
|
|
if (BuildConfig.DEBUG) { |
|
|
|
|
e.printStackTrace() |
|
|
|
|
} |
|
|
|
|
val consume: Boolean = errorReturn?.value?.let { value -> |
|
|
|
|
success?.let { dispatchCallback(this, value, it) } |
|
|
|
|
if (isActive) { |
|
|
|
|
success?.let { dispatchCallback(this, value, it) } |
|
|
|
|
} |
|
|
|
|
true |
|
|
|
|
} ?: false |
|
|
|
|
|
|
|
|
|
if (!consume) { |
|
|
|
|
if (!consume && isActive) { |
|
|
|
|
error?.let { dispatchCallback(this, e, it) } |
|
|
|
|
} |
|
|
|
|
} finally { |
|
|
|
|
finally?.let { dispatchVoidCallback(this, it) } |
|
|
|
|
if (isActive) { |
|
|
|
|
finally?.let { dispatchVoidCallback(this, it) } |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|