2020-11-21 08:58:19 +00:00
|
|
|
package dev.inmo.krontab.utils
|
2020-01-13 04:15:01 +00:00
|
|
|
|
2023-05-25 14:53:10 +00:00
|
|
|
import korlibs.time.DateTime
|
|
|
|
import korlibs.time.DateTimeTz
|
|
|
|
import korlibs.time.milliseconds
|
2023-03-18 06:34:06 +00:00
|
|
|
import dev.inmo.krontab.KronScheduler
|
|
|
|
import dev.inmo.krontab.next
|
2023-03-18 06:23:53 +00:00
|
|
|
import kotlinx.coroutines.currentCoroutineContext
|
|
|
|
import kotlinx.coroutines.delay
|
2021-11-22 13:09:33 +00:00
|
|
|
import kotlinx.coroutines.flow.Flow
|
2023-03-18 06:23:53 +00:00
|
|
|
import kotlinx.coroutines.flow.flow
|
|
|
|
import kotlinx.coroutines.flow.onEach
|
2022-04-29 15:57:10 +00:00
|
|
|
import kotlinx.coroutines.isActive
|
2020-01-13 04:15:01 +00:00
|
|
|
|
2021-04-24 10:58:25 +00:00
|
|
|
/**
|
2023-03-18 06:23:53 +00:00
|
|
|
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
2021-04-24 10:58:25 +00:00
|
|
|
*
|
2023-03-18 06:23:53 +00:00
|
|
|
* Will emit all the [KronScheduler.next] as soon as possible. In case [KronScheduler.next] return null, flow will
|
|
|
|
* be completed
|
|
|
|
*
|
2023-06-20 05:35:57 +00:00
|
|
|
* @param since Will be used as the first parameter for [KronScheduler.next] fun. If passed null, `flow`
|
|
|
|
* will always start since the moment of collecting start
|
2021-04-24 10:58:25 +00:00
|
|
|
*/
|
2023-06-20 05:35:57 +00:00
|
|
|
fun KronScheduler.asTzFlowWithoutDelays(since: DateTimeTz? = null): Flow<DateTimeTz> = flow {
|
|
|
|
var previous = since ?: DateTime.nowLocal()
|
2023-03-18 06:23:53 +00:00
|
|
|
while (currentCoroutineContext().isActive) {
|
|
|
|
val next = next(previous) ?: break
|
|
|
|
emit(next)
|
|
|
|
previous = next + 1.milliseconds
|
2021-04-24 10:58:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-03-18 06:23:53 +00:00
|
|
|
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
|
|
|
*
|
|
|
|
* This [Flow] will use [asTzFlowWithoutDelays], but stop on each time until this time will happen
|
|
|
|
*/
|
|
|
|
fun KronScheduler.asTzFlowWithDelays(): Flow<DateTimeTz> = asTzFlowWithoutDelays().onEach { futureHappenTime ->
|
|
|
|
val now = DateTime.nowLocal()
|
|
|
|
|
|
|
|
delay((futureHappenTime - now).millisecondsLong)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
|
|
|
*
|
|
|
|
* This [Flow] will use [asTzFlowWithoutDelays], but stop on each time until this time will happen
|
|
|
|
*/
|
|
|
|
@Deprecated(
|
|
|
|
"Behaviour will be changed. In some of near versions this flow will not delay executions",
|
|
|
|
ReplaceWith("this.asTzFlowWithDelays()", "dev.inmo.krontab.utils.asTzFlowWithDelays")
|
|
|
|
)
|
|
|
|
fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = asTzFlowWithDelays()
|
|
|
|
|
|
|
|
/**
|
|
|
|
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
2021-09-25 13:28:49 +00:00
|
|
|
*
|
2023-03-18 06:23:53 +00:00
|
|
|
* Will emit all the [KronScheduler.next] as soon as possible. In case [KronScheduler.next] return null, flow will
|
|
|
|
* be completed
|
|
|
|
*
|
2023-06-20 05:35:57 +00:00
|
|
|
* @param since Will be used as the first parameter for [KronScheduler.next] fun. If passed null, `flow`
|
|
|
|
* will always start since the moment of collecting start
|
2021-09-25 13:28:49 +00:00
|
|
|
*/
|
2023-06-20 05:35:57 +00:00
|
|
|
fun KronScheduler.asFlowWithoutDelays(since: DateTime? = null): Flow<DateTime> = flow {
|
|
|
|
var previous = since ?: DateTime.now()
|
2023-03-18 06:23:53 +00:00
|
|
|
while (currentCoroutineContext().isActive) {
|
|
|
|
val next = next(previous) ?: break
|
|
|
|
emit(next)
|
|
|
|
previous = next + 1.milliseconds
|
2021-09-25 13:28:49 +00:00
|
|
|
}
|
|
|
|
}
|
2023-03-18 06:23:53 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
|
|
|
*
|
|
|
|
* This [Flow] will use [asFlowWithoutDelays], but stop on each time until this time will happen
|
|
|
|
*/
|
|
|
|
fun KronScheduler.asFlowWithDelays(): Flow<DateTime> = asFlowWithoutDelays().onEach { futureHappenTime ->
|
|
|
|
val now = DateTime.now()
|
|
|
|
|
|
|
|
delay((futureHappenTime - now).millisecondsLong)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
|
|
|
*
|
|
|
|
* This [Flow] will use [asFlowWithDelays], but stop on each time until this time will happen
|
|
|
|
*/
|
|
|
|
@Deprecated(
|
|
|
|
"Behaviour will be changed. In some of near versions this flow will not delay executions",
|
|
|
|
ReplaceWith("this.asFlowWithDelays()", "dev.inmo.krontab.utils.asFlowWithDelays")
|
|
|
|
)
|
|
|
|
fun KronScheduler.asFlow(): Flow<DateTime> = asFlowWithDelays()
|