I developed a system in VVVV that I’m now in the process of converting to VL (which I am new to) so as to be able to use custom datatypes and other OOP concepts. I watched many tutorial videos and read what documentation there is on VL but I have some questions as to best practices.
My patch starts with receiving OSC messages over UDP. The messages are essentially note data from different instruments, each with their own OSC address. In my VVVV prototype, this is done like so:
Simple and works, but I hate that I have to have a static number of outputs set. When/if I want to change the instruments, it’s quite tedious and error-prone making all the changes all the places.
Enter VL. I want to follow the approach I’d take in C#/C++: create a type called Instrument that contains some properties (like the OSC address) as well as other custom types. I would then build VL operations that I’d use in VVVV to harness the power of Spreading over my types and so on. In this case, I made an operation called FromOSC to decode the OSC data and process it to get a spread of Instrument objects that contain NoteGroups that contain Notes.
After making my types, as well as Join / Split operations (scaffolding to do this automatically would be smart), I would up with this:
…which is in turn called like this:
This is doing what I want it to. But I have some questions:
- ToOSCMessages takes a
Spread<byte>. I am using AsValue (Raw) to get this from the UDP output. Is there a better way?
- I still do not understand exactly what the ♦ symbol does in a the context of a loop. What is it called/used for and is it explained anywhere in documentation? My best guess is that it makes an object immutable for that region.
- The links from Match to IsEmpty and the ForEach spreader are called out with “The transported value is mutable…” Is there a better pattern to do an evaluation while also then passing through to a loop the object that’s evaluated?
- Same thing with the OSCMessage Split -> GetSlice section. In practice this seems to work but is there a better way? Is there, for example, a Using region that’d make the value immutable within it?
- My Note object is strongly typed (I’d like to be able to use it within VVVV), therefore I had to do CastAs. This seems hella janky. What’s the right way to do it?
- I want the ForEach to return only NoteGroups with values (Match is not empty). I had to add “Keep” to the ForEach to accomplish this. I thought the If region would do this by itself, as NoteGroup (Join) is within that region, but that does not seem to work; without Keep, 3 objects (one for each Instrument) are always returned, rather than only the ones which match the If condition.
I have two additional comments on VL generally, as a new user:
- Scaffolding to create join/split operations automatically would be a big help.
- I like that I can right click and “Open” any built-in VL object in the VL editor (for example, right-click ToOSCMessages and you are taken to the OSCUtils group). But these should really be read-only. I would hate to accidentally make a change to a library when hitting “save all” during quitting, for example.
Thank you in advance and I hope this is helpful!