68 lines
No EOL
1.3 KiB
Text
68 lines
No EOL
1.3 KiB
Text
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)
|
|
}
|
|
} |