aboutsummaryrefslogtreecommitdiffstats
path: root/lib/util.moon
blob: 65bab65e4fc6807927e19a22f7fab070e842a075 (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
import Op, Value, ValueInput, EventInput, ColdInput, match
  from require 'core.base'

all_same = (list) ->
  for v in *list[2,]
    if v != list[1]
      return false

  list[1]

class switch_ extends Op
  @doc: "(switch i v0 [v1 v2...]) - switch between multiple inputs

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 (floor)ed and the matching argument (starting from 0) is reproduced."

  setup: (inputs) =>
    { i, values } = match 'any *any', inputs

    i_type = i\type!
    assert i_type == 'bool' or i_type == 'num', "#{@}: i has to be bool or num"
    typ = all_same [v\type! for v in *values]
    @out = Value typ

    super
      i: ValueInput i
      values: [ValueInput 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]
    @out\set active and active!

--class switch_pause extends Op
--  @doc: "(switch- i v0 [v1 v2...]) - switch and pause multiple inputs
--
--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
--
--  tick: =>
--    i = @i\unwrap!
--    active = switch i
--      when true
--        @choices[1]
--      when false
--        @choices[2]
--      else
--        i = 1 + (math.floor i) % #@choices
--        @choices[i]
--
--    @out\set if active
--      active\unwrap!

class edge extends Op
  @doc: "(edge bool) - convert rising edges to bangs"
  new: => super 'bang'

  setup: (inputs) =>
    { value } = match 'bool', inputs
    super value: EventInput

  tick: =>
    now = @inputs.value!
    if now and not @last
      @out\set true
      @last = now

class default extends Op
  @doc: "(default stream default) - provide a default value for an event stream

starts out as default but forwards events from stream.
default defaults to zero."

  setup: (params) =>
    { value, init } = match 'any any', inputs
    super
      value: EventInput value
      init: ColdInput init

    @out = Value value\type!
    @out\set @inputs.init\unwrap!

  tick: =>
    { :value } = @inputs
    if value\dirty!
      @out\set value!

{
  'switch': switch_
  :edge
  :default
}