diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-04-14 09:21:00 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-04-14 09:21:00 +0000 |
| commit | 5faab5d81cc5ed36824a52a273e83eb20240cb2e (patch) | |
| tree | dba10fadf4cdad0f5524df642fab83f6310a8574 /alv-lib/util.moon | |
| parent | move spec out of spec/core (diff) | |
| download | alive-5faab5d81cc5ed36824a52a273e83eb20240cb2e.tar.gz alive-5faab5d81cc5ed36824a52a273e83eb20240cb2e.zip | |
move lib to alv-lib module
Diffstat (limited to 'alv-lib/util.moon')
| -rw-r--r-- | alv-lib/util.moon | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/alv-lib/util.moon b/alv-lib/util.moon new file mode 100644 index 0000000..dc133e4 --- /dev/null +++ b/alv-lib/util.moon @@ -0,0 +1,112 @@ +import Op, ValueStream, EventStream, Input, val, evt from require 'alv.base' + +all_same = (list) -> + for v in *list[2,] + if v != list[1] + return false + + list[1] + +switch_ = ValueStream.meta + meta: + name: 'switch' + summary: "Switch between multiple inputs." + examples: { '(switch i v0 [v1 v2…])' } + description: " +- when `i` is `true`, the first value is reproduced. +- when `i` is `false`, the second value is reproduced. +- when `i` is a `num`, it is [math/floor][]ed and the matching argument + (indexed starting from 0) is reproduced." + + value: class extends Op + val_or_evt = (val! / evt!)! + pattern = (val.num / val.bool) + val_or_evt*0 + setup: (inputs) => + { i, values } = pattern\match inputs + + @state = values[1].value.__class == ValueStream + + @out = if @state + ValueStream values[1]\type! + else + EventStream values[1]\type! + + super + i: Input.hot i + values: [Input.hot v for v in *values] + + tick: => + { :i, :values } = @inputs + active = switch i! + when true + values[1] + when false + values[2] + else + i = 1 + (math.floor i!) % #values + values[i] + if @state + @out\set active and active! + else + if active and active\dirty! + for event in *active! + @out\add event + +edge = ValueStream.meta + meta: + name: 'edge' + summary: "Convert rising edges to bangs." + examples: { '(edge bool)' } + + value: class extends Op + setup: (inputs) => + @out or= EventStream 'bang' + value = val.bool\match inputs + super value: Input.hot value + + tick: => + now = @inputs.value! + if now and not @state.last + @out\set true + @state.last = now + +change = ValueStream.meta + meta: + name: 'change' + summary: "Convert value changes to events." + examples: { '(change val)' } + + value: class extends Op + setup: (inputs) => + value = val!\match inputs + @out or= EventStream value\type! + super value: Input.hot value + + tick: => + now = @inputs.value! + if now != @state + @out\add @inputs.value! + @state = now + +hold = ValueStream.meta + meta: + name: 'hold' + summary: "Convert events to value changes." + examples: { '(hold evt)' } + + value: class extends Op + setup: (inputs) => + event = evt!\match inputs + @out or= ValueStream event\type! + super event: Input.hot event + + tick: => + for val in *@inputs.event! + @out\set val + +{ + 'switch': switch_ + :edge + :change + :hold +} |
