Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplifying send() function #219

Open
SeanBannister opened this issue Dec 4, 2024 · 2 comments
Open

Simplifying send() function #219

SeanBannister opened this issue Dec 4, 2024 · 2 comments

Comments

@SeanBannister
Copy link

SeanBannister commented Dec 4, 2024

I recently settled on this library, thanks for writing it! In the process I tested two other JS based OSC libraries and really enjoyed the simplicity of their send functions. I've included some code below where I've replicated this functionality and wanted to share it here in case anyone else finds it useful, or maybe it could be incorporated into the project:

This allows you to send an OSC message with a simple:
transmit('/address')
It also auto detects the type of arguments which i noticed the other JS libraries do, so you can specify and argument like:
transmit('/address', 'arg')
And it knows its a string.

But you can still manually specify types:
transmit('/address', { type: 'r', value: { r: 0, g: 255, b: 255, a: 1.0 }))

And you can still do bundles:

transmit(
  ['/address1'],
  ['/address2', 'arg'],
  ['/address3', { type: 'r',  value: { r: 0, g: 255, b: 255, a: 1.0 }]
);

And still supports multiple args:
transmit('/address', 'arg1', 'arg2')

I'm writing 100s of OSC sends in my code and this has really made it much easier to maintain.

For my use case I didn't need Time Tags so that would need to be added if this was used in the project, I also only setup auto detecting floats (f), integers (i), and strings (s).

function transmit(...args) {
  // Convert single message to array format
  const messages = Array.isArray(args[0]) ? args : [args];
  
  // Helper to determine type
  const getType = (value) => {
    if (typeof value === 'number') return Number.isInteger(value) ? 'i' : 'f';
    if (typeof value === 'string') return 's';
    return value.type;
  };

  // Helper to format arg
  const formatArg = (arg) => {
    if (arg && arg.type) return arg;
    return { type: getType(arg), value: arg };
  };

  // Format packets
  const packets = messages.map(([address, ...args]) => ({
    address,
    args: args.length ? args.map(formatArg) : undefined
  }));

  osc.send({
    timeTag: OSC.timeTag(0),
    packets
  });
}
@colinbdclark
Copy link
Owner

Hey, thanks for sharing this helper function! It looks nice and compact for cases where you're sending lots of small messages of different types in a bundle. In some ways, this is closer to the low-level representation of an OSC message, so it's something I might be able to provide in the API with the side effect of some additional memory-usage benefits too.

Just as a note, osc.js does support argument type inference if you set the metadata option to false. That implementation is also exposed in the low-level API as osc.inferTypeForArgument. So I think you could swap it for your getType() function, or just change your Port to not use metadata if you wanted to.

This looks great, thanks again for sharing it!

@SeanBannister
Copy link
Author

Oh I totally missed that type inference was included. Awesome thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants