support args for osc.message.create

This commit is contained in:
Joel Wetzell
2025-11-24 17:33:18 -06:00
parent 0c9f793a30
commit dd061b375a

View File

@@ -3,7 +3,9 @@ package processing
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/hex"
"fmt" "fmt"
"strconv"
"text/template" "text/template"
"github.com/jwetzell/osc-go" "github.com/jwetzell/osc-go"
@@ -12,6 +14,8 @@ import (
type OSCMessageCreate struct { type OSCMessageCreate struct {
config ProcessorConfig config ProcessorConfig
Address *template.Template Address *template.Template
Args []*template.Template
Types string
} }
func (o *OSCMessageCreate) Process(ctx context.Context, payload any) (any, error) { func (o *OSCMessageCreate) Process(ctx context.Context, payload any) (any, error) {
@@ -37,6 +41,31 @@ func (o *OSCMessageCreate) Process(ctx context.Context, payload any) (any, error
Address: addressString, Address: addressString,
} }
args := []osc.OSCArg{}
for argIndex, argTemplate := range o.Args {
var argBuffer bytes.Buffer
err := argTemplate.Execute(&argBuffer, payload)
if err != nil {
return nil, err
}
argString := argBuffer.String()
typedArg, err := argToTypedArg(argString, o.Types[argIndex])
if err != nil {
return nil, err
}
args = append(args, typedArg)
}
if len(args) > 0 {
payloadMessage.Args = args
}
return payloadMessage, nil return payloadMessage, nil
} }
@@ -67,7 +96,123 @@ func init() {
return nil, err return nil, err
} }
args, ok := params["args"]
if ok {
rawArgs, ok := args.([]interface{})
if !ok {
return nil, fmt.Errorf("osc.message.create address must be an array found %T", args)
}
types, ok := params["types"]
if !ok {
return nil, fmt.Errorf("osc.message.create requires a types parameter with args")
}
typesString, ok := types.(string)
if !ok {
return nil, fmt.Errorf("osc.message.create types must be a string")
}
if len(rawArgs) != len(typesString) {
return nil, fmt.Errorf("osc.message.create args and types must be the same length")
}
argTemplates := []*template.Template{}
for _, rawArg := range rawArgs {
argString, ok := rawArg.(string)
if !ok {
return nil, fmt.Errorf("osc.message.create arg must be a string")
}
argTemplate, err := template.New("arg").Parse(argString)
if err != nil {
return nil, err
}
argTemplates = append(argTemplates, argTemplate)
}
return &OSCMessageCreate{config: config, Address: addressTemplate, Args: argTemplates, Types: typesString}, nil
}
return &OSCMessageCreate{config: config, Address: addressTemplate}, nil return &OSCMessageCreate{config: config, Address: addressTemplate}, nil
}, },
}) })
} }
func argToTypedArg(rawArg string, oscType byte) (osc.OSCArg, error) {
switch oscType {
case 's':
return osc.OSCArg{
Value: rawArg,
Type: "s",
}, nil
case 'i':
number, err := strconv.ParseInt(rawArg, 10, 32)
if err != nil {
return osc.OSCArg{}, err
}
return osc.OSCArg{
Value: int32(number),
Type: "i",
}, nil
case 'f':
number, err := strconv.ParseFloat(rawArg, 32)
if err != nil {
return osc.OSCArg{}, err
}
return osc.OSCArg{
Value: float32(number),
Type: "f",
}, nil
case 'b':
data, err := hex.DecodeString(rawArg)
if err != nil {
return osc.OSCArg{}, err
}
return osc.OSCArg{
Value: data,
Type: "b",
}, nil
case 'h':
number, err := strconv.ParseInt(rawArg, 10, 64)
if err != nil {
return osc.OSCArg{}, err
}
return osc.OSCArg{
Value: int64(number),
Type: "h",
}, nil
case 'd':
number, err := strconv.ParseFloat(rawArg, 64)
if err != nil {
return osc.OSCArg{}, err
}
return osc.OSCArg{
Value: float64(number),
Type: "d",
}, nil
case 'T':
return osc.OSCArg{
Value: true,
Type: "T",
}, nil
case 'F':
return osc.OSCArg{
Value: false,
Type: "F",
}, nil
case 'N':
return osc.OSCArg{
Value: nil,
Type: "N",
}, nil
default:
return osc.OSCArg{}, fmt.Errorf("osc.message.create unhandled osc type: %c", oscType)
}
}