Forums > MaxMSP

feature request (with prototype): overridable pv

April 15, 2007 | 7:53 pm

Hi,

As promised, here’s the prototype of the overridable pv object that I’ve been talking about lately on this list. It introduces a separate definition object that determines the scope of a variable, thus allowing for overriding.

These objects are 100% what I want them to be, except that they’re in javascript.

So, dear Cycling ’74, if there is any chance for you to make this a native max object, that would create a lot of possibilities.

Thanks,
Mattijs

All files a zip:

http://www.oli.tudelft.nl/avdl1064/overridable%20pv.zip

Alternatively:
—- save as MK.pv.pat

#P newex 17 43 57 196617 route bang;
#P newex 17 62 40 196617 t 0 b 1;
#P newex 17 134 29 196617 gate;
#P newex 32 112 133 196617 pattr value @autorestore 0;
#X prestore 1 0 0;
#P objectname value;
#P newex 122 90 158 196617 pattr checkName @autorestore 0;
#X prestore 1 0 0;
#P objectname checkName;
#P newex 241 43 108 196617 loadmess setName $1;
#P newex 103 65 46 196617 sel done;
#P newex 103 43 64 196617 patcherargs;
#N comlet (anything) value;
#P inlet 17 26 15 0;
#N comlet (anything) value;
#P outlet 17 154 15 0;
#P newex 170 43 68 196617 r defInitDone;
#P newex 51 90 62 196617 js MK.pv.js;
#P connect 0 1 7 0;
#P connect 7 0 0 1;
#P connect 5 0 0 1;
#P connect 4 1 5 0;
#P fasten 6 0 0 0 246 86 56 86;
#P fasten 1 0 0 0 175 86 56 86;
#P connect 8 0 9 1;
#P connect 11 1 8 0;
#P connect 0 0 8 0;
#P connect 10 1 8 0;
#P connect 9 0 2 0;
#P connect 10 0 9 0;
#P fasten 10 2 9 0 52 82 22 82;
#P connect 11 0 10 0;
#P connect 3 0 11 0;

—- save as MK.pvdef.pat

#P newex 91 110 149 196617 pattr pv_name @autorestore 0;
#X prestore 1 0 0;
#P objectname pv_name;
#P newex 76 154 150 196617 pattr pv_value @autorestore 0;
#X prestore 1 0 0;
#P objectname pv_value;
#P newex 61 67 40 196617 t b b b;
#P newex 61 177 76 196617 js MK.pvdef.js;
#P newex 91 89 30 196617 t $1;
#P newex 76 133 30 196617 t $2;
#P newex 61 46 46 196617 sel done;
#P newex 7 25 64 196617 patcherargs;
#P connect 3 0 7 0;
#P connect 5 2 3 0;
#P connect 2 0 6 0;
#P connect 5 1 2 0;
#P connect 5 0 4 0;
#P connect 1 0 5 0;
#P connect 0 1 1 0;

—- save as MK.pv.js

autowatch = 1;
inlets = 2;
outlets = 2;

toLoad = new Global("toLoad");

var pvName = null;
var patcherArgsDone = false;
var initDone = false;
var pattrReturn = null;

function setName(v)
{
pvName = v;
}

function bang()
{
if (inlet == 1) patcherArgsDone = true;
if (toLoad.done && patcherArgsDone && !initDone)
{
getLink(pvName);
initDone = true;
}
}

function getLink(name)
{
var path = searchUp(this.patcher, "", name);
if (path != null) outlet(0, "bindto", path);
else pst("error: Definition of " + name + " not found");
}

function searchUp(p, path, name) { //pst("searchUp: p " + p + ", path " + path + ", name " + name);
var def = null;
if (p != null) def = getDef(p, path, name);
else return null;

if(def != null) return "" + path + def + "::pv_value";
else return searchUp(p.parentpatcher, "parent::" + path, name);
}

function getDef(p, path, name)
{
var checkName = null;
var child = p.firstobject;
while (child != null)
{
if (child.maxclass == "patcher")
{
if (child.subpatcher().name == "MK.pvdef.pat") { //pst("opvdef.pat found. checking path " + path + child.varname + "::opv_name");
checkName = getPattr(path + child.varname + "::pv_name");
if (checkName == name) return child.varname;
}
}
child = child.nextobject;
}
return null;
}

function getPattr(path)
{
pattrReturn = null;
outlet(1, "bindto", path);
return pattrReturn;
}

function anything()
{
if (inlet == 1) pattrReturn = messagename;
}

function pst(v)
{
post(v + "n");
}

—- save as MK.pvdef.js

autowatch = 1;

toLoad = new Global("toLoad");
toLoad.amount = null;
toLoad.done = false;

function loadbang()
{
if (toLoad.amount != null) toLoad.amount++;
else toLoad.amount = 0;
}

function bang()
{
if (toLoad.amount == 0)
{
toLoad.done = true;
toLoad.message = "bang";
toLoad.sendnamed("defInitDone", "message");
}
else toLoad.amount–;
}

—- save as anything (has to be loaded to trigger loadbangs):

