Troubleshooting Flash Events - actionscript-3

I wanted to ask any Flash gurus here if they have any best practices for troubleshooting Flash (custom) Events. I'm currently dealing with a couple of events that are supposedly being dispatched but never caught by the corresponding listeners.
Here is the list of things I've already checked for:
Event names are defined as a String const in the custom event and the event name is used in the listener.
Checked for Event bubbling (as explained here).
If anyone has any suggestion, It will be much appreciated.

I believe most frequent mistakes are:
1. Event listener added after event being already dispatched.
2. Non-overriden clone() and toString() methods for custom event.
3. Simply listening wrong objects/wrong events.

Related

Firing a KeyDown event in WinRT

Is there a way to fire a custom KeyUp/KeyDown event on the CoreWindow?
For example, take the following event:http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.core.corewindow.keyup.aspx.
My application already uses CoreWindow::KeyUp and CoreWindow::KeyDown to handle events. I am trying to test that the correct delegates are being attached and thus called when an event happens.
Note that I can't call the delegate function directly since it will not test the fact that the delegate is attached to the event.
I am looking for an answer similar to https://stackoverflow.com/a/3977396/756356.
I doubt that's possible because it sounds like something possibly interfering with the sandbox concept of modern apps. You could maybe insert some layer between the CoreWindow and your handlers and bubble the events through that layer to make is possible to raise your proxy events. I would recommend against that though since that just adds code you don't need.

AS3 Event architecture

I'm having difficulty with the last piece in the puzzle on AS3 events.
I understand target classes inherit from EventDispatch or implement IEventDispatch and can register (amongst other methods) event listeners.
However what do the target classes register with? If an Event happens, how does AS3 know to pass the Event to the target classes?
Regards,
shwell.
Read this article about event phases and it will make more sense:
http://livedocs.adobe.com/flex/3/html/help.html?content=events_02.html
Hope this helps. Have a great day.
You can look at how starling event works
starling even dispatcher
When a displayObject bubbles an event, it will check if the parent of the displayObject exist and add the parent to bubbleList if exist util the ancestor of displayObject is null.
The following code is in starling eventDispatcher
var element:DisplayObject = this as DisplayObject;
var chain:Vector.<EventDispatcher> = new <EventDispatcher>[element];
while ((element = element.parent) != null)
chain[int(length++)] = element;
In AS3, EventDispatcher is an implementation of the observer design pattern. This class implement the addEventLister, removeEventListener, dispatchEvent' andhasEventListener` methods. Internally, it also maintains a dictionary or similar data structure that contains the events which are currently being listened for, and a list of methods which have to be called when the event is dispatched. Something like this -
{"event1": [method7, method5, method3], "event2": [method3, method2], "event3": [method1]};
When addEventListener is called on an object, it creates a new key for the event in question and adds the method reference to its associated value list.
When dispatchEvent is called on the class, it fetches all the methods associated with the event and calls the methods attached with it. Each method is called with an instance of the Event class or its subclasses.
Removing an event listener obviously does the opposite of what adding does.
I guess you're missing of addEventListener() mechanics. This thing has a global side effect on event engine, registering a callback function along with caller this value to provide correct context of a fired event, with possible update of event.localX and event.localY properties by calling globalToLocal() either statically or dynamically, as the event bubbles up and down.
If you are, like me, confused about how does Flash player determine the target of an event - there is an internal "focus" pointer that determines which component of the SWF has keyboard focus, and that one is used to target keyboard events. For mouse events, most likely Flash engine calls getObjectsUnderPoint() to query for topmost IEventDispatcher compatible objects (not all of the DisplayObjects can process events), and that one is sent a mouse event, with the previous event's target to receive a say MouseEvent.ROLL_OUT or MouseEvent.MOUSE_OUT if the target has been changed. For other events, most likely the entire display list can react.
For objects in the display list, the following excerpt from Adobe is the answer "When Adobe® Flash® Player dispatches an Event object, that Event object makes a roundtrip journey from the root of the display list to the target node, checking each node for registered listeners.".
For non display objects, AS3 run time maintains a dictionary of all AS3 events containing bound variables. The bound variables are a reference to the event listeners.

