-
[flex as3]function non recursive call. how?
So, I create standard AS3 flex project. In constructor goes only start();
rest of functions are basically this:
private start():void { f1();}
private function f1():void { f2();}
private function f2():void { f1();}
And it's standard recursion. SWF either breaks or loops as many times as I tell it. One f calls the other, which calls first... I do not want that.
I want f1 to do some stuff, calls f1 and closes itself. Than f2 works, calls f1 and closes. And so on.
Like having 2 sets of code that loops through.
What's the cleanest way to do that?
-
I made one with timer 0.
so when f1 end it's calculations, call timer0 to start f2.
and f2 use same timer to call f1.
Ugly, I know. anything better, cleaner?
-
Error #2094: Event dispatch recursion overflow
Or, my question should be: Why the heck this doesn't work?
And how to overcome " Error #2094: Event dispatch recursion overflow."
Code:
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFieldType;
import flash.utils.Timer;
public class Loop1 extends Sprite
{
private var i_int:int=0;
private var zbir_int:int=0;
private var counter_int:int=0;
private var time_txt:TextField=new TextField();
public var myTimer:Timer = new Timer(10, 2050); // 10 ms, 2050 times repeat
public function Loop1() //constructor
{
stage.addEventListener(KeyboardEvent.KEY_UP, startLoop_f);
this.addEventListener("_START", f1);
time_txt.type = TextFieldType.DYNAMIC;
time_txt.border = true;
time_txt.background = true;
time_txt.backgroundColor = 0xD6D3CE;// 0xFFFF66;
time_txt.width = 160; //px
time_txt.height = 450;
time_txt.autoSize = TextFieldAutoSize.LEFT; //size from left
time_txt.wordWrap = true;
time_txt.text = "Initializing! Please wait.";
addChild(time_txt);
} //end of constructor
private function startLoop_f(event:KeyboardEvent):void
{
if(event.keyCode==32)
{
dispatchEvent(new Event("_START")); //calls f1();
}
}
private function f1(e:Event):void
{
counter_int++;
for(i_int=0;i_int<100000;i_int++)
{
zbir_int=zbir_int+i_int;
}
time_txt.text = "loop counter: "+counter_int+
"\nzbir: "+zbir_int;
dispatchEvent(new Event("_START")); //calls f1();
} //end of f1
} //end of class
} // end of package
-
This thread is all over the place, so I'll address the last question only.
It doesn't work because you have no termination condition. Every time f1 is called, it dispatches an event which calls f1 again. This leads to an infinite loop. I don't know what you were trying to accomplish.
Also, that loop in f1 is a ridiculously inefficient way of accomplishing that calculation.
Code:
for(i_int=0;i_int<100000;i_int++)
{
zbir_int=zbir_int+i_int;
}
is equivalent to:
Code:
zbir_int += 100000*(100000+1)/2; //see guassian summation
http://www.cut-the-knot.org/Curricul...ummation.shtml
which is equivalent to
Code:
zbir_int += 5000050000;
Which, by the way, is bigger than an int can hold.
What the heck are you trying to accomplish?
-
Exactly! All I want is infinite loop!!! By calling functions.
Like:
while(true){...do something...}
I have Event stack overflow. That is my real problem.
The for(100000){} is only for adding some weight to code. Just to have comp calculate something. The result is big, but it works if I call f1 by timer. That's not the issue.
I want to, as mentioned in first post, to create infinite loop by function calls.
1. I event f1(). When it's done it events itself.
2. When f1() is done it events f2(). f2() works, when it is done, it events f1()
-
Thanks for reply!
If I wasn't clear, let me try another way...
1.
{
:label z:
...
some code
...
goto z
}
or:
2.
{
label a
...
some code
...
goto b
}
{
:label b
...
some code
...
goto a
}
So either I jump to a or b code loops until I break it. That's what I want.
Calling one function. Function has to be done, over, removed from the stack... And before that it sends event that calls itself or another f.
-
Before this thread, I wasn't aware of event dispatch recursion overflow, so that's what I would have suggested for an alternating infinite loop.
Infinite loops are generally bad (understatement of the century), so there's stuff that tries to detect them. Would an ENTER_FRAME listener work for you?
Code:
addEventListener(Event.ENTER_FRAME, alternateAB);
var doA:Boolean = true;
function alternateAB(e:Event):void{
doA ? afunc() : bfunc();
doA = !doA;
}
Putting it in an ENTER_FRAME ensures that your function completes before the next round, but also should avoid the script timeout error. Unless afunc() or bfunc() themselves cause it.
-
Can you explain the actual application for this?
1.
PHP Code:
while(true){
// ...
break;
}
2.
PHP Code:
function a(keepLooping:Boolean = true):void{
// ...
if(keepLooping) b();
}
function b(keepLooping:Boolean = true):void{
// ...
if(keepLooping) a();
}
-
Exactly 5TOF! Exactly! I had an idea, coded it, tested it and nothing. Event error
If flash player uses regular events there should not be event overflow. Ever!
But it seems it didn't. It's smells like regular function. Like event has a return value or something that has to end (listener method) and return something to someone to continue with new events.
I am new at this stuff, do you think it's because of some bubbling or unknown effect that could be tweaked by setting some strange event value. Or I need to build different custom events...
I have found one book on events and im reading it right now.
I was trying to evade usage of onEnterFrame or timers. Basicly that non recursive loop could be used as my own enter frame or timer or in a million different ways
@neznein9
PHP Code:
while(true) // for(i;i<100;i++;){}
{ i++;
if(i<100) {code} else break;
}
For i:int and simple i++ stepping it's almost ridiculous. But if stepping or condition are much more complex... I find while(true) more understandable or easier. Sometimes condition complexity is really to great to be put in for(). Or you simply have some number crunching and multiple condition exits.
Or it could be used as a timer, pause, to hog your cpu...
But here, I used it just to illustrate what I wanted to make with function and call event.
I hope goto a,b is more colorful
And no, I tried your idea first. These are two recursive functions. If I they go too deep, regular function stack will overflow. There is no way it will loop to infinity (or until condition is meet in my case).
If anyone asks why, here's the answer:
While recursive functions are working, nothing else is. No keyboard events, no mouse, timer, enterFrame, nothing! If they go too deep, stack overflows and it's the end. When/if they are finished, and all returns are been made, player continues as normal.
If it's possible to create non recursive infinite loop if AS3, it's like you have your own SEPARATE thread!
And with that, you can do some cool things
-
It sounds like you need a second timeline...you can't really do that within flash (read: elastic racetrack) but you could run the second timer outside in js. Since ExternalInterface is synchronous it can call in and execute AS3 outside the normal scope of operations so you could run code "behind the scenes"...I don't think you can force a screen refresh though.
Here's a demo - the left shows the frame and time of each enterFrame event (running at 1fps) and the right shows the time that each js was called and executed (4 times per sec).
Here's what the code looks like (thanks to Flax for the js injection technique - I so rarely get to use it ):
PHP Code:
var i:int = 1; var j:int = 1;
addEventListener('enterFrame', function(e:Event):void{ asLog.appendText('\n' + i++ + ': \t' + (getTimer()/1000).toFixed(2) + 'sec'); });
function jsFrame():void{ jsLog.appendText('\n' + j++ + ': \t' + (getTimer()/1000).toFixed(2) + 'sec'); }
ExternalInterface.addCallback('fireJSFrame', jsFrame); ExternalInterface.call('function startJSTimeline(){ setInterval("document.getElementById(\'tester\').fireJSFrame()", 250); }');
EDIT: Forgot to add - THIS IS A TERRIBLE IDEA!! DON'T USE THIS CODE FOR PRODUCTION SITES!!! That is all.
-
A couple of things:
Psuedo-threading has already been done in flash.
http://www.joristimmerman.be/wordpre...tionscrip-as3/
It looks clumsy, but somewhat functional. I actually like the js technique above more.
And nez, if you hadn't seen the xml/cdata way of embedding js in flash, it's wonderful.
http://board.flashkit.com/board/show...ight=embedding
-
Hmm...I still don't see a way to squeeze any more juice out of flash as it is now...all these techniques rely on the idea that the JIT has a bunch of spare time lying around between frames...maybe Alchemy will change all that?
Regardless - that xml method for loading js is just about the hottest thing I've seen all day!
-
Came across another one over at generalrelativity.org - I think I like this method best so far.
http://blog.generalrelativity.org/?p=29
-
Yeah, that's actually exactly what I was looking for and didn't find yesterday. Thanks.
-
Ok, thanks for all replies. So can anyone of this help me overcome event recursion as I intended to use f1() and f2()?
-
Last edited by DevilMayCry; 02-10-2009 at 02:10 PM.
-
If there's anyone awake here's another peace of code that generates same event overflow error
What am I doing wrong
PHP Code:
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFieldType;
import flash.utils.Timer;
//import flash.display.*;
public class gameLoop1 extends Sprite
{
private var i_int:int=0;
private var zbir_int:int=0;
private var counter_int:int=0;
private var time_txt:TextField=new TextField();
public var again:Event=new Event("_AGAIN",false,true);
public var reload:Event=new Event("_RELOAD",false,true);
public var start:Event=new Event("_START",false,true);
public var gameLoopStartTimer:Timer; // = new Timer(10, 2050); // 10 ms, 22250 times repeat
public function gameLoop1() //constructor
{
stage.addEventListener(KeyboardEvent.KEY_UP, startGame_f);
stage.addEventListener(start.type, f1,false,0,false);
stage.addEventListener(again.type, f2,false,0,false);
stage.addEventListener(reload.type,f1,false,0,false);
//this.addEventListener("_AGAIN",f1,false,0,false);
//this.addEventListener("_RECALL",f2);
//this false e error
//stage true e error
time_txt.type = TextFieldType.DYNAMIC;
time_txt.border = true;
time_txt.background = true;
time_txt.backgroundColor = 0xD6D3CE;// 0xFFFF66;
time_txt.width = 160; //px
time_txt.height = 450;
time_txt.autoSize = TextFieldAutoSize.LEFT; //size from left
time_txt.wordWrap = true;
time_txt.text = "Initializing! Please wait.";
addChild(time_txt);
} //end of constructor
private function startGame_f(e:KeyboardEvent):void
{
e.stopImmediatePropagation();
e.preventDefault();
if(e.keyCode==32)
{
dispatchEvent(start); //calls f1();
stage.removeEventListener(start.type,f1);
}
}
private function f1(e:Event):void
{
e.stopPropagation();
e.preventDefault();
e.stopImmediatePropagation()
counter_int++;
for(i_int=0;i_int<1000;i_int++)
{
zbir_int=zbir_int+i_int;
}
time_txt.text = "loop counter: "+counter_int+
"\nzbir: "+zbir_int+
"\n"+start.type;
stage.removeEventListener(reload.type, f1);
dispatchEvent(again); //calls f2();
} //end of f1
public function f2(e:Event):void
{
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
stage.addEventListener(reload.type, f1,true,0,false);
stage.removeEventListener(again.type,f2);
dispatchEvent(reload); //calls f1();
}
} //end of class
} // end of package
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|