aboutsummaryrefslogtreecommitdiffstats
path: root/alv-lib/util.moon
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-04-14 09:21:00 +0000
committers-ol <s-ol@users.noreply.github.com>2020-04-14 09:21:00 +0000
commit5faab5d81cc5ed36824a52a273e83eb20240cb2e (patch)
treedba10fadf4cdad0f5524df642fab83f6310a8574 /alv-lib/util.moon
parentmove spec out of spec/core (diff)
downloadalive-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.moon112
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
+}