-
Notifications
You must be signed in to change notification settings - Fork 367
/
EventProducer.kt
95 lines (85 loc) · 3.1 KB
/
EventProducer.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.onesignal.common.events
import com.onesignal.common.threading.suspendifyOnMain
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.Collections
/**
* A standard implementation that implements [IEventNotifier] and additional functionality to make
* event firing less burdensome to the user.
*/
open class EventProducer<THandler> : IEventNotifier<THandler> {
override val hasSubscribers: Boolean
get() = subscribers.any()
private val subscribers: MutableList<THandler> = Collections.synchronizedList(mutableListOf())
override fun subscribe(handler: THandler) {
synchronized(subscribers) {
subscribers.add(handler)
}
}
override fun unsubscribe(handler: THandler) {
synchronized(subscribers) {
subscribers.remove(handler)
}
}
/**
* Subscribe all from an existing producer to this subscriber.
*/
fun subscribeAll(from: EventProducer<THandler>) {
synchronized(subscribers) {
for (s in from.subscribers) {
subscribe(s)
}
}
}
/**
* Call this to fire the callback which will allow the caller to drive the calling of the
* callback handlers if there are any.
*
* @param callback The callback will be invoked for each subscribed handler, allowing you to call the handler.
*/
open fun fire(callback: (THandler) -> Unit) {
synchronized(subscribers) {
for (s in subscribers) {
callback(s)
}
}
}
/**
* Call this to fire the callback which will allow the caller to drive the calling of the
* callback handlers if there are any. The callback will be invoked asynchronously on the main
* thread. Control will be returned immediately, most likely prior to the callbacks being invoked.
*
* @param callback The callback will be invoked for each subscribed handler, allowing you to call the handler.
*/
fun fireOnMain(callback: (THandler) -> Unit) {
suspendifyOnMain {
for (s in subscribers) {
callback(s)
}
}
}
/**
* Call this to fire the callback which will allow the caller to drive the calling of the
* callback handlers if there are any.
*
* @param callback The callback will be invoked for each subscribed handler, allowing you to call the handler.
*/
suspend fun suspendingFire(callback: suspend (THandler) -> Unit) {
for (s in subscribers) {
callback(s)
}
}
/**
* Call this to fire the callback which will allow the caller to drive the calling of the
* callback handlers if there are any. The callback will be invoked on the main thread.
*
* @param callback The callback will be invoked for each subscribed handler, allowing you to call the handler.
*/
suspend fun suspendingFireOnMain(callback: suspend (THandler) -> Unit) {
withContext(Dispatchers.Main) {
for (s in subscribers) {
callback(s)
}
}
}
}