#P button 165 57 15 0;
#P comment 182 58 47 196617 get value;
#P flonum 165 113 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 177 75 27 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P comment 206 75 23 196617 set;
#P newex 165 93 63 196617 MK.pv juice;
#P objectname opv[1];
#P button 20 57 15 0;
#P comment 37 58 47 196617 get value;
#P flonum 20 113 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 32 75 27 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P comment 61 75 23 196617 set;
#N vpatcher 50 251 530 425;
#P button 16 60 15 0;
#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P comment 33 61 47 196617 get value;
#P flonum 16 116 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 28 78 27 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P comment 57 78 23 196617 set;
#P newex 16 96 62 196617 MK.pv fruit;
#P objectname opv[1];
#N vpatcher 56 454 218 582;
#P window setfont "Sans Serif" 9.;
#N vpatcher 49 625 435 785;
#P button 163 29 15 0;
#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P comment 180 30 47 196617 get value;
#P flonum 163 85 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 175 47 27 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P comment 204 47 23 196617 set;
#P newex 163 65 63 196617 MK.pv juice;
#P objectname opv[1];
#P button 18 29 15 0;
#P comment 35 30 47 196617 get value;
#P flonum 18 85 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 30 47 27 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P comment 59 47 23 196617 set;
#P newex 18 65 62 196617 MK.pv fruit;
#P objectname opv;
#P window linecount 2;
#P comment 34 106 247 196617 Same as current pv: variable is accessible from anywhere below its definition;
#P connect 3 0 1 0;
#P connect 6 0 1 0;
#P connect 1 0 4 0;
#P connect 9 0 7 0;
#P connect 12 0 7 0;
#P connect 7 0 10 0;
#P pop 1;
#P newobj 18 31 52 196617 p deepest;
#P objectname "sub patch";
#P pop 1;
#P newobj 390 62 48 196617 p deeper;
#P objectname deep;
#P newex 16 29 100 196617 MK.pvdef fruit 1.41;
#P objectname opvdef;
#P window linecount 2;
#P comment 122 30 227 196617 Definition determines scope , overriding variable ‘fruit’ defined in parent level;
#P connect 5 0 3 0;
#P connect 8 0 3 0;
#P connect 3 0 6 0;
#P pop 1;
#P newobj 306 34 38 196617 p deep;
#P objectname "pv’s inside";
#P newex 165 34 101 196617 MK.pvdef juice 3.14;
#P objectname opvdef[1];
#P newex 20 93 62 196617 MK.pv fruit;
#P objectname opv;
#P newex 20 30 100 196617 MK.pvdef fruit 1.62;
#P objectname opvdef;
#P connect 8 0 1 0;
#P connect 5 0 1 0;
#P connect 1 0 6 0;
#P connect 11 0 9 0;
#P connect 14 0 9 0;
#P connect 9 0 12 0;


April 16, 2007 | 6:26 pm

Am 15.04.2007 um 15:53 schrieb Mattijs Kneppers:

> These objects are 100% what I want them to be, except that they’re
> in javascript.

Why is this a disadvantage? They are cross-platform and customizable.

> So, dear Cycling ’74, if there is any chance for you to make this a
> native max object, that would create a lot of possibilities.

I would simply note that we do offer a C SDK to facilitate the
creation of custom objects by users. To be fair, some of the features
of Max which you are exploiting (I’m principally referring to pattr)
are neither fully documented nor available to 3rd party developers
(that is, writing an object which behaves like a pattr object is not
currently possible). I’m hoping to open that up to developers down
the road, but we’ve got other, more pressing concerns at the moment.

I guess that the short answer is, no time soon will this be written
by us. Stick with JS for now. If it works, it works!

Jeremy


April 17, 2007 | 8:47 am

Quote: Jeremy Bernstein wrote on Mon, 16 April 2007 20:26
—————————————————-
>
> Am 15.04.2007 um 15:53 schrieb Mattijs Kneppers:
>
> > These objects are 100% what I want them to be, except that they’re
> > in javascript.
>
> Why is this a disadvantage? They are cross-platform and customizable.

I understand your comment. Unfortunately, javascript still has a few issues when used heavily. I need this object essentially as a replacement for send/receive in a patch with currently around 700 send/receive pairs (I counted them with textwrangler :p).

I tried replacing all send/receives with these abstractions. But overall loading slowed down significantly, there were issues with load order and I got several crashes in js calls (I can send you the crash reports if you want).

So I am afraid that I can’t use these objects in practice..

>
> > So, dear Cycling ’74, if there is any chance for you to make this a
> > native max object, that would create a lot of possibilities.
>

.. which I guess explains my request a little better.

> I would simply note that we do offer a C SDK to facilitate the
> creation of custom objects by users. To be fair, some of the features
> of Max which you are exploiting (I’m principally referring to pattr)
> are neither fully documented nor available to 3rd party developers
> (that is, writing an object which behaves like a pattr object is not
> currently possible).
> I’m hoping to open that up to developers down
> the road, but we’ve got other, more pressing concerns at the moment.

Yeah, some load order and pattr hacks were necessary to make this work. I would be doing this in C if it was possible..

>
> I guess that the short answer is, no time soon will this be written
> by us.

Ok, I understand, that’s a pity.

> Stick with JS for now. If it works, it works!

Unfortunately this is not always the case..

Appreciate your reply, of course.

Thanks,
Mattijs

>
> Jeremy
>
>
>
—————————————————-


April 17, 2007 | 9:04 am

Hi, I hear that there can be a problem if js names are the same as abstraction names. Here is a version where js names are different from the abstraction names.

http://www.oli.tudelft.nl/avdl1064/overridable-pv-(jsnames-changed).zip

Furthermore I recommend using this link to download instead of copy-pasting from your browser. It appears that when you paste the js objects without having the javascript files in your search path, the js objects init with only 1 in-/oulet instead of making a bogus object that retains in/outlet connections. This corrupts one of the abstractions.

I’d say this is another feature request: js object should retain connections if a js object is pasted or opened but the file is not found.
Cheers,
Mattijs


Viewing 4 posts - 1 through 4 (of 4 total)