import "math/event" for Event, MultiListenerToken import "math/util" for Util class Observable{ value{_value} value=(v){ _event.emit([v]) //do extra list wrapping here to allow list values _value = v } value_no_update=(v){_value = v} event{_event} static new(value){ var variable = new() variable.value_no_update = value return variable } construct new(){ _event = Event.new() } //manually emit an update emit(){ _event.emit([_value]) } on_change(fn){ return _event.listen(fn) } on_change(initial, fn){ if(initial){ fn.call(value) } return on_change(fn) } not_on_change(fn){ _event.unlisten(fn) } on_not_null(fn){ if(value){ fn.call(value) } else { _event.once(fn) } } static any_change(observables, fn){ var change_method = Fn.new{|whatever| Util.call_arg_list(fn, observables.map{|observable| observable.value.toList}) } var tokens = observables.map{|observable| return observable.on_change(change_method) } return MultiListenerToken.new(tokens) } static any_change(observables, initial, fn){ if(initial){ Util.call_arg_list(fn, observables.map{|observable|observable.value}.toList) } any_change(observables, fn) } }