Should I remove listener for SOUND_COMPLETE event?

My application needs to notify UI that sound playback is finished. To accomplish that is attaches listener to the SOUND_COMPLETE event of a SoundChannel object.
Should I remove my SOUND_COMPLETE event listener after event processing is done?
private function playbackCompleteHandler(event:Event):void {
// Notify UI that playback is done etc
channel.removeEventListener(Event.SOUND_COMPLETE, playbackCompleteHandler);
}
Everyone says that we should always remove event listeners so that GC could properly collect objects ('channel' object in this case). But it seems that Adobe doesn't do that in the official documentation [1][2]
[1] http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/SoundChannel.html
[2] http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7d21.html
Dispatcher holds listeners, so, if your dispatcher is long-living(like Application), you should use weak listeners:
channel.removeEventListener(Event.SOUND_COMPLETE, playbackCompleteHandler,false,0, true)
last true allows your objects to be freed.
If you don't need your temporary objects to process dispatcher's events after you loose all references to temporary objects and until they are collected, you shall remove listeners
Otherwise(when dispatchers are short-living), there is no need to care about listeners: if you are listening to something temporary, it will die without any problems.
It seems that your case is the last one, so it's better not to pollute code with meaningless lines.
You're question states my answer for this
Everyone says that we should always remove event listeners so that GC
could properly collect objects
If you are no longer keeping an instance of the Sound object around; then remove the event listener. If you will still be using the Sound object; then there is no need to remove the listener.

flex 4 - why dispatchEvent triggering creationComplete recursively

I have a custom component called shopView which is an MXML skinnable component. I have a controller class called ShopController which takes care of showing this component in popup, updating info shown in the component etc.
Now, I wanted to maniupate some of the subcomponents of this ShopView after it has been created from the controller after the ShopView is created (creationComplete() event)
So, I have attached an event listener which intern does some initialization process
creationComplete="init(event)"
the init() function
private function init(event:FlexEvent):void{
event.stopImmediatePropagation();
initMenus();
initSlots();
dispatchEvent(event);
}
Attached another creation complete event from the controller class
_shop.addEventListener(FlexEvent.CREATION_COMPLETE,onShopCreated);
*_shop is the instance of ShopView*
Now, if you see the init() function, there I am stopping the event propagation, doing some initialization process and after that I am dispatching the event (for the shop controller do the rest of the job)
Now, this is crashing the app because the crationComplete event of the ShopView is recursively called. I was thinking the dispatchEvent will propagate to the other listerners but seems like it is propagating back to the same component.
I have fixed it by removing the e.stopImmediatePropagation() and dispatchEvent(event) lines from the init() function. But I want to know why it is happening like this?
Is it a known issue for the mxml/flex components? OR it is expected behavior?
Update: I am not doing same in .as as I said below. Got answer, basically its my stupidity :)
because I have not seen this behavior when I write .as classes where I
stopevent propagation and dispatch the event based on business logic.
Thanks in advance.
This is expected behavior.
When you redispatch an existing event dispatchEvent automatically clones it (since you can't dispatch the same event twice.) This clears any propagation-related flags.
May I ask why you want to redispatch CREATION_COMPLETE in this situation anyway? Both handlers will function just fine without the two lines you removed.

What do you think about NResponder?

I was on the point of start using AS3 Signals for my new project because Native Events has a bad reputation, and then I found this:
http://code.google.com/p/nineveh-responder/
But I couldn't find more information (in addition to official docs and tuts).
What do you think about NResponder?
OT: I can't create the tag "NResponder" in this question because is new :(
NResponder goes above and beyond the call of duty. It is soo easy to use and learn. The real difference maker is its NResponder.remove(action,function,target) method.
It has the ability to remove all event listeners that fall under the parameters provided. In one call, you can remove all listeners associated to one object(target), any listeners associated to a certain function, listeners that respond to a certain event like MouseEvent.CLICK, or any combination of these parameters.