aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2025-03-18 11:23:55 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-18 12:03:57 +0000
commitf480c0b670725c10d6f431d67b1c0ca54e679916 (patch)
tree38e2c116b18e453f1a7b175f05ed38828d65f7be
parentlib: add glsl-view (diff)
downloadalive-f480c0b670725c10d6f431d67b1c0ca54e679916.tar.gz
alive-f480c0b670725c10d6f431d67b1c0ca54e679916.zip
builtins: switch takes single array as value
-rw-r--r--alv/builtins.moon39
-rw-r--r--spec/lib/builtins/cond_spec.moon15
2 files changed, 42 insertions, 12 deletions
diff --git a/alv/builtins.moon b/alv/builtins.moon
index f612203..d76effc 100644
--- a/alv/builtins.moon
+++ b/alv/builtins.moon
@@ -330,24 +330,32 @@ switch_ = Constant.meta
meta:
name: 'switch'
summary: "Switch between multiple inputs."
- examples: { '(switch i v1 v2…)' }
+ examples: { '(switch i v1 v2…)', '(switch i arr)' }
description: "
-- When fed a bang! trigger, steps forward to the next step on each trigger.
-- When fed a num~ or num! stream, reproduces the matching argument (indexed
+- When fed a num~ or num! stream, reproduces the matching value (indexed
starting from 0).
-- When fed a bool~ or bool! stream, outputs the first or second argument for
- `true` and `false` respectively. This version takes at most two argumetns."
+- When fed a bang! trigger, steps forward to the next step on each trigger.
+- When fed a bool~ or bool! stream, outputs the first or second value for
+ `true` and `false` respectively. This version takes at most two values.
+
+When only a single value is provided, it must be an array and is indexed as above."
value: class extends Op
pattern = (sig.num / sig.bool / evt.num / evt.bool / evt.bang) + any!!*0
setup: (inputs) =>
{ i, values } = pattern\match inputs
- val1 = values[1]
- @setup_out val1.result.metatype, val1.result.type
-
if i\type! == T.bang
- @state or= 1
+ @state or= 0
+
+ val1 = values[1].result
+ if #values > 1
+ @length = nil
+ @setup_out val1.metatype, val1.type
+ else
+ assert val1.type.__class == Array, "single value must be array"
+ @length = val1.type.size
+ @setup_out val1.metatype, val1.type.type
super
i: Input.hot i
@@ -356,17 +364,24 @@ switch_ = Constant.meta
tick: =>
{ :i, :values } = @inputs
+ length = @length or #values
+
if i\type! == T.bang
if i\dirty!
@state += 1
- @state = @state % (#values)
+ @state = @state % length
else
@state = switch i!
when true then 0
when false then 1
- else (math.floor i!) % #values
+ else (math.floor i!) % length
- @out\set if v = values[@state + 1] then v!
+ @out\set if @length
+ val = values[1]!
+ val and val[@state + 1]
+ else
+ val = values[@state + 1]
+ val and val!
vis: =>
with Op.vis @
diff --git a/spec/lib/builtins/cond_spec.moon b/spec/lib/builtins/cond_spec.moon
index 89f7c7e..04c56ef 100644
--- a/spec/lib/builtins/cond_spec.moon
+++ b/spec/lib/builtins/cond_spec.moon
@@ -90,3 +90,18 @@ describe "when", ->
assert.is.true \is_const!
assert.is.equal '<num[3]= [1 2 3]>', tostring .result
+
+describe "switch", ->
+ COPILOT = TestPilot!
+
+ it "switches by num", ->
+ for key, val in pairs {[0]: 11, [0.5]: 11, 22, 33, 11}
+ with COPILOT\eval_once "(switch #{key} 11 22 33)"
+ assert.is.true \is_const!
+ assert.is.equal val, .result!
+
+ it "switches arrays by num", ->
+ for key, val in pairs {[0]: 11, [0.5]: 11, 22, 33, 11}
+ with COPILOT\eval_once "(switch #{key} [11 22 33])"
+ assert.is.true \is_const!
+ assert.is.equal val, .result!