Forums > Javascript

another [coll] to [pattr] js

November 21, 2010 | 11:49 am

It works by living in between [pattr] and [coll]. You can send it any command you would send a [coll] except for "delete", which is a reserved internal js function name (use "del" instead, it will forward the proper command to the [coll] it is connected to). It updates the pattr with the new coll every time it receives one of the messages it understands. There is a list of functions which it merely passes on to the coll, without making any changes in its internal structuring of the data. It is also capable of retrieving the information directly from [coll] if the two are connected properly. The first, second, and fourth outlets of the [coll] must be connected to the second, third and fourth inlets of [js coll_pattr.js] for [coll] to send its data to the [pattr]. The function "collect" will read the current data from the [coll] object.

If there is no need for collecting data from the [coll], then its only necessary to connect the output of the javascript to the input of the [coll] and send any message you would send to [coll] to the input of the javascript. As long as a [pattr] is connected to the first inlet of the javascript, and has "parameter mode" enabled, it will function nearly identically to the [coll] downstream from it and will store nearly identical data in the [pattr].

"Nearly"…what does that mean? I don’t know yet. Some ordering will probably get lost….time will tell. Check it out.

autowatch=1;

inlets=5;

setinletassist(0, "pattr bind and incoming messages to coll");
setinletassist(1, "receives output from first inlet of bound coll");
setinletassist(2, "receives output from second inlet of bound coll");
setinletassist(3, "receives output from third and fourth inlet of bound coll");
setinletassist(4, "receives output from freebang object");
setoutletassist(0, "messages to bound coll");

var reg=0;
var data;
var new_data=[];
var coll=[];
var thru=["assoc", "deassoc", "dump", "end", "goto", "filetype", "flags", "length", "next", "max", "nth", "min", "prev", "open", "start", "store", "subsym", "read", "readagain", "refer", "wclose", "write", "writeagain"];

function collect()
{
coll=[];
outlet(0, "dump");
}

function clear()
{
coll=[];
notifyclients();
outlet(0, "clear");
}

function del(num)
{
var args=arrayfromargs(arguments);
for(var i in coll)
{
if(coll[i][0]==num)
{
coll.splice(i,1);
}
if(typeof coll[i][0]=="number")
{
if(coll[i][0]>num)
{
coll[i][0]=coll[i][0]-1;
}
}
}
notifyclients();
outlet(0, "delete", args);
}

function insert()
{
var args=arrayfromargs(arguments);
var num=args[0];
for(var i in coll)
{
if((coll[i][0]>=num)&&(typeof coll[i][0]=="number"))
{
coll[i][0]=coll[i][0]+1;
}
}
var proc=0;
for(var j in coll)
{
if((coll[j][0]>=args[0])&&(proc==0))
{
coll.splice(j,0,args)
proc=1;
}
}
outlet(0, "insert", args);
notifyclients();
}

function nstore()
{
var args=arrayfromargs(arguments);
var new_args=[];
for(var i in args)
{
if(i!=1)
{
new_args.push(args[i])
}
}
store_to_coll(new_args);
outlet(0, "nstore", args);
}

function merge()
{
var args=arrayfromargs(arguments);
for(var i in coll)
{
if(coll[i][0]==args[0])
{
for(var j in args)
{
coll[i].push(args[j]);
}
}
}
notifyclients();
outlet(0, "merge", args);
}

function nsub()
{
var args=arrayfromargs(arguments);
for(var i in coll)
{
if(coll[i][0]==args[0])
{
coll[i][args[1]]=args[2];
}
}
notifyclients();
outlet(0, "nsub", args);
}

function seperate(args)
{
for(var i in coll)
{
if((coll[i][0]>=args)&&(typeof coll[i][0]=="number"))
{
coll[i][0]++;
}
}
notifyclients();
outlet(0, "seperate", args);
}

function sort()
{
args=arrayfromargs(arguments);
outlet(0, "sort");
outlet(0, "dump");
}

function store()
{
var args = arrayfromargs(arguments);
store_to_coll(args);
notifyclients();
outlet(0, "store", args);
}

function swap(a, b)
{
var coll_a;
var coll_b;
for(var i in coll)
{
if(coll[i][0]==a)
{
coll_a=parseInt(i);
}
if(coll[i][0]==b)
{
coll_b=parseInt(i);
}
}
if((coll_a!=undefined)&&(coll_b!=undefined))
{
coll[coll_a][0]=b;
coll[coll_b][0]=a;
}
notifyclients();
outlet(0, "swap", a, b);
}

function renumber()
{
var new_num=0;
for(var i in coll)
{
if(typeof coll[i][0]=="number")
{
coll[i][0]=new_num;
new_num++;
}
}
notifyclients();
outlet(0, "renumber");
}

function renumber2()
{
for(var i in coll)
{
if(typeof coll[i][0]=="number")
{
coll[i][0]=coll[i][0]+1;
}
}
notifyclients();
outlet(0, "renumber2");
}

function remove(arg)
{
for(var i in coll)
{
if(coll[i][0]==arg)
{
coll.splice(i,1);
}
}
notifyclients();
outlet(0, "remove", arg);
}

function anything(num)
{
var args = arrayfromargs(arguments);
switch(inlet)
{
case 0:
store_to_coll(args);
outlet(0, args);
break;
case 2:
reg=num;
break;
case 1:
var args_out=[];
args_out.push(reg);
for(var i in args)
{
args_out.push(args[i]);
}
store_to_coll(args_out);
break;
}
}

function store_to_coll(args)
{
var proc=0;
for(var t in thru)
{
if(args[0]==thru[t])
{
proc=1;
}
}
if(proc==0)
{
var add=1;
if(coll.length>0)
{
for(var i in coll)
{
if(coll[i][0]==args[0])
{
coll[i]=args;
add=0;
}
}
}
if(add>0)
{
coll.push(args);
}
notifyclients();
}
}

function getvalueof()
{
mux();
return new_data;
}

function setvalueof()
{
args=arrayfromargs(arguments);
outlet(0, "clear");
var temp=[];
for(var i in args)
{
if(args[i]=="^")
{
if(i>0)
{
coll.push(temp);
if(typeof temp[0]!="number")
{
temp.unshift("store");
}
outlet(0, temp);
temp=[];
}
}
else
{
temp.push(args[i]);
}
}
}

function bang()
{
switch(inlet)
{
case 0:
outlet(0, "bang");
case 3:
mux();
notifyclients();
break;
case 4:
mux();
notifyclients();
break;
}
}

function mux()
{
new_data=[]
for(var i in coll)
{
new_data.push("^");
for(var j in coll[i])
{
new_data.push(coll[i][j]);
}
}
new_data.push("^");
}

function sortNumber(a,b)
{
return a – b;
}

– Pasted Max Patch, click to expand. –

November 22, 2010 | 6:40 am

hey, i checked it, i’m not sure what you mean with "If there is no need for collecting data from the [coll]".
do you mean if everything inside the coll came trough the script i don’t need the extra inlets?
and "collect" replaces the dump of the coll to a
pattr useable object (my old way)?

this is a more elegant way, without disput. but is it faster then dumping
the coll content to a textedit ?

regards
o.


November 22, 2010 | 7:49 pm

Exactly: if all the data in the [coll] was input through the js, there is no need for the outlets of the [coll] to be connected to the js (except for one case: sort).

"collect" replaces the contents of the [pattr] with the current data in the [coll]. So for instance, say you edit the [coll] via text edit, or you are adding a new [coll] file to a project and want to get its contents into the [pattr], you would use "collect" to get the current data. "dump" would do the same thing.

I don’t know that its any faster, honestly. It should be more efficient. I’ve just started using it in my patches, but I have to redesign some things to get it to work optimally. I was using [matrixctl] connected to a [pattr] previously to store settings, and this new method definitely works better for that sort of thing. I’m still using [textedit] for smaller lists, though: basically anything that doesn’t need the [coll] functions. This should be faster, since there’s no need to dump the [coll] again after changes are made in order to reflect the change in the [pattr].


November 24, 2010 | 2:28 pm

Thanks for this patch/script. very helpful.

One thing does not work as expected: I’ve tried to store an array(?) in the first place. So in the [coll] editor appears the following line:

1, "array at first" x y z;

After the coll was restored by the [js] it look like that:

