Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Throw this while handling a signal to disconnect it
- class DisconnectException : Exception()
- class Connection<T> (val signal: Signal<T>, val function: (T) -> Unit) {
- fun disconnect() {
- signal.removeConnection(this)
- }
- }
- class Signal<T> {
- private val connections = mutableListOf<Connection<T>>()
- fun connect(slot: (T) -> Unit): Connection<T> =
- Connection(this, slot).also(connections::add)
- fun connect(slot: () -> Unit): Connection<T> =
- connect { _: T -> slot() }
- fun connect(signal: Signal<Unit>): Connection<T> =
- connect { _ -> signal.emit(Unit) }
- fun connectAndNow(slot: () -> Unit): Connection<T> {
- slot()
- return connect(slot)
- }
- fun emit(value: T) {
- with (connections.listIterator()) {
- while (hasNext()) {
- try {
- next().function(value)
- }
- catch (e: DisconnectException) {
- remove()
- }
- }
- }
- }
- // Do not call this while this connection is being executed,
- // throw DisconnectException instead.
- fun removeConnection(connection: Connection<T>) {
- connections.remove(connection)
- }
- }
- class Variable<T> (initialValue: T) {
- var value: T = initialValue
- set(newValue) {
- if (field != newValue) {
- field = newValue
- onChange.emit(newValue)
- }
- }
- val onChange = Signal<T>()
- fun nowAndOnChange(slot: (T) -> Unit): Connection<T> =
- onChange.connect(slot).also { slot(value) }
- fun <U> map(f: (T) -> U): Variable<U> {
- val v = Variable(f(value))
- onChange.connect { _ -> v.value = f(value) }
- return v
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement