method pushcontextframe/popcontextframe (m4l)
Hi fellows, I'm having these two messages in the Max Window. Have you ever seen them?
"method pushcontextframe called on invalid object"
"method popcontextframe called on invalid object"
This is the simple code (inside M4L):
inlets = 1;
outlets = 1;
var paramValue = new Array();
root = new LiveAPI(param_callback);
function setup() {
root.path = "live_set view";
root.property = "selected_parameter";
}
function param_callback(args) {
if(args[2] != 0) { //filter Id 0
paramValue[0] = args[1];
paramValue[1] = args[2];
value = new LiveAPI(paramValue);
outlet(0, value.get("max"));
}
}
Hey Kevinripper,
I got the same error and talked to ableton support about it. They couldn't give me any answers as to why it happens. I did ask if I should just ignore it (since it doesnt seem to cause any significant error) and they said, it probably should be ignored.
Cheers
the callback is called each time selected_parameter property changes.
wouldn't it be a problem of thread-like interference ?
Thanks @newtfish!
@Julien, I'm not following you on this one. The code is very very simple, you now it, just get the max value of the parameter selected. I don't know why these messages appear 'cause if I code another function to get the max value they don't appear... but I would have to call two different functions and I want this all automated. Achieving this with max objects is nothing really I mean (path live_set view selected_parameter) -> [live.path] -> [deferlow] -> [t b l] -> (get max) -> [live.object] but I want to build everything in js now...and although my code works I find annoying to see those messages in the Max Window.
Hi, never use that form of LiveAPI, always pass a path in, try:
root = new LiveAPI( paramcallback, "live_set selected_parameter" );
you're 2nd call to LiveAPI is not valid as the first parameter is always a callback and you've passed it an array.
you probably want something like
control = new LiveAPI( nullcallback, "id " + args[ 0 ] );
max = control.get( "max" );
I can have a better look when I get home, but this is the gist of it...
ultimately, you are probably seeing those messages as it thinks it can call those methods on "paramValue" which it expecting to be a function, but it's not, it's an array
@Julien, js code is all single threaded so there are no threading concerns...
@LEE, the array I'm passing it's a "valid id" (the id of the parameter I'm selecting) and in the max window the message "invalid path" is not appearing so my guess is that is working just fine.
I test your code and it's not working :S
i'm at work, i can't try it - was just trying to get the idea across...
i have to try later
No worries, it's nothing urgent. Thanks in advance!
Apparently there is a strange behavior when calling the LiveAPI constructor in a callback.
The solution by Andrew Pask:
inlets = 1;
outlets = 1;
root = new LiveAPI(param_callback);
var value = new LiveAPI();
function setup() {
root.path = "live_set view";
root.property = "selected_parameter";
}
function param_callback(args) {
if(args[2] != 0) { //filter Id 0
value.id = args[2];
outlet(0, value.get("max"));
}
}
Here a code to observe the current value and the max value of the selected parameter:
inlets = 1;
outlets = 2;
var root = new LiveAPI(param_callback);
var value = new LiveAPI(value_callback);
function setup() {
root.path = "live_set view";
root.property = "selected_parameter";
}
function param_callback(args){
if(args[2] != 0) {
value.id = args[2];
value.property = ("value");
}
}
function value_callback(vals){
outlet(0, value.get("value"));
outlet(1, value.get("max"));
}
ive not had chance to look in this in detail yet (sorry), but I've just fired up my m4l abstraction and it spews these messages all over the place - this is new, it never used to... this has only started happening since 9.1 (i have to check if it was in 9.1 beta), but it didn't happen to me in 9.0...
i'll look into it more tomorrow when I get some time...
The short answer is don't put LiveAPI constructors inside your callback functions. That's what's causing the error in this case. We have a ticket for investigating it.
-A
ok, thanks Andrew.
ive been learning javascript and found that I needed to send a message out of a js outlet into a deferlow object then that would trigger the Bang() in the javascript. not tried the code above but that's my solution that works for me.
cheers
Chris.
Given that I'm not supposed to call LiveAPI constructors in callbacks, does anyone have a way to
1. Observe track changes, (i.e. the live_set property 'tracks')
2. Populate a list of track names in response to changes (i.e. iterating through live_set.get('tracks') which returns an array of track ids)
without throwing this pushcontextframe error?
Any help much appreciated!
I'm wondering this too... Andrew, as this used to be ok and you indicated you are investigating, does this imply something has been changed and you are investigating a way to make this work again in the old way?
e.g. when a new clip is added and I want to monitor properties I now have to send a message out of an outlet, defer it, and then back in to monitor the new properties which is alot more hassle than just creating a new LiveAPI object which we used to be able to do...
Adding constructors in callbacks has never been officially supported. I have no further news on this issue ATM
Sorry....
-A
ok, shame - it does complicate dealing with this situation somewhat...
ok, may I please have a small code example of this going wrong to support?
Thanks
-A
ok never mind, I have one here.
Can you guys verify that the error seems harmless? I see my LiveAPI code still working right, despite the deluge
Cheers
-A
I'm seeing this exact error and so far it seems harmless.
it is harmless in one way in the fact that stuff appears to work fine - however, it sends lots of stuff to the MAX window - as more stuff goes to the MAX window, it starts to slow down... once it gets to 10000 rows you'll start getting status lines appearing in the devices - Also, if there is any useful information sent to the window, it is hard to track down as it's surrounded by noise
so, more of an annoyance in the short term, but one that ultimately needs to be dealt with by the coder (whereas if the behaviour is not a problem then it would be better if the message were not generated)
I may have found a different workaround if you want to see if it works for you.
Just to clear a couple things up first, the first one reiterating that the 'push/popcontextframe error' comes up when you're creating new LiveAPIs in a callback.
So what I ended up doing was creating a new function for what I wanted to do (create more new LiveAPI's). Regardless of if it's a function outside the scope of the original containing the callback, you'll still get that push/pop error, but if you call that function using a
Task
with a little bit of delay (I'm fine with 10msm haven't checked less), then I stop getting the errors. This also works for that other ol' famous error when too much is being asked of the LiveAPI all at once (which is actually what made me think of trying this.
So something like:
autowatch = 1;
outlets = 2;
var LiveObj = {}, trackArr = [], getTest = new Task(getRest, this);
function trackVol() {
var liveSet = new LiveAPI(getTracks);
liveSet.path = 'live_set';
liveSet.property = 'tracks';
function getTracks(args) {
if (args[0] == 'tracks') {
trackArr = [];
for (var i = 0; i < args.length; i += 2)
trackArr.push(args[i]);
}
trackArr.splice(0, 1);
getTest.schedule(10);
}
}
function getRest() {
var mixApi,
getVol,
mixArr = [],
volApi,
vol,
volArr = [];
LiveObj = {};
for (var j = 0; j < trackArr.length; j++) {
mixApi = new LiveAPI('live_set tracks ' + j + ' mixer_device');
getVol = mixApi.get('volume');
mixArr[j] = getVol[1];
volApi = new LiveAPI('id ' + mixArr[j]);
vol = volApi.get('value');
volArr.push(vol[0]);
LiveObj['track' + j] = {
'id' : trackArr[j],
'mixer' : mixArr[j],
'vol' : volArr[j]
};
}
outlet(1, LiveObj.toSource());
}
another approach might be this:
- function 'X' contains the usage of LiveAPI constructors
- function 'Y' gets called when a LiveAPI property changes
- function 'Y' then calls 'outlet(0,"x")'
...and outlet 0 is connected, via a deferlow object, to the js inlet!
So function 'Y' calls function 'X' with a deferlow in between.
thats how I solved this issue for myself...
Andrew, I am also seeing this warning when creating LiveAPI objects in LiveAPI callbacks. I am not seeing any behavioral side effects when the warning is given and it seems like it could be hidden. It does make debugging difficult. However, if calling the constructor isn't supported from callbacks, maybe hiding the current stack warning and adding an appropriate warning as you might do for calls becoming obsolete in the future?
Anyway, just thoughts. Thanks so much!
Just chiming in that this is still an issue in 7.1