Skip to content

Instantly share code, notes, and snippets.

@maxs-rose
Created May 31, 2020 15:57
Show Gist options
  • Save maxs-rose/37afb3fcf8d567fa42b26b3de44f1231 to your computer and use it in GitHub Desktop.
Save maxs-rose/37afb3fcf8d567fa42b26b3de44f1231 to your computer and use it in GitHub Desktop.
Lightweight C# style events in Kotlin
fun <T> event() = SetEvent<T>()
fun <T> namedEvent() = MapEvent<T>()
object EventBus {
//to use
val exampleSetEvent = event<int>()
}
open class SetEvent<T> private constructor(private val backing: MutableSet<(T) -> Unit>) : AbstractEvent<T>(), MutableCollection<(T) -> Unit> by backing {
constructor() : this(HashSet())
}
class MapEvent<T>(private val backing: MutableMap<String, (T) -> Unit>)
: AbstractEvent<T>(), MutableMap<String, (T) -> Unit> by backing {
constructor() : this(HashMap())
private val nextUnnamedIndex = AtomicInteger()
override val size get() = backing.size
override fun contains(element: (T) -> Unit) = backing.containsValue(element)
override fun containsAll(elements: Collection<(T) -> Unit>) = backing.values.containsAll(elements)
override fun isEmpty() = backing.isEmpty()
override fun iterator() = backing.values.iterator()
override fun remove(element: (T) -> Unit) = backing.values.remove(element)
override fun removeAll(elements: Collection<(T) -> Unit>) = backing.values.removeAll(elements)
override fun retainAll(elements: Collection<(T) -> Unit>) = backing.values.retainAll(elements)
override fun add(element: (T) -> Unit): Boolean {
backing[nextUnnamedIndex.getAndIncrement().toString()] = element
return true
}
override fun addAll(elements: Collection<(T) -> Unit>): Boolean {
elements.forEach { add(it) }
return true
}
@JvmSynthetic
operator fun set(name: String, handler: ((T) -> Unit)?) {
if (handler == null) backing.remove(name)
else backing[name] = handler
}
override fun clear() = backing.clear()
}
abstract class AbstractEvent<T> : Event<T> {
@JvmSynthetic
override operator fun plusAssign(handler: (T) -> Unit) {
add(handler)
}
@JvmSynthetic
override operator fun minusAssign(handler: (T) -> Unit) {
remove(handler)
}
override fun invoke(data: T) = forEach { it(data) }
}
interface Event<T> : MutableCollection<(T) -> Unit> {
@JvmSynthetic
operator fun plusAssign(handler: (T) -> Unit)
@JvmSynthetic
operator fun minusAssign(handler: (T) -> Unit)
operator fun invoke(data: T)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment