Local send and receive solution (please comment)

Thomas FREDERICKS's icon

Hi, I have looking for a local send receive solution in Max for sending render bangs, but only inside the local patcher hierarchy. Here is a proposed solution that uses the root patcher name. A [tof.psend destination] will send any message to any [tof.preceive destination] that shares the same root patcher! FINALLY!

What do you think of my proposed solution? The names for the internal sends and receives are created as follows : rootpatchername_destination. Do you think that such long symbol slow down send and receive?

All of this would be moot if Cycling '74 just had a special symbol for referring to the root patcher. It so annoying to have to name everything and having to resolve name conflicts because everything is global...

psend and preceive example 2.maxpat
text/plain 6.08 KB

psend and preceive example.maxpat
text/plain 6.08 KB

psend_abstraction.maxpat
text/plain 2.75 KB

tof.preceive.maxpat
text/plain 5.06 KB

tof.psend.maxpat
text/plain 5.06 KB

tof.rootpatchername.js
application/x-javascript 0.44 KB

Thomas FREDERICKS's icon

Here are the same files in a zip

local send receive example.zip
application/x-zip-compressed 6.94 KB

tyler mazaika's icon

So... just making sure that in your use using #0 for patcher-specific variable is not a viable solution? (It may involve passing the top-level #0 value into abstractions as an argument)

Otherwise your approach seems fine. I'd simplify your subpatcher addressing code by putting a loadbang() in your js and doing the string concat (combine and set objects) in the JS too, just to cut down on objects.

You could conceivably use a single javascript this.patcher.applydeepif() call from the top level patcher with no special abstractions. But you would need to hack some other attribute of the forward/receive objects you wanted to target (like by stuffing the desired symbol suffix in the varname and then parsing the varname for the target symbol).

I don't _think_ there's a way to read the typed in argument string to the receive/forward objects in JS. Otherwise that could avoid the ugly varname hack. "hint" might be a better attribute for the symbol... but its still a hack.

tyler mazaika's icon
It would look something like this.  Code is untested...

function bang() {
    var p = this.patcher
    var patchername = this.patcher.getattr("globalpatchername")
    p.applydeepif(
        function(maxobj) {
            var address = patchername+"-"+maxobj.getattr("hint")
            if (maxobj.maxclass == "receive") {
                maxobj.message("set", address)
            } else {
                // then forward
                maxobj.message("send", address)
            }
        },
        function(maxobj) {
            // Make sure its a receive or forward object with a non-null hint (which will double to form the address)
            return (maxobj.maxclass=="receive"||maxobj.maxclass=="forward") && maxobj.getattr("hint")
        }
    )
}

function loadbang() {
    bang()
}

Andy Maskell's icon

I've been asking for a true hierarchical subroutine/function style of some sort in Max for a while now, where things inside the subroutine are local to just that subroutine. I find the "global everywhere" style in Max quite taxing at times.

Thomas FREDERICKS's icon

So... just making sure that in your use using #0 for patcher-specific variable is not a viable solution? (It may involve passing the top-level #0 value into abstractions as an argument)

Yes. But the root patcher does not have a #0 value. And the only way to share the #0 value is to write it as an argument to children objects. The goal is to avoid having to write "bogus" names to simulate a local namespace.
The problem is obvious with the way Vizzie needs a special vzgl-context object running the vizzie-global.js code.
The problem is even worse when you use something like Vsynth when you can't open two patchers without having a conflict :(
In my implementation, I tried to use more Max objects than JavaScript code as JavaScript tends to be much slower...

tyler mazaika's icon

If you're just running the JS code at load time the deferred nature of JS won't have any impact. In any event I think this is a pretty clean and light-as-possible solution. Similar to what I described above, but making a trivial wrapper abstraction around the [forward] [receive] objects so that you can use the #1 argument as the varname of the [forward] / [receive] and still potentially have multiple instances within the same patch level. Then read that varname back from js and concatenate as proposed above.

varname of the forward and receive objects in pLocal.forward is #1

PatcherLocalSends.zip
application/zip 9.59 KB

tyler mazaika's icon

Funny semi-related story... a while back I was at a Max meetup and showed some patch with a [send+] object in it. And Sam T. from cycling was like "Oh, I don't think I've ever seen that object before". [send+] was just my abstraction to delete and recreate a [send] with a different target because I didn't know that [forward] existed.

Thomas FREDERICKS's icon

Thank you for sharing @Tyler Mazaika. Nice implementation!

Please @Cycling '74 give us a #p or similar symbol that is similar to #0 but is the root patcher's unique number!