import "luxe: events" for Events

class Observable{
  static on_change{"on_change"}

  value{_value}
  value=(v){
    _event.emit(Observable.on_change, v)
    _value = v
  }
  value_no_update=(v){_value = v}

  events{_event}

  static new(value){
    var variable = new()
    variable.value_no_update = value
    return variable
  }

  construct new(){
    _event = Events.new()
  }

  on_change(fn){
    _event.listen(Observable.on_change, fn)
  }

  on_change(initial, fn){
    if(initial){
      fn.call(value)
    }
    on_change(fn)
  }

  not_on_change(fn){
    _event.unlisten(Observable.on_change, fn)
  }

  on_not_null(fn){
    if(value){
      fn.call(value)
    } else {
      _event.once(Observable.on_change, fn)
    }
  }
}