A Flash Developer Resource Site

Results 1 to 17 of 17

Thread: [flex as3]function non recursive call. how?

  1. #1
    Member
    Join Date
    Jun 2008
    Posts
    34

    [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?

  2. #2
    Member
    Join Date
    Jun 2008
    Posts
    34
    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?

  3. #3
    Member
    Join Date
    Jun 2008
    Posts
    34

    Question 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

  4. #4
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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?

  5. #5
    Member
    Join Date
    Jun 2008
    Posts
    34

    Post

    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()

  6. #6
    Member
    Join Date
    Jun 2008
    Posts
    34

    Smile

    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.

  7. #7
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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.

  8. #8
    Ө_ө sleepy mod
    Join Date
    Mar 2003
    Location
    Oregon, USA
    Posts
    2,441
    Can you explain the actual application for this?

    1.
    PHP Code:
    while(true){
        
    //  ...
        
    break;

    2.
    PHP Code:
    function a(keepLooping:Boolean true):void{
        
    //  ...
        
    if(keepLoopingb();
    }

    function 
    b(keepLooping:Boolean true):void{
        
    //  ...
        
    if(keepLoopinga();


  9. #9
    Member
    Join Date
    Jun 2008
    Posts
    34

    Wink

    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

  10. #10
    Ө_ө sleepy mod
    Join Date
    Mar 2003
    Location
    Oregon, USA
    Posts
    2,441
    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.

  11. #11
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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

  12. #12
    Ө_ө sleepy mod
    Join Date
    Mar 2003
    Location
    Oregon, USA
    Posts
    2,441
    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!

  13. #13
    Ө_ө sleepy mod
    Join Date
    Mar 2003
    Location
    Oregon, USA
    Posts
    2,441
    Came across another one over at generalrelativity.org - I think I like this method best so far.

    http://blog.generalrelativity.org/?p=29

  14. #14
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Yeah, that's actually exactly what I was looking for and didn't find yesterday. Thanks.

  15. #15
    Member
    Join Date
    Jun 2008
    Posts
    34
    Ok, thanks for all replies. So can anyone of this help me overcome event recursion as I intended to use f1() and f2()?

  16. #16
    Member
    Join Date
    Jun 2008
    Posts
    34

    Thumbs up

    A little modified code says that it loops exactly 1000 times. And in one book is written:
    ...Flash runtime’s maximum recursion limit, which defaults to 1000 but can be set via the compiler argument default-script-limits.
    I am also reading about stopPropagation( ), stopImmediatePropagation( ) and public, internal and global functions. Don't know how to successfully implement it yet but maybe there lies solution

    EDIT:
    If I use two addEventListener which events f1 or f2 in a loop, code executes 500 times
    1000recursions / 2events

    I must say I do not have a clue how to overcome this
    Last edited by DevilMayCry; 02-10-2009 at 02:10 PM.

  17. #17
    Member
    Join Date
    Jun 2008
    Posts
    34

    Post

    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_UPstartGame_f);
    stage.addEventListener(start.typef1,false,0,false);
    stage.addEventListener(again.typef2,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.typef1);
        
    dispatchEvent(again); //calls f2();
    //end of f1

    public function f2(e:Event):void
    {
        
    e.preventDefault();
        
    e.stopImmediatePropagation();
        
    e.stopPropagation();
    stage.addEventListener(reload.typef1,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
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center