Advertisement
Guest User

Untitled

a guest
Jan 6th, 2025
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 1.79 KB | None | 0 0
  1. // Throw this while handling a signal to disconnect it
  2. class DisconnectException : Exception()
  3.  
  4. class Connection<T> (val signal: Signal<T>, val function: (T) -> Unit) {
  5.     fun disconnect() {
  6.         signal.removeConnection(this)
  7.     }
  8. }
  9.  
  10. class Signal<T> {
  11.     private val connections = mutableListOf<Connection<T>>()
  12.  
  13.     fun connect(slot: (T) -> Unit): Connection<T> =
  14.         Connection(this, slot).also(connections::add)
  15.  
  16.     fun connect(slot: () -> Unit): Connection<T> =
  17.         connect { _: T -> slot() }
  18.  
  19.     fun connect(signal: Signal<Unit>): Connection<T> =
  20.         connect { _ -> signal.emit(Unit) }
  21.  
  22.     fun connectAndNow(slot: () -> Unit): Connection<T> {
  23.         slot()
  24.         return connect(slot)
  25.     }
  26.  
  27.     fun emit(value: T) {
  28.         with (connections.listIterator()) {
  29.             while (hasNext()) {
  30.                 try {
  31.                     next().function(value)
  32.                 }
  33.                 catch (e: DisconnectException) {
  34.                     remove()
  35.                 }
  36.             }
  37.         }
  38.     }
  39.  
  40.     // Do not call this while this connection is being executed,
  41.     // throw DisconnectException instead.
  42.     fun removeConnection(connection: Connection<T>) {
  43.         connections.remove(connection)
  44.     }
  45. }
  46.  
  47. class Variable<T> (initialValue: T) {
  48.     var value: T = initialValue
  49.         set(newValue) {
  50.             if (field != newValue) {
  51.                 field = newValue
  52.                 onChange.emit(newValue)
  53.             }
  54.         }
  55.  
  56.     val onChange = Signal<T>()
  57.  
  58.     fun nowAndOnChange(slot: (T) -> Unit): Connection<T> =
  59.         onChange.connect(slot).also { slot(value) }
  60.  
  61.     fun <U> map(f: (T) -> U): Variable<U> {
  62.         val v = Variable(f(value))
  63.         onChange.connect { _ -> v.value = f(value) }
  64.         return v
  65.     }
  66. }
  67.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement