retrieve patcher heirarchy from pattr?

johnpitcairn's icon

Is there a pattr-family object that can output a message corresponding to the patcher heirarchy it finds itself in?

Say the pattr object is in a patcher named "L3", which is in an abstraction named "L2", which is in a patcher named "L1" - can that pattr object be persuaded to output something like "L1::L2::L3"?

Jeremy's icon

Nope, you'd need to use javascript to do this, probably.

jb

Am 10.04.2007 um 00:40 schrieb John Pitcairn:

>
> Is there a pattr-family object that can output a message
> corresponding to the patcher heirarchy it finds itself in?
>
> Say the pattr object is in a patcher named "L3", which is in an
> abstraction named "L2", which is in a patcher named "L1" - can that
> pattr object be persuaded to output something like "L1::L2::L3"?
>
>

johnpitcairn's icon

Quote: Jeremy Bernstein wrote on Wed, 11 April 2007 01:16
----------------------------------------------------
> Nope, you'd need to use javascript to do this, probably.

Rats. That's what I'm doing.

Feature request for one of the pattr objects?

Mattijs's icon

Quote: johnpitcairn wrote on Wed, 11 April 2007 00:13
----------------------------------------------------
> Quote: Jeremy Bernstein wrote on Wed, 11 April 2007 01:16
> ----------------------------------------------------
> > Nope, you'd need to use javascript to do this, probably.
>
> Rats. That's what I'm doing.
>
> Feature request for one of the pattr objects?
>
----------------------------------------------------

Good idea.

Mattijs

Jeremy's icon

So, explain to me how that would work. The object would know what
object you wanted to know about, and tell you its path? pattrvoyant,
I suppose?

>8 >8 >8 >8 >8 save as pattrvoyant.js >8 >8 >8 >8 >8

autowatch = 1;

var n = "";

function list(x, y)
{
    var p = max.frontpatcher;
    var w = p.wind;
    var o = p.firstobject;

    x -= p.wind.location[0];
    y -= p.wind.location[1];
    while (o) {
        r = o.rect;
        if (x >= o.rect[0] &&
            x
            y >= o.rect[1] &&
            y
        {
            n = o.varname;
            if (n) {
                post(getfullname(p, n),"n");
                return;
            }
        }
        o = o.nextobject;
    }
    post("nothing foundn")
}

function getfullname(p, n)
{
    if (!p) {
        return n;
    }
    var o = p.box;

    if (!o) {
        return n;
    }
    if (!o.varname) {
        post("parent patcher of", n, "has no namen");
        return "";
    } else {
        n = o.varname + "::" + n;
        return getfullname(p.parentpatcher, n);
    }
}

>8 >8 >8 >8 >8 save as pattrvoyant.pat >8 >8 >8 >8 >8

Max Patch
Copy patch and select New From Clipboard in Max.

jb

Am 11.04.2007 um 12:18 schrieb Mattijs Kneppers:

>> Feature request for one of the pattr objects?
>>
> ----------------------------------------------------
>
> Good idea.

Emmanuel Jourdan's icon

On 11 avr. 07, at 15:23, Jeremy Bernstein wrote:

> So, explain to me how that would work. The object would know what
> object you wanted to know about, and tell you its path?
> pattrvoyant, I suppose?

Can't you just use a crystal ball instead? ;-)

ej

Mattijs's icon

Um, no, sorry this is not what I had in mind.

I don't know about john, but I thought more like this:

--- save as "getpath.js":

autowatch = 1;

function bang()
{
    outlet(0, getPath(patcher, "top"));
}

function getPath(p, path)
{
    if(p.parentpatcher != null)
    {
        path += "." + p.box.varname;
        return getPath(p.parentpatcher, path);
    }
    else return path;
}

--- save as anything:

#N vpatcher 208 60 420 204;
#P window setfont "Sans Serif" 9.;
#N vpatcher 423 56 586 188;
#P window setfont "Sans Serif" 9.;
#P newex 30 74 32 196617 print;
#P button 30 30 15 0;
#P newex 30 50 67 196617 js getpath.js;
#P comment 47 30 46 196617 get path;
#P connect 2 0 1 0;
#P connect 1 0 3 0;
#P pop 1;
#P newobj 50 50 38 196617 p dank;
#P objectname dank;
#P pop 1;
#P newobj 25 42 38 196617 p sank;
#P objectname sank

Btw, while trying your patch, Jeremy, I got another js crash. I can't depend on js for permanent solutions. For these core issues, that makes me fully dependant on the option that Cycling 74 accepts my js prototype and incorporates it in max as a standard feature.. :/

Mattijs

Quote: Jeremy Bernstein wrote on Wed, 11 April 2007 15:23
----------------------------------------------------
> So, explain to me how that would work. The object would know what
> object you wanted to know about, and tell you its path? pattrvoyant,
> I suppose?
>

johnpitcairn's icon

Yeah, that sort of thing, just retrieve the parent patcher's scripting name all the way up the heirarchy, concatenate those using a specified delimiter (either :: or .). The purpose being to use that as a unique source-name for a receive object, ie

[loadmess path]
|
[pattrpath]
|
[prepend set]
|
[receive]

This assumes that the parent patchers already have names.

But: I also want to auto-name the parent patcher object based on an attribute argument supplied to the patcher (not the js) - the innermost js in the heirarchy will fire first when triggered by [patcherargs], and js objects higher up won't yet have auto-named their patchers. So you need to register appropriate callbacks to "child" js objects and notify those when a full top-down path is available. OK, but requires an appropriate js in each patcher/abstraction at each level of the heirarchy.

So I'd thought that maybe pattr could be persuaded to handle this with less hassle - but I guess there would still be load-order problems if I want to name the containing patcher based on an attribute argument to it (NOT just pattr's default auto-name)?

The idea being that you specify a patcher or abstraction as:

[p @name test] or [abstraction @name test]

Then the object gets named "test" automatically, preventing duplicate names within that scope (throws error in Max window when duplicated), and the js or pattr within will provide a full top-down "name::name::name" for use within the patcher.

johnpitcairn's icon

Uh, make that "auto name a receive object" using the patcher heirarchy. But I'm (possibly) no longer pursuing that course of inquiry...

Mattijs's icon

Quote: johnpitcairn wrote on Thu, 12 April 2007 02:52
----------------------------------------------------
> Yeah, that sort of thing, just retrieve the parent patcher's scripting name all the way up the heirarchy, concatenate those using a specified delimiter (either :: or .). The purpose being to use that as a unique source-name for a receive object, ie
>
> [loadmess path]
> |
> [pattrpath]
> |
> [prepend set]
> |
> [receive]
>
> This assumes that the parent patchers already have names.
>
> But: I also want to auto-name the parent patcher object based on an attribute argument supplied to the patcher (not the js) - the innermost js in the heirarchy will fire first when triggered by [patcherargs], and js objects higher up won't yet have auto-named their patchers. So you need to register appropriate callbacks to "child" js objects and notify those when a full top-down path is available. OK, but requires an appropriate js in each patcher/abstraction at each level of the heirarchy.

You are starting to run into the loading order gap I ran into earlier.. it is nasty. What you can do is use [loadbang] to trigger a js that names the containing patcher and then use [patcherargs] to trigger a js that names the receives. Since all loadbangs fire before patcherargs this will guarantee a full top-down patch before you get to the receives.

I've already made scripts that name their containing patcher according to an argument or attribute, let me know if you'd like to have them.

About the loading order problem: I would totally dig an integer argument to loadbang that specifies which series of loadbangs fire before others. Why not use one central loadbang and [t b b b] to some receives? Because this requires you to restart your entire patch when you insert one abstraction. I made a prototype of this loadbang-with-argument and I'll try to post it as a feature request somewhere soon.

Mattijs

>
> So I'd thought that maybe pattr could be persuaded to handle this with less hassle - but I guess there would still be load-order problems if I want to name the containing patcher based on an attribute argument to it (NOT just pattr's default auto-name)?
>
> The idea being that you specify a patcher or abstraction as:
>
> [p @name test] or [abstraction @name test]
>
> Then the object gets named "test" automatically, preventing duplicate names within that scope (throws error in Max window when duplicated), and the js or pattr within will provide a full top-down "name::name::name" for use within the patcher.
>
>
>
----------------------------------------------------

Mattijs's icon

At a second view, Jeremy, it appears that the script I posted is similar to yours, apart from the mouse handling. I was confused by the mouse handling part, which I figured had nothing to do with john's idea at a first glance.

You must have misunderstood johns intentions, he wasn't looking for a way to get info about the path to the user but to the patch. Nonetheless it's a nice script :)

Mattijs

Quote: Jeremy Bernstein wrote on Wed, 11 April 2007 15:23
----------------------------------------------------
> So, explain to me how that would work. The object would know what
> object you wanted to know about, and tell you its path? pattrvoyant,
> I suppose?
>
> >8 >8 >8 >8 >8 save as pattrvoyant.js >8 >8 >8 >8 >8
>
> autowatch = 1;
>
> var n = "";
>
> function list(x, y)
> {
>     var p = max.frontpatcher;
>     var w = p.wind;
>     var o = p.firstobject;
>
>     x -= p.wind.location[0];
>     y -= p.wind.location[1];
>     while (o) {
>         r = o.rect;
>         if (x >= o.rect[0] &&
>             x
>             y >= o.rect[1] &&
>             y
>         {
>             n = o.varname;
>             if (n) {
>                 post(getfullname(p, n),"n");
>                 return;
>             }
>         }
>         o = o.nextobject;
>     }
>     post("nothing foundn")
> }
>
> function getfullname(p, n)
> {
>     if (!p) {
>         return n;
>     }
>     var o = p.box;
>
>     if (!o) {
>         return n;
>     }
>     if (!o.varname) {
>         post("parent patcher of", n, "has no namen");
>         return "";
>     } else {
>         n = o.varname + "::" + n;
>         return getfullname(p.parentpatcher, n);
>     }
> }
>
> >8 >8 >8 >8 >8 save as pattrvoyant.pat >8 >8 >8 >8 >8
>
> max v2;
> #N vpatcher 10 59 610 459;
> #P window setfont "Sans Serif" 9.;
> #N vpatcher 20 74 620 474;
> #P window setfont "Sans Serif" 9.;
> #N vpatcher 24 260 624 660;
> #P window setfont "Sans Serif" 9.;
> #P flonum 210 146 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
> #P objectname wank;
> #P pop;
> #P newobj 303 157 41 196617 p clank;
> #P objectname clank;
> #N vpatcher 30 89 630 489;
> #P window setfont "Sans Serif" 9.;
> #P number 259 124 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
> #P objectname flank;
> #P pop;
> #P newobj 236 155 41 196617 p blank;
> #P number 234 101 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
> #P objectname slank;
> #P pop;
> #P newobj 348 162 42 196617 p stank;
> #P objectname stank;
> #P number 350 94 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
> #P objectname swank;
> #P toggle 107 105 15 0;
> #P newex 107 127 52 196617 metro 20;
> #P newex 107 213 36 196617 zl reg;
> #P newex 143 185 48 196617 pack 0 0;
> #P newex 107 185 32 196617 sel 1;
> #P newex 107 159 66 196617 mousestate;
> #P newex 107 260 88 196617 js pattrvoyant.js;
> #P connect 6 0 5 0;
> #P connect 5 0 1 0;
> #P connect 1 0 2 0;
> #P connect 2 0 4 0;
> #P connect 4 0 0 0;
> #P connect 3 0 4 1;
> #P connect 1 1 3 0;
> #P connect 1 2 3 1;
> #P pop;
>
>
> jb
>
> Am 11.04.2007 um 12:18 schrieb Mattijs Kneppers:
>
> >> Feature request for one of the pattr objects?
> >>
> > ----------------------------------------------------
> >
> > Good idea.
>
>
----------------------------------------------------

Jeremy's icon

Getting info about the path to the patch is a matter of exchanging a
post() call with an outlet() call. I figured that the savvy user
would get the idea.

jb

Am 12.04.2007 um 11:07 schrieb Mattijs Kneppers:

> You must have misunderstood johns intentions, he wasn't looking for
> a way to get info about the path to the user but to the patch.
> Nonetheless it's a nice script :)

Mattijs's icon

Well, a patch won't need the mouse part either, only a bang input, which was confusing at start.

Mattijs

Quote: Jeremy Bernstein wrote on Thu, 12 April 2007 11:32
----------------------------------------------------
> Getting info about the path to the patch is a matter of exchanging a
> post() call with an outlet() call. I figured that the savvy user
> would get the idea.
>
> jb
>
> Am 12.04.2007 um 11:07 schrieb Mattijs Kneppers:
>
> > You must have misunderstood johns intentions, he wasn't looking for
> > a way to get info about the path to the user but to the patch.
> > Nonetheless it's a nice script :)
>
>
----------------------------------------------------

johnpitcairn's icon

Quote: Mattijs wrote on Thu, 12 April 2007 20:51
----------------------------------------------------
> You are starting to run into the loading order gap I ran into
> earlier.. it is nasty. What you can do is use [loadbang] to
> trigger a js that names the containing patcher and then use
> [patcherargs] to trigger a js that names the receives. Since
> all loadbangs fire before patcherargs this will guarantee a
> full top-down patch before you get to the receives.

OK, but I want to name the patcher based on an attribute argument, so it would need to be:

[loadbang]
|
[patcherargs]
|
[js]

Then make the js traverse the heirarchy and name the receive on the second pass (when patcherargs fires by itself). And don't connect anything else to the patcherargs object...

We're assuming the loadbang/patcherargs firing order is reliable and won't change in future - and given the lack of specific documentation, I'm not so sure.

I'll take another look at it, though a [pattrpath] object (or "getpath" message to some pattr object) would sure be preferable...

Mattijs's icon

Quote: johnpitcairn wrote on Fri, 13 April 2007 07:54
----------------------------------------------------
> I'll take another look at it, though a [pattrpath] object (or "getpath" message to some pattr object) would sure be preferable...

But you can make a [pattrpath] with js now. Js is clearly not stable enough for intensive use, but it could serve as a temporary solution, right?

Mattijs

>
>
>
----------------------------------------------------

Jeremy's icon

Exactly my point.

jb

Am 13.04.2007 um 10:16 schrieb Mattijs Kneppers:

> But you can make a [pattrpath] with js now. Js is clearly not
> stable enough for intensive use, but it could serve as a temporary
> solution, right?