diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-04-05 13:01:27 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-04-05 13:01:27 +0000 |
| commit | bb731b49b55b3843f16721ee6682afabfb647ff7 (patch) | |
| tree | ea18ff69849894c8114fc02a1ffd140cec824f91 | |
| parent | lib/pilot: fix (diff) | |
| download | alive-bb731b49b55b3843f16721ee6682afabfb647ff7.tar.gz alive-bb731b49b55b3843f16721ee6682afabfb647ff7.zip | |
lib/time: add scale-time, sequence
| -rw-r--r-- | lib/time.moon | 104 |
1 files changed, 84 insertions, 20 deletions
diff --git a/lib/time.moon b/lib/time.moon index 28a0824..a585e63 100644 --- a/lib/time.moon +++ b/lib/time.moon @@ -16,18 +16,13 @@ class Clock extends IOStream tick: => time = monotime! @dt = time - @last - @is_dirty = if @dt >= @frametime + if @dt >= @frametime + @add { dt: @dt, :time } @last = time - true - else - false - unwrap: => - dt = @dt - time = @last - { :dt, :time } - - dirty: => @is_dirty +class ScaledClock extends EventStream + set: (val) => @value + unwrap: => @value clock = ValueStream.meta meta: @@ -50,6 +45,28 @@ IO that triggers other operators at a fixed frame rate. tick: => @out.frametime = 1 / @inputs.fps! +scale_time = ValueStream.meta + meta: + name: 'scale-time' + summary: "Scale clock times." + examples: { '(scale-time [clock] scale)' } + value: class extends Op + new: (...) => + super ... + @out or= EventStream 'clock' + + pattern = -evt.clock + val.num + -val.str + setup: (inputs, scope) => + { clock, scale } = pattern\match inputs + super + clock: Input.hot clock or scope\get '*clock*' + scale: Input.cold scale + + tick: => + scale = @inputs.scale! + for evt in *@inputs.clock! + @out\add {k, v*scale for k,v in pairs evt} + lfo = ValueStream.meta meta: name: 'lfo' @@ -78,8 +95,8 @@ wave selects the wave shape from the following: tau = math.pi * 2 tick: => - if @inputs.clock\dirty! - @state += @inputs.clock!.dt * @iputs.freq! + for tick in *@inputs.clock! + @state += tick.dt * @inputs.freq! @out\set switch @inputs.wave! when 'sin' then .5 + .5 * math.cos @state * tau @@ -109,16 +126,15 @@ ramps from 0 to max (default same as ramp) once every period seconds." max: max and Input.cold max tick: => - clock_dirty = @inputs.clock\dirty! - if clock_dirty + for tick in *@inputs.clock! period = @inputs.period! max = (@inputs.max or @inputs.period)! - @phase += @inputs.clock!.dt / period + @phase += tick.dt / period - while @phase >= 1 - @phase -= 1 + while @phase >= 1 + @phase -= 1 - @out\set @phase * max + @out\set @phase * max tick = ValueStream.meta meta: @@ -142,7 +158,8 @@ ticks." period: Input.cold period tick: => - @state.phase += @inputs.clock!.dt / @inputs.period! + for tick in *@inputs.clock! + @state.phase += tick.dt / @inputs.period! while @state.phase >= 1 @state.phase -= 1 @@ -169,18 +186,65 @@ every = ValueStream.meta period: Input.cold period tick: => - @state += @inputs.clock!.dt / @inputs.period! + for tick in *@inputs.clock! + @state += tick.dt / @inputs.period! while @state >= 1 @state -= 1 @out\add true +sequence = ValueStream.meta + meta: + name: 'sequence' + summary: "Play a sequence of events." + examples: { '(sequence [clock] delay0 evt1 delay1 evt2...)' } + value: class extends Op + new: (...) => + super ... + @state or= { i: 1, t: 0 } + + pair = (val! + val.num)\named('value', 'delay') + pattern = -evt.clock + val.num + pair*0 + + inputify = (step) -> + { + delay: Input.cold step.delay + value: if step.value then Input.hot step.value + } + + setup: (inputs, scope) => + { clock, first, steps } = pattern\match inputs + @out = EventStream steps[1].value\type! + table.insert steps, 1, { delay: first } + super + clock: Input.hot clock or scope\get '*clock*' + steps: [inputify step for step in *steps] + + tick: => + for tick in *@inputs.clock! + @state.t += tick.dt + + change, current = false, nil + while true + current = @inputs.steps[@state.i] + if @state.t >= current.delay! + @state.t -= current.delay! + @state.i = 1 + (@state.i % #@inputs.steps) + change = true + else + break + + if current.value and (change or current.value\dirty!) + @out\add current.value! + { :clock + 'scale-time': scale_time :lfo :ramp :tick :every + :sequence '*clock*': with Clock 1/60 .meta = name: '*clock*' |
