Dan K Posted March 11, 2019 Share Posted March 11, 2019 I am having a difficult time passing a variable to a me.timer.setTimeout... can it accept variables? Specifically its a bit of a closure problem as well. I am trying to deploy units over set intervals of time. I have the units in an array with time offsets. I thought I'd cycle through the array of units setting the timer event to the offset. But when the timer event fires, it accesses the last known value on the closure variable. for (let i = 0; i < this.unitList.length; i++) { var unitType = this.unitList[i].type; var delay = this.unitList[i].delay; var toBeCalled = function () { console.log("Deploying Unit: " + unitType); // this.deployUnit(unitType); this.deployUnit(unitType); // 'this' here is the 'window' object because the timer comes from the window }.bind(this); // if you don't bind it to this. then the unitType won't be declared me.timer.setTimeout(toBeCalled, delay * 1000, true); // window.setTimeout(toBeCalled,delay*1000,[unitType]); // but this is not pausable and it can't access the deployUnit function because it is part of a class } Any ideas of improving the closure? or passing arguments to the function? the window version allows arguments but I can't seem to reach my class instances... (in theory they have to be there somewhere) Quote Link to comment Share on other sites More sharing options...
Dan K Posted March 11, 2019 Author Share Posted March 11, 2019 As with the nature of all things... Pluging at this for a few more hours finally yields an answer myself... This is an interesting trick... The problem was that the timer object gets called from the 'window' object where the application instance was difficult to find. So instead, I pass the 'this' instance as the context variable, thus ensuring that I had the 'deployUnit' property availble to call when the setTimeout executed the toBeCalled() function. var makeTimer = function(unitType,delay,context) { var localUnit = unitType; var toBeCalled = function () { console.log("Deploying Unit: " + localUnit); // this.deployUnit(unitType); // context.deployUnit(localUnit,context); // 'this' here is the 'window' object because the timer comes from the window. // on top of that problem, I couldn't seem to access the AppJS.GameController object, so I just // passing int along in the parameter context. };//.bind(this); // eventually just removed the bind, because I was able to pass in the class pointer in the parameter 'context' me.timer.setTimeout(toBeCalled, delay * 1000, true); }; for (let i = 0; i < this.unitList.length; i++) { var unitType = this.unitList[i].type; var delay = this.unitList[i].delay; makeTimer(unitType,delay,this); //https://www.youtube.com/watch?v=-jysK0nlz7A 9.6: JavaScript Closure - p5.js Tutorial by the Coding Train } Quote Link to comment Share on other sites More sharing options...
obiot Posted March 12, 2019 Share Posted March 12, 2019 Indeed this is a valid request and to be honest i don’t recall why arguments passlng has not been included when we implemented these functions, as this is indeed supported by the global « standard » ones. i’m glad that you found a way to make it work for you (passing arguments to bind was another one), but i’ll look anyway into adding it to our setTimeout and setInterval methods. Thanks ! Quote Link to comment Share on other sites More sharing options...
obiot Posted March 12, 2019 Share Posted March 12, 2019 to keep it under my radar : https://github.com/melonjs/melonJS/issues/977 Quote Link to comment Share on other sites More sharing options...
obiot Posted March 14, 2019 Share Posted March 14, 2019 FYI, I just added it to the current 7.0 version : https://github.com/melonjs/melonJS/commit/97d6a2eb1dd8d788112b40c6f92869e0b25b5b39 test build available below if you want to give it a try : https://melonjs-builds.s3.amazonaws.com/index.html?prefix=artifacts/master/2506/build/ Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.