diff --git a/CHANGELOG.md b/CHANGELOG.md index 5990de4f722..dd6045f7252 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ * `Versions`: * `Kotlin`: `1.4.30` -> `1.4.31` * `Ktor`: `1.5.1` -> `1.5.2` +* `Coroutines` + * Add `createActionsActor`/`createSafeActionsActor` and `doWithSuspending` ## 0.4.27 diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/ActionsActor.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/ActionsActor.kt new file mode 100644 index 00000000000..9a22f9f1cfe --- /dev/null +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/ActionsActor.kt @@ -0,0 +1,46 @@ +package dev.inmo.micro_utils.coroutines + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.Channel +import kotlin.coroutines.* + +interface ActorAction { + suspend operator fun invoke(): T +} + +/** + * Planned to use with [doWithSuspending]. Will execute incoming lambdas sequentially + * + * @see actor + */ +fun CoroutineScope.createActionsActor() = actor Unit> { + it() +} + +/** + * Planned to use with [doWithSuspending]. Will execute incoming lambdas sequentially + * + * @see safeActor + */ +inline fun CoroutineScope.createSafeActionsActor( + noinline onException: ExceptionHandler = defaultSafelyExceptionHandler +) = safeActor Unit>(Channel.UNLIMITED, onException) { + it() +} + +/** + * Must be use with actor created by [createActionsActor] or [createSafeActionsActor]. Will send lambda which will + * execute [action] and return result. + * + * @see suspendCoroutine + * @see safely + */ +suspend fun Channel Unit>.doWithSuspending( + action: ActorAction +) = suspendCoroutine { + offer { + safely({ e -> it.resumeWithException(e) }) { + it.resume(action()) + } + } +}