blob: abb49c030f6d29e9778e5ae5e7180100caf944d4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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
@out\add true
@state = 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
}
|