slowing down a loop in a recursive function - actionscript-3

I have a difficult problem with a recursive function. Essentially I need to 'slow down' a for loop within a function that repeatedly calls itself(the function);
Is this possible, or do I need to somehow extract the recursive nature of the function?
function callRecursiveFuncAgain(ob:Object):void{
//do recursive stuff;
for (var i:int = 0; i < 4; i++) {
_nextObj=foo
callRecursiveFuncAgain(_nextObj);
}
}

Try setTimeout
function callRecursiveFuncAgain(ob:Object):void{
// do recursive stuff
var i = 0;
function callNext()
{
if(i++ < 4)
{
_nextObj=foo;
callRecursiveFuncAgain(_nextObj);
setTimeout(callNext, 1000);
}
}
callNext();
}

You should use some function which will wait for some time or another function which will use much CPU and therefore will slow down your recursive function. Another way would be using debugger and breakpoints.

Are you serious? If you have a slow computer your CPU will have more load then a fast CPU which will NEVER work in a situation that needs a good solution. It's not even close to a crappy solution.
Try to use the setTimeOut that's in the flash.utils package http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/utils/package.html.
example use: setTimeout(delayedFunction, delay, arguments);
Note that the delay is expressed in milliseconds.
Check the 'clearTimeOut()' function (flash.utils) to clear your setTimeOut when you're done with it.

Related

Can JavaScript Functions Auto Detect and Log their Execution Cycle

