Skip to content

Commit adc5b9c

Browse files
committed
feat: timer
1 parent 5ce94e9 commit adc5b9c

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

common/src/main/kotlin/com/lambda/event/EventFlow.kt

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,32 @@ object EventFlow {
9494
}
9595
}
9696

97+
/**
98+
* Registers a timer that invokes the specified block at regular intervals
99+
*
100+
* This function runs a timer that emits a signal at the specified interval, and invokes the
101+
* provided block each time the signal is emitted. The interval is specified in milliseconds,
102+
* and the block is a suspend function that is called each time the timer triggers
103+
*
104+
* **Note**: This function uses a flow to emit signals at the specified interval, and uses `conflate()`
105+
* to prevent overloading the block execution in case the block takes longer than the interval
106+
*
107+
* @param interval The time interval (in milliseconds) between each invocation of the block
108+
* @param block The suspend function that will be called each time the timer triggers
109+
*
110+
* @return A [Job] representing the running timer. The timer can be canceled by invoking `cancel()` on the returned job
111+
*/
112+
inline fun timer(interval: Long, crossinline block: suspend () -> Unit) =
113+
runConcurrent {
114+
// This allows for 18,446,744,073,709,551,615 events
115+
// Don't worry, a 10 ms timer will end after 5.849 billion years
116+
(Long.MAX_VALUE downTo Long.MIN_VALUE)
117+
.asFlow()
118+
.onEach { delay(interval) }
119+
.conflate()
120+
.collect { block() }
121+
}
122+
97123
/**
98124
* Suspends until an event of type [E] is received that satisfies the given [predicate].
99125
*
@@ -123,7 +149,7 @@ object EventFlow {
123149
noinline predicate: (E) -> Boolean = { true },
124150
) = runBlocking {
125151
withTimeout(timeout) {
126-
concurrentFlow.filterIsInstance<E>().first(predicate)
152+
this@EventFlow.concurrentFlow.filterIsInstance<E>().first(predicate)
127153
}
128154
}
129155

@@ -150,7 +176,7 @@ object EventFlow {
150176
suspend inline fun <reified E : Event> collectEvents(
151177
crossinline predicate: (E) -> Boolean = { true },
152178
): Flow<E> = flow {
153-
concurrentFlow
179+
this@EventFlow.concurrentFlow
154180
.filterIsInstance<E>()
155181
.filter { predicate(it) }
156182
.collect {
@@ -175,7 +201,7 @@ object EventFlow {
175201
*/
176202
@JvmStatic
177203
fun <E : Event> E.post(): E {
178-
concurrentFlow.tryEmit(this)
204+
this@EventFlow.concurrentFlow.tryEmit(this)
179205
executeListenerSynchronous()
180206
return this@post
181207
}

0 commit comments

Comments
 (0)