diff --git a/alv-lib/_osc.moon b/alv-lib/_osc.moon index 43297df..265be9e 100644 --- a/alv-lib/_osc.moon +++ b/alv-lib/_osc.moon @@ -2,21 +2,19 @@ import opairs from require 'alv.util' import T, Array, Struct from require 'alv.base' -add_item = (message, type, val) -> +add_item = (message, type, val, use_arrays=false) -> switch type.__class when Array - -- message\add '[' + message\add '[' if use_arrays for i=1,type.size - add_item message, type.type, val[i] - -- message\add ']' + add_item message, type.type, val[i], use_arrays + message\add ']' if use_arrays when Struct - -- message\add '[' + message\add '[' if use_arrays for key, subtype in opairs type.types - -- message\add '[' message\add 's', key - add_item message, subtype, val[key] - -- message\add ']' - -- message\add ']' + add_item message, subtype, val[key], use_arrays + message\add ']' if use_arrays else ts = switch type when T.num then 'f' diff --git a/alv-lib/osc.moon b/alv-lib/osc.moon index b50d9f8..8c93b07 100644 --- a/alv-lib/osc.moon +++ b/alv-lib/osc.moon @@ -66,6 +66,45 @@ add_item msg, @inputs[i]\type!, args[i] socket\send msg.pack msg.content +send_arr = Constant.meta + meta: + name: 'send-arr' + summary: "Send an OSC message using arrays." + examples: { '(osc/send [socket] path val…)' } + description: "Sends an OSC message to `path` with `val…` as arguments. + +- `socket` should be a `udp/socket` value. This argument can be omitted and the + value be passed as a dynamic definition in `*sock*` instead. +- `path` is the OSC path to send the message to. It should be a string-value. +- the arguments can be any type: + - `num` will be sent as `f` + - `str` will be sent as `s` + - `bool` will be sent as `T`/`F` + - `bang` will be sent as `T` + - arrays will be sent as a series of values surrounded by `[…]` + - structs will be sent as a series of key (`s`)/value tuples surrounded by `[…]` + +This is a pure op, so between the values at most one !-stream input is allowed." + + value: class extends PureOp + pattern: any!^0 + + full_pattern = -sig['udp/socket'] + sig.str + any!^0 + setup: (inputs, scope) => + { socket, path, values } = full_pattern\match inputs + super values, scope, { + socket: Input.cold socket or scope\get '*sock*' + path: Input.cold path + } + + tick: => + args = @unwrap_all! + { :socket, :path } = args + msg = new_message path + for i=1,#args + add_item msg, @inputs[i]\type!, args[i], true + socket\send msg.pack msg.content + Constant.meta meta: name: 'osc'