import Constant, Error, Op, Input, T, Array, sig, evt from require 'alv.base' apply_range = (range, val) -> if range\type! == T.str switch range! when 'uni' then val when 'bip' then val*2 - 1 when 'rad' then val*2 * math.pi when 'deg' then val * 360 else error Error 'argument', "unknown range '#{range!}'" elseif range\type! == T.num val * range! else error Error 'argument', "range has to be a string or number" range_doc = " range can be one of: - 'uni' [ 0 - 1[ (default) - 'bip' [-1 - 1[ - 'rad' [ 0 - tau[ - 'deg' [ 0 - 360[ - (num) [ 0 - num[" pattern = -evt.bang + -(sig.num / sig.str) num = Constant.meta meta: name: 'num' summary: 'Generate a random number.' examples: { '(random/num [trigger] [range]))' } description: "Generate a random value in `range` when created and on `trig`. #{range_doc}" value: class extends Op new: (...) => super ... @setup_out '~', T.num @state or @gen! gen: => @state = math.random! setup: (inputs) => { trig, range } = pattern\match inputs super trig: trig and Input.hot trig range: Input.hot range or Constant.str 'uni' tick: => @gen! if @inputs.trig and @inputs.trig\dirty! @out\set apply_range @inputs.range, @state vec = (n) -> typ = Array n, T.num Constant.meta meta: name: "vec#{n}" summary: 'Generate a random vector.' examples: { '(random/vec#{n} [trigger] [range]))' } description: "Generate a random #{typ} in `range` when created and on `trig`. #{range_doc}" value: class extends Op new: (...) => super ... @setup_out '~', typ @state or @gen! gen: => @state = for i=1,n do math.random! setup: (inputs) => { trig, range } = pattern\match inputs super trig: trig and Input.hot trig range: Input.hot range or Constant.str 'uni' tick: => @gen! if @inputs.trig and @inputs.trig\dirty! @out\set [apply_range @inputs.range, v for v in *@state] int = Constant.meta meta: name: 'int' summary: 'Generate a random integer.' examples: { '(random/num [trigger] [min] max))' } description: "Generate a random value in `range` when created and on `trig`. #{range_doc}" value: class extends Op new: (...) => super ... @setup_out '~', T.num @state or @gen! gen: => @state = math.random! int_pattern = -evt.bang + sig.num + -sig.num setup: (inputs) => { trig, min, max } = int_pattern\match inputs if not max min, max = nil, min super trig: trig and Input.hot trig min: Input.hot min or Constant.num 0 max: Input.hot max tick: => { :trig, :max, :min } = @unwrap_all! if trig last = math.floor min + (max - min) * @state while last == math.floor min + (max - min) * @state @gen! @out\set math.floor min + (max - min) * @state Constant.meta meta: name: 'random' summary: "Random number generation." value: :num :int vec2: vec 2 vec3: vec 3 vec4: vec 4