1, x y z;

Any idea how to fix this ?


November 24, 2010 | 3:42 pm

ok, this could be a solution:

I’ve added these lines

if(messagename!="list")
{
   args_out.push(messagename);
}

in this function:

function anything(num)
{
    var args = arrayfromargs(arguments);
    switch(inlet)
    {
        case 0:
            store_to_coll(args);
            outlet(0, args);
            break;
        case 2:
            reg=num;
            break;
        case 1:
            var args_out=[];
            args_out.push(reg);

            if(messagename!="list")
            {
                args_out.push(messagename);
            }
            for(var i in args)
            {
                args_out.push(args[i]);
            }
            store_to_coll(args_out);
            break;
    }
}

November 24, 2010 | 7:16 pm

Thanks for the observation: I hadn’t noticed this, so I’ll try to figure out what’s up and repost a solution. I definitely want to know about any problems with this thing before I package it in all the Monomodular patches.

One thing: if you change any of the code in the "mux" function, make sure that there is a "^" placed in between each item in the coll, as well as at the beginning and end of the value stored in the [pattr].

I expect it will probably need some more fine tuning….please, if anyone else notices any weird behaviour, let me know; I haven’t had a lot of time to test out all the different functionality in real world situations.

Cheers :)

edit:: thanks again for the code…now that I’m looking at your solution, I realize I wouldn’t have even thought of that without hours of staring and scratching. :)


September 3, 2012 | 12:25 am

Someone was interested in this, and I noticed that my original js code snippet got garbled when Cycling updated the forums last. Here’s a link to a m4l frozen patcher that displays some of the functionality of this; I haven’t had time to retest it, but it seems to work ok at first glance. Let me know if anything doesn’t work right:


September 3, 2012 | 5:19 pm

The above mentioned "collect an array in the first place" bug is back. :-)

Have a look at the appended M4L device. It shows you exactly how to reproduce it.

cheers
stan


September 4, 2012 | 8:14 pm

Ahhh….thanks for that. Bad file references, the newest js must’ve gotten lost in the shuffle somehow. I’ll update and repost shortly…..


September 9, 2012 | 9:49 pm

Here’s an updated version with Stan’s fix….I spent a few minutes testing it, and it should work as expected now.


September 9, 2012 | 11:47 pm

:)))))))))) u are my hero !!!


September 18, 2012 | 10:39 am

everything works great until i dump/collect the data from [coll] into the js.collstore . im getting additional strings "symbol" "msg_int" "msg_float" . Is there a way to force javascript not to push these messages into the pattr ?


September 18, 2012 | 1:06 pm

ive spotted that this line cause the problem

if(messagename!="list")
{
   args_out.push(messagename);
}

September 21, 2012 | 1:47 pm

Hey there,

Thanks, I’ll try to have a look at this today or tomorrow.

a


September 21, 2012 | 3:12 pm

Hi .

is there a way to improve JS iteration process too ? ive noticed a long hangs (around 2 -3 minutes) when iterating elements into an array that gets over 1000 steps . this efficiency issue has something to do with JS processing within Max ? i know that JS is slower over native patching , C or Java, but such hangs are rare in the computing world ,especially when we are not dealing with huge audio/visual data streams ,just some characters


September 22, 2012 | 5:50 pm

Sounds like it’s probably not JS that’s causing the lag….it’s more likely a problem with sending such long lists as a blob to the [pattr]. Unfortunately, there’s probably not much to be done about this except reduce the number of times your making changes and restoring these "long lists".

If you can send me an example patch showing what’s going on, I’ll check and see what’s going on….I’ve been travelling lately, so all my "freetime coding" has been a bit curtailed…..

Cheers,

a


September 22, 2012 | 7:18 pm

Hello !
thanks for your effort !

well , ive done a workaround with your JS .ive reproduced your JS logic directly in max . ive bypassed dumping/collecting . im dumping data with max elements in right order and list preparation so it remains the same as your JS conditions but without collstore in action, directly to pattr . it takes around 30ms now ,not 2 minutes .
would be great if you can see it ,so i will send it to you with my files (to check) via email . if you will be able to spot things then we will continue in here ,in the case of other people that might like to use it ,if u dont mind


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