aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-02-16 11:47:24 +0000
committers-ol <s-ol@users.noreply.github.com>2020-02-16 11:47:24 +0000
commit2953f1e56b408fc26eb54fa65935505dd128ce82 (patch)
tree8c7c513ccf03df06c4e9e2e70ba68031d2d0b7a5 /lib
parentadd ==, mod (diff)
downloadalive-2953f1e56b408fc26eb54fa65935505dd128ce82.tar.gz
alive-2953f1e56b408fc26eb54fa65935505dd128ce82.zip
major refactoring: Const, Stream + ResultNode
Diffstat (limited to 'lib')
-rw-r--r--lib/debug.moon6
-rw-r--r--lib/envelope.moon13
-rw-r--r--lib/gui.moon9
-rw-r--r--lib/logic.moon46
-rw-r--r--lib/math.moon66
-rw-r--r--lib/midi/core.moon17
-rw-r--r--lib/midi/init.moon44
-rw-r--r--lib/midi/launchctl.moon99
-rw-r--r--lib/osc.moon11
-rw-r--r--lib/pilot.moon22
-rw-r--r--lib/string.moon9
-rw-r--r--lib/time.moon57
-rw-r--r--lib/util.moon53
13 files changed, 270 insertions, 182 deletions
diff --git a/lib/debug.moon b/lib/debug.moon
index ece365f..f642c2e 100644
--- a/lib/debug.moon
+++ b/lib/debug.moon
@@ -3,12 +3,10 @@ import Op from require 'core'
class out extends Op
@doc: "(out name-str value) - log value to the console"
- setup: (name, @chld) =>
- @name = name\getc!
+ setup: (@name, @value) =>
update: (dt) =>
- @chld\update dt
- L\print "@name", @chld\get!
+ L\print "#{@name\unwrap 'str'}", @value\unwrap!
{
:out
diff --git a/lib/envelope.moon b/lib/envelope.moon
index 8e8fafe..eb79a64 100644
--- a/lib/envelope.moon
+++ b/lib/envelope.moon
@@ -1,4 +1,4 @@
-import Const, Op, Scope, eval from require 'core'
+import Stream, Op, Scope, eval from require 'core'
class ar_core extends Op
@doc: "(ar-core attack release gate)
@@ -8,21 +8,18 @@ goes from 0 to 1 in attack seconds, holds while gate is on, then goes back to 0
new: (...) =>
super ...
- @value = 0
+ @out = Stream 'num', 0
setup: (@a, @r, @gate) =>
assert @a, "ar requires an attack value"
assert @r, "ar requires a release value"
assert @gate, "ar requires a gate value"
+ @out
update: (dt) =>
- @a\update dt
- @r\update dt
- @gate\update dt
+ slope = if (@gate\unwrap 'bool') then (@a\unwrap! or 0.1) else -(@r\unwrap! or 0.5)
- slope = if @gate\get! then (@a\get! or 0.1) else -(@r\get! or 0.5)
-
- @value = math.min 1, math.max 0, @value + dt / slope
+ @out\set math.min 1, math.max 0, @out\unwrap! + dt / slope
scope = Scope.from_table { 'ar-core': ar_core }
scope\set 'ar', eval '(fn (a r) (fn (gate) (ar-core a r gate)))', scope
diff --git a/lib/gui.moon b/lib/gui.moon
index a2fee4b..474de5c 100644
--- a/lib/gui.moon
+++ b/lib/gui.moon
@@ -12,12 +12,11 @@ display value as a bar"
setup: (name, @chld) =>
@@instances[@name] = nil if @name
- @name = name\getc!
+ @name = name\const!\unwrap!
@@instances[@name] = @
update: (dt) =>
- @chld\update dt
- @value = @chld\get!
+ @value = @chld\unwrap!
destroy: =>
@@instances[@name] = nil
@@ -44,9 +43,11 @@ class key extends Op
setup: (@key) =>
assert @key
+ @out = Stream 'bool', false
+ @out
update: (dt) =>
- @value = lk.isDown @key\get!
+ @out\set lk.isDown @key\unwrap!
arguments, k = {}
for a in *arg
diff --git a/lib/logic.moon b/lib/logic.moon
index 1c274dd..c476033 100644
--- a/lib/logic.moon
+++ b/lib/logic.moon
@@ -1,37 +1,36 @@
-import Op from require 'core'
+import Stream, Op from require 'core'
unpack or= table.unpack
class BinOp extends Op
+ new: (...) =>
+ super ...
+ @out = Stream 'bool'
+
setup: (...) =>
@children = { ... }
assert #@children >= 2, "#{@} needs at least two parameters"
-
- update: (dt) =>
- for child in *@children
- child\update dt
+ @out
class eq extends BinOp
@doc: "(eq a b [c]...)
(== a b [c]...) - check for equality"
update: (dt) =>
- super\update dt
-
- @value = true
- val = @children[1]\get!
+ equal = true
+ val = @children[1]\unwrap!
for child in *@children[2,]
- @value and= val == child\get!
+ equal and= val == child\unwrap!
+ @out\set equal
class and_ extends BinOp
@doc: "(and a b [c]...) - AND values"
update: (dt) =>
- super\update dt
-
- @value = true
+ value = true
for child in *@children
- @value and= child\get!
+ value and= child\unwrap!
+ @out\set value
class or_ extends BinOp
@doc: "(or a b [c]...) - OR values
@@ -39,31 +38,30 @@ class or_ extends BinOp
subtracts all other arguments from a"
update: (dt) =>
- super\update dt
-
- @value = false
+ value = false
for child in *@children
- @value or= child\get!
+ value or= child\unwrap!
+ @out\set value
class not_ extends Op
@doc: "(not a) - boolean opposite"
setup: (@a) =>
+ @out = Stream 'bool'
+ @out
update: (dt) =>
- @a\update dt
-
- @value = not @a\get!
+ @out\set not @a\unwrap!
class bool extends Op
@doc: "(bool a) - convert to bool"
setup: (@a) =>
+ @out = Stream 'bool'
+ @out
update: (dt) =>
- @a\update dt
-
- @value = switch @a\get!
+ @out\set switch @a\unwrap!
when false, nil, 0
false
else
diff --git a/lib/math.moon b/lib/math.moon
index 54d3440..68dae3a 100644
--- a/lib/math.moon
+++ b/lib/math.moon
@@ -1,25 +1,25 @@
-import Op from require 'core'
+import Stream, Op, Const from require 'core'
unpack or= table.unpack
class BinOp extends Op
+ new: (...) =>
+ super ...
+ @out = Stream 'num', 0
+
setup: (...) =>
@children = { ... }
assert #@children >= 2, "#{@} needs at least two parameters"
-
- update: (dt) =>
- for child in *@children
- child\update dt
+ @out
class add extends BinOp
@doc: "(+ a b [c]...)
(add a b [c]...) - add values"
update: (dt) =>
- super\update dt
-
- @value = 0
+ value = 0
for child in *@children
- @value += child\get!
+ value += child\unwrap 'num'
+ @out\set value
class sub extends BinOp
@doc: "(- a b [c]...)
@@ -28,22 +28,20 @@ class sub extends BinOp
subtracts all other arguments from a"
update: (dt) =>
- super\update dt
-
- @value = @children[1]\get!
+ value = @children[1]\unwrap 'num'
for child in *@children[2,]
- @value -= child\get!
+ value -= child\unwrap 'num'
+ @out\set value
class mul extends BinOp
@doc: "(* a b [c]...)
(mul a b [c]...) - multiply values"
update: (dt) =>
- super\update dt
-
- @value = 1
+ value = 1
for child in *@children
- @value *= child\get!
+ value *= child\unwrap 'num'
+ @out\set value
class div extends BinOp
@doc: "(/ a b [c]...)
@@ -52,11 +50,26 @@ class div extends BinOp
divides a by all other arguments"
update: (dt) =>
- super\update dt
-
- @value = @children[1]\get!
+ value = @children[1]\unwrap 'num'
for child in *@children[2,]
- @value /= child\get!
+ value /= child\unwrap 'num'
+ @out\set value
+
+evenodd_op = (name, remainder) ->
+ class k extends Op
+ setup: (@a, @div=Const.num 2) =>
+ @out = Stream 'bool'
+ @out
+
+ update: (dt) =>
+ a, divi = (@a\unwrap 'num'), @div\unwrap 'num'
+ @out\set (a % divi) == remainder
+
+ k.__name = name
+ k.doc = "(#{name} a [div]) - check for #{name} divison
+
+div defaults to 2"
+ k
func_op = (name, arity, func) ->
k = class extends Op
@@ -65,12 +78,11 @@ func_op = (name, arity, func) ->
if arity != '*'
assert #@params == arity, "#{@} needs exactly #{arity} parameters"
- update: (dt) =>
- params = for param in *@params
- param\update dt
- param\get!
+ @out = Stream 'num'
+ @out
- @value = func unpack params
+ update: (dt) =>
+ @out\set func unpack [p\unwrap 'num' for p in *@params]
k.__name = name
k
@@ -85,6 +97,8 @@ module = {
:mod, '%': mod
mix: func_op 'mix', 3, (a, b, i) -> i*b + (1-i)*a
+ even: evenodd_op 'even', 0
+ odd: evenodd_op 'odd', 1
pi: math.pi, huge: math.huge
}
diff --git a/lib/midi/core.moon b/lib/midi/core.moon
index ea49a2c..891de0a 100644
--- a/lib/midi/core.moon
+++ b/lib/midi/core.moon
@@ -51,8 +51,10 @@ class Input
-- register a handler
-- mask is { :status, :chan, :a } (all keys optional)
+ -- returns mask for op convenience
attach: (mask, handler) =>
@listeners[mask] = handler
+ mask
detach: (mask) =>
@listeners[mask] = nil
@@ -83,8 +85,23 @@ class InOut
detach: (...) => @inp\detach ...
send: (...) => @out\send ...
+apply_range = (range, val) ->
+ if range.type == 'str'
+ switch range\unwrap!
+ when 'raw' then val
+ when 'uni' then val / 128
+ when 'bip' then val / 64 - 1
+ when 'rad' then val / 64 * math.pi
+ else
+ error "unknown range #{@range}"
+ elseif range.type == 'num'
+ val / 128 * range\unwrap!
+ else
+ error "range has to be a string or number"
+
{
:Input
:Output
:InOut
+ :apply_range
}
diff --git a/lib/midi/init.moon b/lib/midi/init.moon
index f522b6c..c9e2476 100644
--- a/lib/midi/init.moon
+++ b/lib/midi/init.moon
@@ -1,29 +1,29 @@
-import Const, Op from require 'core'
-import Input from require 'lib.midi.core'
+import Stream, Const, Op from require 'core'
+import Input, apply_range from require 'lib.midi.core'
-dispatch = Input 'system:midi_capture_6'
+dispatch = Input 'system:midi_capture_4'
class gate extends Op
@doc: "(midi/gate note [chan]) - gate from note-on and note-off messages"
- new: (...) =>
- super ...
-
destroy: =>
dispatch\detach @mask if @mask
setup: (note, chan) =>
dispatch\detach @mask if @mask
- note = note\getc 'num'
- chan = chan and chan\getc 'num'
+ note = note\const!\unwrap 'num'
+ chan = chan and chan\const!\unwrap 'num'
@value = false
@mask = dispatch\attach { :chan, a: note }, (status) ->
if status == 'note-on'
- @value = true
+ @out\set true
else if status == 'note-off'
- @value = false
+ @out\set false
+
+ @out = Stream 'bool', false
+ @out
update: (dt) => dispatch\tick!
@@ -43,26 +43,16 @@ range can be one of:
setup: (cc, chan, @range=Const.str'uni') =>
dispatch\detach @mask if @mask
- cc = cc\getc 'num'
- chan = chan and chan\getc 'num'
+ cc = cc\const!\unwrap 'num'
+ chan = chan and chan\const!\unwrap 'num'
- @mask = dispatch\attach { status: 'control-change', :chan, a: cc }, (_, _, _, val) -> @apply val
+ @mask = dispatch\attach { status: 'control-change', :chan, a: cc }, (_, _, _, val) ->
+ @out\set apply_range @range, val
- update: (dt) => dispatch\tick!
+ @out = Stream 'num', 0
+ @out
- apply: (val) =>
- @value = if @range.type == 'str'
- switch @range\get!
- when 'raw' then val
- when 'uni' then val / 128
- when 'bip' then val / 64 - 1
- when 'rad' then val / 64 * math.pi
- else
- error "unknown range #{@range}"
- elseif @range.type == 'num'
- val / 128 * @range\get!
- else
- error "range has to be a string or number"
+ update: (dt) => dispatch\tick!
{
:gate
diff --git a/lib/midi/launchctl.moon b/lib/midi/launchctl.moon
index c7d7b06..778a724 100644
--- a/lib/midi/launchctl.moon
+++ b/lib/midi/launchctl.moon
@@ -1,66 +1,127 @@
-import Const, Op from require 'core'
-import InOut from require 'lib.midi.core'
+import Stream, Const, Op from require 'core'
+import InOut, apply_range from require 'lib.midi.core'
import bor, lshift from require 'bit32'
-launch = InOut 'system:midi_capture_6', 'system:midi_playback_6'
+launch = InOut 'system:midi_capture_4', 'system:midi_playback_4'
color = (r, g) -> bor 12, r, (lshift g, 4)
+class cc_seq extends Op
+ @doc: "(launctl/cc-seq i start chan [steps [range]]) - CC-Sequencer
+
+returns the value for the i-th step steps (buttons starting from start).
+steps defaults to 8.
+
+range can be one of:
+- 'raw' [ 0 - 128[
+- 'uni' [ 0 - 1[ (default)
+- 'bip' [-1 - 1[
+- 'rad' [ 0 - tau[
+- (num) [ 0 - num["
+
+ destroy: =>
+ launch\detach @mask if @mask
+
+ new: =>
+ @steps = {}
+ @out = Stream 'num'
+
+ setup: (@i, start, chan, steps=(Const.num 8), @range=Const.str 'uni') =>
+ launch\detach @mask if @mask
+
+ @start = start\const!\unwrap 'num'
+ @chan = chan\const!\unwrap 'num'
+ steps = steps\const!\unwrap 'num'
+
+ while steps > #@steps
+ table.insert @steps, 0
+ while steps < #@steps
+ table.remove @steps
+
+ @mask = launch\attach { status: 'control-change', chan: @chan }, (_, _, cc, val) -> @change cc, val
+ @out
+
+ change: (cc, val) =>
+ i = cc - @start
+ if i < #@steps
+ @steps[i+1] = val
+
+ update: (dt) =>
+ launch\tick!
+
+ curr_i = (@i\unwrap 'num') % #@steps
+
+ @out\set apply_range @range, @steps[curr_i+1]
+
+
class gate_seq extends Op
@doc: "(launctl/gate-seq i start chan [steps]) - Gate-Sequencer
-returns true or false for the i-th step steps (buttons starting from start)."
+returns true or false for the i-th step steps (buttons starting from start).
+steps defaults to 8."
destroy: =>
launch\detach @mask if @mask
new: =>
@steps = {}
- @value = false
+ @out = Stream 'bool'
setup: (@i, start, chan, steps=(Const.num 8)) =>
launch\detach @mask if @mask
- @start = start\getc 'num'
- @chan = chan\getc 'num'
- steps = steps\getc 'num'
+ for i=1, #@steps
+ launch\send 'note-on', @chan, (@start+i), 0, color 0, 0
+
+ @start = start\const!\unwrap 'num'
+ @chan = chan\const!\unwrap 'num'
+ steps = steps\const!\unwrap 'num'
while steps > #@steps
table.insert @steps, false
while steps < #@steps
table.remove @steps
- @mask = launch\attach { status: 'note-on', chan: @chan }, (_, _, note, _) -> @toggle note
+ for i=1, steps
+ @display i
+
+ @mask = launch\attach { status: 'note-on', chan: @chan }, (_, _, note, _) ->
+ @toggle note
+
+ @out
toggle: (note) =>
i = note - @start
val = @steps[i+1]
if val != nil
@steps[i+1] = not val
- curr_i = (@i\get 'num') % #@steps
- launch\send 'note-on', @chan, note, light @steps[i+1], i == curr_i
+ curr_i = (@i\unwrap 'num') % #@steps
+ @display i, i == curr_i
+
+ display: (i, active) =>
+ launch\send 'note-on', @chan, (@start + i), light @steps[i+1], active
light = (set, active) ->
set = if set then 'S' else ' '
active = if active then 'A' else ' '
color switch set .. active
when ' ' then 0, 0
- when ' A' then 1, 0
- when 'S ' then 0, 1
- when 'SA' then 0, 3
+ when ' A' then 1, 1
+ when 'S ' then 1, 0
+ when 'SA' then 3, 1
update: (dt) =>
launch\tick!
- @i\update dt
- curr_i = (@i\get 'num') % #@steps
+ curr_i = (@i\unwrap 'num') % #@steps
prev_i = (curr_i - 1) % #@steps
- launch\send 'note-on', @chan, (@start + curr_i), light @steps[curr_i+1], true
- launch\send 'note-on', @chan, (@start + prev_i), light @steps[prev_i+1], false
+ @display curr_i, true
+ @display prev_i, false
- @value = @steps[curr_i+1]
+ @out\set @steps[curr_i+1]
{
'gate-seq': gate_seq
+ 'cc-seq': cc_seq
}
diff --git a/lib/osc.moon b/lib/osc.moon
index dae6737..fed1697 100644
--- a/lib/osc.moon
+++ b/lib/osc.moon
@@ -1,4 +1,4 @@
-import Const, Op, FnDef from require 'core'
+import Stream, Op from require 'core'
import pack, unpack from require 'osc'
import dns, udp from require 'socket'
@@ -13,12 +13,9 @@ class out extends Op
setup: (@host, @port, @path, @value) =>
update: (dt) =>
- for p in *{@host, @port, @path, @value}
- L\push p\update, dt
-
- ip = dns.toip @host\get!
- port = @port\get!
- msg = pack @path\get!, @value\get!
+ ip = dns.toip @host\unwrap 'str'
+ port = @port\unwrap 'num'
+ msg = pack (@path\unwrap 'str'), @value\unwrap!
@@udp\sendto msg, ip, port
{
diff --git a/lib/pilot.moon b/lib/pilot.moon
index 1cbc070..2a7d21a 100644
--- a/lib/pilot.moon
+++ b/lib/pilot.moon
@@ -1,5 +1,5 @@
-import Const, Op, FnDef from require 'core'
-import dns, udp from require 'socket'
+import Op from require 'core'
+import udp from require 'socket'
conn = udp!
hex = "0123456789abcdef"
@@ -18,17 +18,12 @@ send = (tbl) ->
class play extends Op
@doc: "(play trig ch oct note [vel [len]]) - play a note when trig is live"
- setup: (@trig, @ch, @oct, @note, @vel, @len) =>
+ setup: (@trig, ...) =>
+ @vals = { ... }
update: (dt) =>
- vals = for c in *{@trig, @ch, @oct, @note, @vel, @len }
- c\update dt
- c\get!
-
- trig = table.remove vals, 1
-
- if trig
- send vals
+ if @trig\unwrap 'bool'
+ send [c\unwrap! for c in *@vals]
class effect extends Op
@doc: "(effect which a b) - set an effect
@@ -38,10 +33,7 @@ which is one of 'DIS', 'CHO', 'REV' or 'FEE'"
setup: (@which, @a, @b) =>
update: (dt) =>
- @which\update dt
- @a\update dt
- @b\update dt
- which, a, b = @which\get!, @a\get!, @b\get!
+ which, a, b = (@which\unwrap 'str'), @a\unwrap!, @b\unwrap!
if which and a and b
send { which, a, b }
{
diff --git a/lib/string.moon b/lib/string.moon
index 82e9702..6a9b7d7 100644
--- a/lib/string.moon
+++ b/lib/string.moon
@@ -1,4 +1,4 @@
-import Op from require 'core'
+import Stream, Op from require 'core'
class str extends Op
@doc: "(str v1 [v2]...)
@@ -6,12 +6,11 @@ class str extends Op
setup: (...) =>
@children = { ... }
+ @out = Stream 'str'
+ @out
update: (dt) =>
- for child in *@children
- child\update dt
-
- @value = table.concat [tostring child\get! for child in *@children]
+ @out\set table.concat [tostring child\unwrap! for child in *@children]
{
:str, '..': str
diff --git a/lib/time.moon b/lib/time.moon
index 89f947e..7ce8b84 100644
--- a/lib/time.moon
+++ b/lib/time.moon
@@ -1,4 +1,4 @@
-import Const, Op from require 'core'
+import Stream, Const, Op from require 'core'
class lfo extends Op
@doc: "(lfo freq [wave]) - low-frequency oscillator
@@ -12,19 +12,19 @@ wave selects the wave shape from the following (default sin):
tau = math.pi * 2
new: (...) =>
super ...
+ print "creating LFO"
+ @out = Stream 'num'
@phase = 0
default_wave = Const 'str', 'sin'
setup: (@freq, @wave=default_wave) =>
assert @freq, "lfo requires a frequency value"
L\trace "setup #{@}, freq=#{@freq}, wave=#{@wave}"
+ @out
update: (dt) =>
- @freq\update dt
- @wave\update dt
-
- @phase += dt * @freq\get!
- @value = switch @wave\get!
+ @phase += dt * @freq\unwrap 'num'
+ @out\set switch @wave\unwrap!
when 'sin' then .5 + .5 * math.cos @phase * tau
when 'saw' then @phase % 1
when 'tri' then math.abs (2*@phase % 2) - 1
@@ -37,45 +37,64 @@ ramps from 0 to max (default same as ramp) once every period seconds"
new: (...) =>
super ...
+ @out = Stream 'num'
@phase = 0
+ @out
setup: (@period, @max) =>
assert @period, "tick requires a period value"
update: (dt) =>
- @period\update dt
- max = if @max
- @max\update dt
- @max\get!
- else
- @period\get!
-
- @phase += dt / @period\get!
+ period = @period\unwrap 'num'
+ max = if @max then @max\unwrap! else period
+ @phase += dt / period
if @phase >= 1
@phase -= 1
- @value = @phase * max
+ @out\set @phase * max
class tick extends Op
@doc: "(tick period) - count ticks
-counts upwards every period seconds and returns the number of completed ticks."
+counts upwards by one every period seconds and returns the number of completed ticks."
new: (...) =>
super ...
+ @out = Stream 'num'
@phase = 0
setup: (@period) =>
assert @period, "tick requires a period value"
+ @out
update: (dt) =>
- @period\update dt
+ @phase += dt / @period\unwrap 'num'
+ @out\set math.floor @phase
+
+class every extends Op
+ @doc: "(every period) - sometimes true
- @phase += dt / @period\get!
- @value = math.floor @phase
+returns true once every period seconds."
+ new: (...) =>
+ super ...
+ @out = Stream 'bool'
+ @phase = 0
+
+ setup: (@period) =>
+ assert @period, "every requires a period value"
+ @out
+
+ update: (dt) =>
+ @phase += dt / @period\unwrap 'num'
+ if @phase > 1
+ @phase -= 1
+ @out\set true
+ else
+ @out\set false
{
:lfo
:ramp
:tick
+ :every
}
diff --git a/lib/util.moon b/lib/util.moon
index af5d8f8..192c489 100644
--- a/lib/util.moon
+++ b/lib/util.moon
@@ -1,4 +1,4 @@
-import Const, Op from require 'core'
+import Stream, Const, Op from require 'core'
class switch_ extends Op
@doc: "(switch i v0 [v1 v2...]) - switch between multiple inputs
@@ -10,14 +10,16 @@ when i is a num, it is (floor)ed and the matching argument (starting from 0) is
setup: (@i, ...) =>
@choices = { ... }
- update: (dt) =>
- @i\update dt
- i = @i\get!
+ typ = @choices[1].type
+ for inp in *@choices[2,]
+ assert inp.type == typ, "not all values have the same type: #{typ} != #{inp.type}"
- for choice in *@choices
- choice\update dt
+ @out = Stream typ
+ @out
- active = switch @i\get!
+ update: (dt) =>
+ i = @i\unwrap!
+ active = switch i
when true
@choices[1]
when false
@@ -25,7 +27,7 @@ when i is a num, it is (floor)ed and the matching argument (starting from 0) is
else
i = 1 + (math.floor i) % #@choices
@choices[i]
- @value = active and active\get!
+ @out\set active and active\unwrap!
class switch_pause extends Op
@doc: "(switch- i v0 [v1 v2...]) - switch and pause multiple inputs
@@ -35,10 +37,16 @@ like (switch ...) except that the unused inputs are paused."
setup: (@i, ...) =>
@choices = { ... }
+ typ = @choices[1].type
+ for inp in *@choices[2,]
+ assert inp.type == typ, "not all values have the same type: #{typ} != #{inp.type}"
+
+ @out = Stream typ
+ @out
+
update: (dt) =>
- @i\update dt
- i = @i\get!
- active = switch @i\get!
+ i = @i\unwrap!
+ active = switch i
when true
@choices[1]
when false
@@ -47,21 +55,18 @@ like (switch ...) except that the unused inputs are paused."
i = 1 + (math.floor i) % #@choices
@choices[i]
- @value = if active
- active\update dt
- active\get!
+ @out\set if active
+ active\unwrap!
class edge extends Op
setup: (@i) =>
- @value = false
@last = false
+ @out = Stream @i.type
+ @out
update: (dt) =>
- @i\update dt
-
- now = @i\get!
-
- @value = not @last and now
+ now = @i\unwrap!
+ @out\set not @last and now
@last = now
class keep extends Op
@@ -71,12 +76,12 @@ always reproduces the last non-nil value the input produced or default.
default defaults to zero."
setup: (@i, @default=Const.num 0) =>
+ @out = Stream @i.type, @default.value
+ @out
update: (dt) =>
- @i\update dt
-
- next = @i\get!
- @value = next or @value or @default\get!
+ if next = @i\unwrap!
+ @out\set next
{
'switch': switch_