Supposing I want to know execution time expended for a function to complete its execution cycle, I know that I would need to run:
function runcycle(){
console.time('runcycle', console.log('runcycle started'));
//function body
return console.timeEnd('runcycle');
}
This is however manual and cumbersome, especially if I have multiple functions, so my question is this:
Is it possible for JavaScript functions run automated timer messages about their execution?
Okay, seems there is an easy workaround to achieve auto logger for function execution, which is by creating a helper function that wraps all functions in a host function:
function logfunc(func, fname){
return function(){
console.time(fname, console.log(fname, 'started'));
let r = func();
console.timeEnd(fname);
return r;
}
}
/* And the helper logfunc can be utilized as: */
let test = logfunc(()=>{//funcbody}, 'test');
/* test() will run normally, but with logger capabilities */
test();
}
Though this works, I am still open to learning if JavaScript has an inbuilt auto logger for functions.

If conditional with no comparison infinitely executing

In the code
while(true)
{
this.rv1 = pdata.ReadString();
this.rv2 = pdata.ReadLong();
if(false)
{
continue;
}
break;
}
Why does if(false) infinitely execute, while other languages such as python's if False: Do.Something() never execute?
I didn't write the code in question, but I can't proceed without being able to read it - and I'm no AS3 pro!

AS3 Asynchronism problems

I had a strange bug in my program which I fortunately found quite quickly but am still puzzled why it was happening. Essentially it was to do with the order of commands in the source code and event listeners, here is the example:
function detectFaces(loader:ImageLoader)
{
var detector:FaceDetector=new FaceDetector();
detector.addEventListener(FaceDetectorEvent.FACE_CROPPED,facesDetected);
detector.loadFaceImageFromBitmap(loader.bitmap);
var something:Number = stage.width;
function facesDetected(e:FaceDetectorEvent):void{
trace(something);
}
}
Operation that raise the event here is not important, only thing to note about it would be it takes around 100ms. What I get as trace output is NaN and I don't know why that is since line declaring the variable something will definitely be called before callback of facesDetected and it is in scope of the handler function declared under it. This problem was easy to solve by just moving var something:Number = stage.width; before loadFaceImageFromBitmap(..) method, but I would really like to know why this is happening?
I am suspecting this is not due to order of execution but has something to do with passingByValue and passingByRefrence deferences but don't know how would these cause an error like this.
EDIT: Now I am even more puzzled... This code works in any order of declaration:
timers();
function timers()
{
var timerTest:Timer = new Timer(100,1);
timerTest.addEventListener(TimerEvent.TIMER,onTime);
//BEFORE DECLARATION
timerTest.start();
var something:Number = stage.width;
function onTime(e:Event)
{
trace("SOMETHING :"+something);
}
}
timers();
function timers()
{
var timerTest:Timer = new Timer(100,1);
timerTest.addEventListener(TimerEvent.TIMER,onTime);
var something:Number = stage.width;
//AFTER DECLARATION
timerTest.start();
function onTime(e:Event)
{
trace("SOMETHING :"+something);
}
}
With regard to your initial question, actionscript will complete the execution of a block of code before it continues to execute subsequent lines. If there was nothing asynchronous happening in your loadFaceImageFromBitmap method (ie, if your weren't using a Loader or some other object that had to wait for an event to fire) then, however long the code takes to execute, the FACE_CROPPED event will still fire before 'something' is set to a value.
As for the other problem, it looks to me like the answer is simply that you're using a TimerEvent - Actionscript will acknowledge that it shouldn't wait for the event to fire before continuing to execute code; It will, therefore, declare 'something' before the 100 miliseconds passes. So, in this case, because you're using an event, the code WILL continue 'reading' and executing the lines following the event listener.
The code of the function loadFaceImageFromBitmap run on a sync way. The FaceDetectorEvent.FACE_CROPPED event listener is invoked inside of that function, it is not a callback declared to run after some response is returned for ie(http request).
In the case of the Timer it works as expected, because event listener is not invoked right at the start moment, it waits for X time.

From synchronous flow to asynchronous flow dilemma

As a PHP programmer I'm very habituated to the fact that the program flow goes line by line, if I call function1() that have to return some value I know the program wont continue until that function makes a return.
Now, im developing a AS3 app using AIR, I need to download some images if some conditions are met, don't know how many, so im using a For like this:
for (var w:int=0; w < newData_array[2]['content'].length; w++ ) {
for (var j:int=0; j < oldData_array[2]['content'].length; j++ ) {
if((oldData_array[2]['content'][j]['id'] == newData_array[2]['content'][w]['id']) && (oldData_array[2]['content'][j]['last_mod'] != newData_array[2]['content'][w]['last_mod'])){
//need to download a image...
}
}
}
As you can see im just comparing each element from each array (newData_array and oldData_array). If the condition met, I need to download something, for that I'm using URLloader and as you know this function is asynchronous, adding a listener, an event will be triggered when the download is complete, the problem is very clear, since the urlloader wont stop the for cycle (like I would expect on a PHP alike language) I'm just going to download a bunch of images at the same time creating a disaster because I wont know when to save. So I need to use by any mean the listener, but since I'm not very habituated to this kind of procedures I'm pretty munch stuck.
Im not interested on the save to disk routines, that part is pretty much done, I just want to understand how I should structure this algorithm to make this work.
This annoyed me too, but one has to realize that you can't do something to something that doesn't exist in memory yet, and these loading operations can take quite some time. Being a single-threaded stack, Flash Player's load operations would require that the entire interface to freeze during the load (if restricted to the loop).
Obviously there's data available to the loop that dictates what you do with the image. The solution I've been using is create a custom load function that starts the load, and returns a proxy image . Your loop gets a container back and you can freely place your image where you want.
In the meantime, your loader listener has kept track of the active images loading, and their associated proxies. When loaded, swap the image in.
Your loop would look something like this...
for (var w:int in newData_array[2]['content']) {
for (var j:int in oldData_array[2]['content']) {
if ((oldData_array[2]['content'][j]['id'] == newData_array[2]['content'][w]['id']) && (oldData_array[2]['content'][j]['last_mod'] != newData_array[2]['content'][w]['last_mod'])){
var proxy:MovieClip = loadImage("image/path.jpg");
// Do stuff to proxy.
}
}
}
And your function + listener would look something like this...
var proxies:Object = {};
function loadImage(path:String):MovieClip {
// load Image
var proxy:MovieClip = new MovieClip();
proxies.path = proxy;
// Load Image
}
function imageLoaded(e:Event):void {
// Once loaded, use the filename as the proxy object's key to find the MovieClip to attach the image.
proxies[e.data.loaderInfo.filename].addChild(e.data);
}
This is just off the top of my head, so you'll need to find the actual variable names, but I hope that makes sense.
I am not really sure if I understood your problem but it seems to me that you simply add the according listener in your inner loop.
//take care this is pseudocode
var parent = ... // some stage object
for (var w:int=0; w < size1; w++ ) {
for (var j:int=0; j < size2; j++ ) {
if(some_condition){
request = new URLRequest(getNextImagePath();
urlLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, onComplete);
urlLoader.load(request);
}
}
}
function onComplete(event:Event) {
parent.addChild(createImageFromData(this.data));
}
I solved the problem using an third party library that pretty munch handles this problem.
https://github.com/arthur-debert/BulkLoader

What's the difference between looping through an array and using array.every()

What's the difference between looping through an array or using array.every() to assign a callback to each array element?
The array.every() function uses a test callback function on each array element, but stops once that test function returns false. If you loop through the array, it will go through every element regardless. In other words, the array.every() function is more properly used to test if every element of an array fits a certain criteria. See the documentation of array.every() for more details.
Suppose you want to check if every element of your array is of type IFoo, and depending on that perform a certain operation.
There are at least 3 ways to do this.
1. Iteration
var allFoo:Boolean = true;
for (var i:int = 0; i < array.length; i++) {
if (!(array[i] is IFoo)) {
allFoo = false;
break;
}
}
if (allFoo) {
// perform operation
} else {
// do something else
}
2. Enumeration
var allFoo:Boolean = true;
for each (var e:* in array) {
if (!(e is IFoo)) {
allFoo = false;
break;
}
}
if (allFoo) {
// perform operation
} else {
// do something else
}
3. Array.every()
function isElementFoo(item:*, index:int, array:Array):Boolean
{
return (item is IFoo);
}
if (array.every(isElementFoo)) {
// perform operation
} else {
// do something else
}
I expect the second one to be the fastest, whereas the third one is the most elegant due to the absence of any temporary variables. Ultimately which one you choose depends on the nature of your program as much as your own personal style and philosophy.
It is basically a convenience function that abstracts common uses of for or while loops on arrays. To make it a little quicker to code and depending on you preferences a little clearer to read.
You would get a little bigger overhead using array.every since it does a function call for every element butt this is a none issue in 99.99...% of the time especially on the flash platform.