Is it possible to get some kind of ID from a JitterListener?

mattyo's icon

Hi.

I have an array of movies being generated in js, and I need to get a loopreport from each:

            movArray[vcount] = new JitterObject("jit.qt.movie");
            movArray[vcount].loopreport = 1;

No problem. then for each, a JitterListener:

listenArray[vcount] = new JitterListener(movArray[vcount].getregisteredname(),callback);

cool. now in my callback function, I need to know which movie has loopnotified. As far as I can see, the only data that the listener can pass to a callback function is the eventname.

function callback(event){

    if(event.eventname = "loopreport"){
        var smov = (Math.round(Math.random() * vcount));
        post("nlistener",smov);
}

Is there some some other call (I don't know -- listener.name, something like that) I can pass as an argument to my callback function so I can determine the source?

Thanks,

M

Jeremy's icon

Hi Matthew,

Inside of your callback, event.subjectname should be whatever you passed to the JitterListener constructor as "movArray[vcount].getregisteredname()".

Best, Jeremy

mattyo's icon

Thanks, Jeremy!

but of course, it's still a bid odd. If I do not explicitly assign a name to the listener, I get what one would expect on loopreport:

js: listener u190002971

Of course, this isn't too helpful, so I assigned a name to each listener on instantiation:

listenArray[vcount] = new JitterListener(movArray[vcount].getregisteredname(),listenresults)
listenArray[vcount].subjectname = "listen_" + vcount;
post("init name ", listenArray[vcount].subjectname, "n")

I get what I would expect posted on initialization: listen_0, listen_1, etc.

However, once I do that, the listener ceases to report events entirely. If I comment out the naming line, it works fine, but still with the jit-style matrix name(obviously, since naming it kills the system)

For the heck of it, i tried:

listenArray[vcount].name = "listen_" + vcount;

but that just gets me an undefined on loopreport:

js: listener loopreport

So the question is, why does explicitly assigning a subjectname kill the listener? Is this another one of my I-forgot-a-semicolon errors, or is it something else?

All I'm really looking for is the index number of the movie/listener, so I can set/reset volume levels at loopreport...

I hope this isn't too vague. I've attached code/patcher if that helps....

Love,

M

5171.jdelk.top.maxpat.zip
zip
Jesse's icon

I'm not familiar with JitterListener particularly, but from Jeremy's comment I think you would set JitterObject.name prior to passing it into the JitterListener constructor via JitterObject.getregisteredname().

Alternately you could skip this and upon receiving the loop event you could simply iterate through movArray[] and match event.subjectname against movArray[].getregisteredname(). This might be expensive if you have a huge array of movies, but likely not a big issue.

Jeremy's icon

The subjectname property is _not_ a property of the Listener, it is a property of the event. It's set by the Listener (based on the info in the Listener's constructor) before triggering the callback function.

So why don't you set the name of your jit.qt.movie JitterObject() when you create it, a la new JitterObject("jit.qt.movie", "mattyo_" + vcount); I haven't tested this, but I think that's correct. Then the names are easier to deal with out of the box.

Best, Jeremy

mattyo's icon

Hey Jeremy,

thanks for the explanation -- I'll have a look later today & get back to you when I know something....

M

mattyo's icon

Hey Jeremy,

the constructor style you proposed: (new JitterObject("jit.qt.movie", "mattyo_" + vcount);

is fine for a window, but it and its variants get errors on compile:

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

at callback, I still get an anonymous jitter-name. With this function:

function listenresults(event){
    post("ncallback: " + event.subjectname + " sent "+ event.eventname);
}

I get this: js: callback: u867009514 sent loopreport

Then I thought -- "who cares if the subjectname is human readable? I just have to refer to it!"

So, thinking myself quite clever, I tried this:

function listenresults(event){
if(event.eventname = "loopreport"){
        event.subjectname.vol = 1.;
        post("nlistener loopreport",event.subjectname);
    }
}

I get the posts, but no dice with changing the volume -- event.subjectname.vol doesn't get back to the movie. So I'm still a bit lost -- how do I assign a subjectname to the movie that I can use when I need to talk to the movie? Sorry if I'm being dense here, but I haven't managed to find any clear hints anywhere on the site...

Thanks,

M

Jeremy's icon

OK, just when you thought it was hopeless, I have it. Add a third argument to:

listenArray[vcount] = new JitterListener(movArray[vcount].getregisteredname(),listenresults);

so that it reads:

listenArray[vcount] = new JitterListener(movArray[vcount].getregisteredname(), listenresults, movArray[vcount]);

Poof! Your jit.qt.movie is now "this" inside of your callback function. So you can say something like "this.vol = 1.;".

Best, Jeremy

mattyo's icon

quick test -- I'll look at it more closely tomorrow -- is not promising, I'm afraid, although I may have one of my habitual typos:

adding the argument to the listener constructor happens without a hitch. adding "this.vol = 1." to the callback function, sadly makes everything go boom. Crashlog attached. 8-(

M

5177.Max20130312183833schwartz.crash
crash
Joshua Kit Clayton's icon

Hi Matthew,

FWIW, Several JS crashes like this were fixed in 6.1.0. If it is still crashing, please give us a stripped example patch and we can solve.

Thanks,
Joshua

Joshua Kit Clayton's icon

Alternatively, as a hack workaround, you could perhaps provide a String object with the name, or number of the movie, in place of the movie object in your callback, then reference a global array of the movies or something along those lines.

Jeremy's icon

Hi Matthew -

So one thing I'm seeing in your JS is that you need to be careful about when you set this attribute. Setting this.vol will trigger another call to the Listener with an "attr_modified" event with 'vol' as the "event.args". So you can't trigger a volume change in response to itself or you'll get a feedback loop and eventually crash. That's probably what's going on, since it happens to me, too.

Another thing is that you're using the '=' assignment operator instead of the '==' comparison operator in your callback. My working callback function (with some superfluous debugging gunk) is below. I notice that the loopreport event is sent constantly, which seems wrong, but I'll need to look into that.

function listenresults(event){
    post("nlistenerevent: " + event.eventname);

    if(event.eventname == "loopreport") {
        post("nlistener loopreport: this = " +
              (Object.prototype.toString.call(this).match(/^[objects(.*)]$/)[1]) +
              " (" + this.moviename + ")");
    } else if (event.eventname == "attr_modified") {
        post("nlistener attr_modified: " + event.args);
    } else {
        post("nchanging vol");
        this.vol = 1.;
    }
}
mattyo's icon

Jeremy: I've sent you some long and boring stuff about this privately... when we have an answer, we can put it here for the public record....

Joshua: 6.1 has issues, I'm bumping that to the beta list...

M