A Flash Developer Resource Site

Results 1 to 5 of 5

Thread: I've had it with custom events. Someone help me figure this stuff out!

  1. #1
    Member
    Join Date
    Apr 2006
    Posts
    37

    I've had it with custom events. Someone help me figure this stuff out!

    I've been running into a billion problems while creating custom events, so I clearly don't understand some of the basics. All the examples I've found online are unnecessarily complicated, so I've gone ahead and created a super simplified version of how I think it should work. The results are in bold...

    Code:
    // DOCUMENT CLASS //
    
    package {
    	
    	import flash.display.MovieClip ;
    	
    	public class DocumentClass extends MovieClip {
    		
    		public function DocumentClass() {
    			
    			var iListen : CustomEventListener = new CustomEventListener() ;
    			var iSpeak : CustomEventDispatcher = new CustomEventDispatcher() ;
    			
    			iSpeak.dispatchCustomEvent(); 
    			// DOES NOT WORK //
    			
    			this.dispatchEvent( new CustomEvent( CustomEvent.SOMETHING_HAPPENED ) ) ; 
    			// DOES NOT WORK //
    			
    			iListen.dispatchEvent( new CustomEvent( CustomEvent.SOMETHING_HAPPENED ) ) ; 
    			// WORKS //
    			
    		}
    		
    	}
    The way I understand it, you should be able to dispatch a custom event from wherever, and then any object that is listening for it should be able to hear it. So how come my CustomEventListener can't hear anything outside of itself?

    The rest of the code...

    Code:
    // CUSTOM EVENT LISTENER //
    
    package {
    	
    	import flash.display.MovieClip ;
    	
    	public class CustomEventListener extends MovieClip {
    		
    		public function CustomEventListener() {
    			
    			this.addEventListener( CustomEvent.SOMETHING_HAPPENED , iHeardWhateverJustHappened );
    			
    		}
    		
    		private function iHeardWhateverJustHappened( e : CustomEvent ) {
    			
    			trace( "I heard whatever just happened from... " + e.currentTarget ) ;
    			
    		}
    		
    	}
    	
    }
    Code:
     // CUSTOM EVENT //
    
    package {
    
    	import flash.events.Event ;
    	
    	public class CustomEvent extends Event {
    		
    		public static const SOMETHING_HAPPENED : String = "something happened" ;
    
    		public function CustomEvent( type : String , bubbles : Boolean = false , cancelable : Boolean = true ) {
    			
    			super( type , bubbles , cancelable ) ;
    		
    		}
    
    		override public function clone() : Event {
    			
    			return new CustomEvent( type , bubbles , cancelable ) ;
    			
    		}
    		
    	}
    	
    }
    Code:
    // CUSTOM EVENT DISPATCHER // 
    
    package {
    	
    	import flash.display.MovieClip ;
    	
    	public class CustomEventDispatcher extends MovieClip {
    		
    		public function dispatchCustomEvent() {
    			
    			this.dispatchEvent( new CustomEvent( CustomEvent.SOMETHING_HAPPENED ) ) ; 
    			
    		}
    		
    	}
    	
    }
    Any help is appreciated.

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    By "DOES NOT WORK" I assume you mean that it does not trigger the listener function rather than it causes some sort of compiler or runtime error.

    In order for an event listener to trigger, it has to be added to either the dispatching instance or another object which will get that event through bubbling. In your case, since your dispatchers are not on the displayList, the events will not bubble anywhere.

  3. #3
    Member
    Join Date
    Apr 2006
    Posts
    37
    Ah, right. I was just reading up on that, and it pretty much said the same thing, but I don't really understand how bubbling works very well. From what I understand, it goes to the original object, then to its parent, then all the way up to the stage.

    I tried this...

    Code:
    package {
    	
    	import flash.display.MovieClip ;
    	
    	public class DocumentClass extends MovieClip {
    		
    		public function DocumentClass() {
    			
    			var iListen : CustomEventListener = new CustomEventListener() ;
    			var iSpeak : CustomEventDispatcher = new CustomEventDispatcher() ;
    			
    			stage.addChild( iListen );
    			stage.addChild( iSpeak );
    			
    			iSpeak.dispatchCustomEvent(); 
    			// DOES NOT WORK //
    			
    			this.dispatchEvent( new CustomEvent( CustomEvent.SOMETHING_HAPPENED ) ) ; 
    			// DOES NOT WORK //
    			
    			iListen.dispatchEvent( new CustomEvent( CustomEvent.SOMETHING_HAPPENED ) ) ; 
    			// WORKS //
    			
    		}
    		
    	}
    	
    }
    But same deal.

    Am I missing something really basic? I just need someone to show me how this stuff should be structured. I keep thinking that event listeners can hear any event that dispatches, but that's probably very wrong.

    EDIT: I tried making the event dispatcher a child of the event listener object, like so...

    Code:
    addChild( iListen );
    iListen.addChild( iSpeak );
    			
    iSpeak.dispatchCustomEvent(); 
    // DOES NOT WORK //
    But no dice there either. I'm totally lost here.
    Last edited by Sub Tank; 03-01-2009 at 06:45 PM.

  4. #4
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    In that code, the event dispatched by iSpeak would bubble up to the stage, but not back down to iListen, so you haven't fixed anything (as you know).

    Here's one way which uses bubbling:
    Code:
    package {
    	
    	import flash.display.MovieClip ;
    	
    	public class DocumentClass extends MovieClip {
    		
    		public function DocumentClass() {
    			
    			var iListen : CustomEventListener = new CustomEventListener() ;
    			var iSpeak : CustomEventDispatcher = new CustomEventDispatcher() ;
    			
                            addChild(iListen);
                            iListen.addChild(iSpeak); // since iSpeak is a child of iListen, events will bubble up
    
    			iSpeak.dispatchCustomEvent(); 
    			
    			this.dispatchEvent( new CustomEvent( CustomEvent.SOMETHING_HAPPENED ) ) ; 
    			// DOES NOT WORK because event bubble only up.//
    			
    			iListen.dispatchEvent( new CustomEvent( CustomEvent.SOMETHING_HAPPENED ) ) ; 
    			// WORKS //
    			
    		}
    		
    	}
    	
    }
    Here's a version without bubbling:
    Code:
    package {
    	
    	import flash.display.MovieClip ;
    	
    	public class DocumentClass extends MovieClip {
    		
    		public function DocumentClass() {
    			
    			var iListen : CustomEventListener = new CustomEventListener() ;
    			var iSpeak : CustomEventDispatcher = new CustomEventDispatcher() ;
    			
                            iSpeak.addEventListener(CustomEvent.SOMETHING_HAPPENED, iListen.iHeardWhateverJustHappened);
    
    			iSpeak.dispatchCustomEvent(); 
    			// DOES NOT WORK //
    			
    			this.dispatchEvent( new CustomEvent( CustomEvent.SOMETHING_HAPPENED ) ) ; 
    			// DOES NOT WORK //
    			
    			iListen.dispatchEvent( new CustomEvent( CustomEvent.SOMETHING_HAPPENED ) ) ; 
    			// WORKS //
    			
    		}
    		
    	}
    	
    }
    You will have to make iHeardWhateverJustHappened public for this.

    I suspect that you want a pattern that I call an EventManager (though it may have an official name I'm not aware of). Basically, there's a Singleton class to be a global broker for events of a certain type. All listeners register themselves on the Manager, and all dispatchers instead call the dispatch method of the Manager. In this way, displayList structure is completely irrelevant, and you get more-or-less broadcast events.

    There is a very good reason that events are not broadcast by default. If everything with a MouseEvent.CLICK listener heard every click, it would be a real pain in the butt to make buttons behave appropriately, for instance.

  5. #5
    Member
    Join Date
    Apr 2006
    Posts
    37
    Nailed it! Thanks a bunch!

    I forgot I had bubbles = false, but it wouldn't have worked until I did what you just showed me.

    I'll have to look into Event Managers. I can think of a few cases where I'd want events to broadcast.

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