Is flash.utils.Timer object's event TIMER always dispatched before TIMER_COMPLETE?
During the 2nd event, I am nullifying stuff that are required during the 1st event; so their order is of prime importance. I checked the docs and there is no guarantee for their dispatching order.
In tests I've done it seems that this is the case, but I don't want to distribute publicly software without confirming first.
You can avoid this problem by using TimerEvent.TIMER only:
private function onTimer(event:TimerEvent)
{
// ...
if (timer.currentCount == timer.repeatCount) {
// timer is complete
}
}
I'm almost positive this is the case, since the code seems to be in the player itself I don't think you can get at the source to get a legitimate confirmation, however I have always seen this to be the case myself and from how the docs read it sounds as though a TIMER event would always be dispatched before the complete event
timerComplete
Dispatched whenever it has completed the number of requests set by Timer.repeatCount.
timer
Dispatched whenever a Timer object reaches an interval specified according to the Timer.delay property.
So I imagine the timerComplete is dispatched after it receives enough timer events that the currentCount equals the repeat count then a timerComplete is dispatched, however without being able to look at the code it's impossible for anyone to completely confirm this. Possibly you could look at the Gnash source to see how it's handled by that implementation of the player, but it's not necessarily the same in the normal Flash Player.
Related
Usually when dispatching an Event (or custom Event) I use this:
function fireEvent():void {
dispatchEvent(new Event(Event.COMPLETE));
}
Is better use a single object to dispatch an event every time? Can I do this?
var myEvent:Event = new Event(Event.COMPLETE);
function fireEvent():void {
dispatchEvent(myEvent);
}
It would be a way better (eg create event pools) if it works. Unfortunately AS3 does some internal magic with event object during event flow which makes objects only one time usable (Sorry, by some reason I can't find proof quickly).
You can easily get confirmation by dispatching event second time, your listeners will not be triggered (may be it's true only for bubbling feature, not remember exactly), so you have to create a new instance of event object for every dispatchEvent call.
It doesn't worth it even if pooling works, I presume. Creating event objects isn't expensive in astionscript, adding event listeners is. You'd better put this effort on managing listeners and handlers which could easily become the performance buttleneck.
Sometimes I'm coding in a wrong way my polymer 1.0 web app and stuff stops to work properly. Like setting data to some custom element and then immediately trying to read some data out of it (that depends on the data just set) (because I don't know better). Sometimes this doesn't work. Most of the time this.async will help me out, but sometimes it will not. However, setTimeout has never ever failed me in these kind of situations. Most of the time calling setTimeout without providing wait time will work just as well.
For a long time I thought that this.async(function(){...}) is the same as setTimeout(function(){...}). Because sometimes code inside this.async will fail to see changes in custom element's data while code inside setTimeout will not.
Are these two methods are implemented in different way?
this.async adds your function to the start of the event queue, while setTimeout adds it to the end. If you use setTimeout other functions may have been executed before your function is called, causing the changes that you can see in your data.
From the documentation of this.async:
If no wait time is specified, runs tasks with microtask timing (after the current method finishes, but before the next event from the event queue is processed)
setTimeout on the other hand will add your function to the end of the queue as is described in the section "Adding Messages" of this article.
Calling setTimeout will add a message to the queue after the time passed as second argument. If there is no other message in the queue, the message is processed right away; however, if there are messages, the setTimeout message will have to wait for other messages to be processed. For that reason the second argument indicates a minimum time and not a guaranteed time
Now I am working on Flex 4 with AS3. In most of time I am using the addEventListener.
This listener default arguments are type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false. But most of the developers doesn't consider the last 3 arguments. But I want to know the uses of these 3 arguments?
Anyone call tell me answer?
Most of the times those three last parameters aren't necessary, because it's usually better to use a programming pattern to manage dependencies rather than leaving it to hard-to-debug spaghetti code that goes through many other classes.
Yet, there is a purpose for them and they can come in very handy:
useCapture - To register a listener with an event target’s ancestor for the capture phase of an event
dispatch, we set addEventListener( )’s third parameter, useCapture, to true, as in:
theAncestor.addEventListener(myEvent, MyListener, true);
The code causes MyListener( ) to be executed whenever AS3 dispatches myEvent targeted at one of theAncestor’s descendants before that descendant receives notification of the event.
priority - if you add more than one event listener to an object, the one that has higher priority will be triggered first. If you add two or more listeners with same priority, the one that was added first will trigger first. Just imagine that upon creating an object you've added an event listener, but later on you need to add another one and you want that new one to run first. Registering it with higher priority should do the trick.
weakReference - this is not a commonly used one, because Flash's garbage collector can run any time or even never. The problem is that regardless of any use of weak references, an object may continue to dispatch and listen to events until it gets garbage collected.
By default, an object that registers a listener
for a given event maintains a reference to that listener until it is explicitly unregistered
for that event—even when no other references to the listener remain in the program.
By setting the value to true the object will lose the reference to the listener when the object is eligible for garbage collection.
It's used to prevent memory leaks, but useWeakReference only has an effect when the listener object has a shorter lifetime than the dispatcher. It's a good idea to understand how to use it, but in practice I avoid it and simply write a method in my class that would remove all the added listeners.
first I'd like to thank you for taking the time to read my question.
So, I've made a little flash game(can't really call it a game), anyway at one point I'm checking for if 2 objects hit each other. So to sum it up here's the code
public function loop(e:Event):void
{
y += vx;
if(y > stageRef.stageHeight || y < 0)
removeSelf();
if(hitTestObject(target.hit))
{
removeSelf();
stageRef.dispatchEvent(new GameOverEvent(GameOverEvent.DEAD)); // <--
stageRef.addChild(new SmallImplosion(stageRef, x, y));
}
}
So, when they collide, one object dispatches an event, there is no problem with the code, it works, but I would like to know if it's good to make handle it this way. stageRef is the reference to stage, both classes have it.
And my other class catches that event and it triggers a function, like this:
stageRef.addEventListener(GameOverEvent.DEAD, takeHit, false, 0, true);
The question is, is this a good way to handle it? Thank you in advance!
When implementing the observer pattern, each of the participating objects has a clear role: One is the subject, who is the object where the action is happening, while the other is the observer, who listenes for events on the subjects. In Flash, any object can be the observer, as you pass the handling function to the subscribe-method. Subjects however implement IEventDispatcher and provide the necessary methods to subscribe to the subject. There is also the standard implementation EventDispatcher which already implements the necessary methods (and many types are subtypes of it).
Now back to your question; you are essentially bringing in a third party, the stage where the events are broadcasted on. Instead of having the events that are local to the subject dispatched on the subject itself, you are dispatching them over the global stage, and all observers have to listen to the stage instead of the subject itself.
This is generally not what you should do. Every subject (IEventDispatcher) should only dispatch its own events. Just like you receive a click event from the button that is clicked, you’d receive a GameOverEvent from the object that triggers it.
From the name GameOverEvent, I believe a bit of significance is implied. Since there's plenty to do at the end of a game, I feel it's appropriate for your stage to listen for an event such as this.
However, don't use this technique to handle any smaller systems. For example, if the collision only dealt some damage to the player (I don't know if this even makes sense in the context of your game but roll with me here) then it would be better to have the classes that check for collisions and the classes that handle health to interact directly with one another instead of firing these "Grand Events".
I'm debating two approaches to a pretty typical problem: Knowing when an event occurs or responding to it immediately if it already HAS occurred.
In approach one, a user of MyLoader1 adds an event listener which will be fired immediately if the loader is already complete.
class MyLoader1 extends EventDispatcher
{
private var _isComplete:Boolean = false;
public override function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
{
super.addEventListener(type, listener, useCapture, priority, useWeakReference);
// if the operation is already complete, immediately notify listeners
if(_isComplete)
{
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
class Application1()
{
function main():void
{
new MyLoader1().addEventListener(Event.COMPLETE, onComplete);
}
}
In approach 2, a user of MyLoader2 must first check the completion status of MyLoader2 before deciding whether to proceed or add a listener, which is fired later.
class MyLoader2 extends EventDispatcher
{
private var _isComplete:Boolean = false;
public function get isComplete():void
{
return _isComplete;
}
}
class Application2()
{
function main():void
{
var loader:MyLoader2 = new MyLoader2();
if(loader.isComplete)
{
// passing null just to simplify the example
onComplete(null);
}
else
{
loader.addEventListener(Event.COMPLETE, onComplete);
}
}
}
What advantages/disadvantages are there to each approach? Is there a design pattern out there that I could/should be using for this situation?
I'm leaning towards the first because it requires less knowledge of the Loader class and less code to leverage it. It could potentially create unwanted side effects when there are multiple listeners though, because the event will fire once for each time a listener is added.
The second method is understandable and easier to debug, but requires more up front work and seems to break encapsulation of the Loader.
I like your first approach better. I don't think that dispatching one event for each listener added is a problem, though; in fact, that's the very idea behind the event mechanism. If you have N objects that want to be notified whenever FooEvent occurs, you have to dispatch the event for each one whenever this event takes place.
Having said that, I wouldn't dispatch the event in the addEventListener method; I think that's the unwanted side effect, really. It goes against anyone's reasonable expectations. Adding a listener should not cause the event to fire. It should just register a listener. You should check whether the data is already loaded in your load function and dispatch the event there if the data is available (because at that point your load operation completed; not when you added the listener).
Another thing: I understand that you want to dispatch immediately if possible. But this has a problem, that can be serious and lead to annoying and not so obvious bugs. If you dispatch immediately you basically have 2 interfaces: one asynchronous and one synchronous. It's possible to handle this correctly in the calling code, but it requires more work and it's quite error prone, especially if you have chained events somewhere (I've made the error of having this kind of async/sync loader and I learned this the hard way).
It's much simpler and it makes almost no difference to delay the dispatching of the event in case the data is available right away. Just a tiny delay to make the code that handles the event run asynchronously (setTimeout(dispatchComplete,10) will do it), in a different stack frame that the code that called the loader. You'll save yourself some troubles and make your calling code simpler, which I think is what you're after.
Though slightly off topic, I would suggest you give signals a try. It depends on what kind of events you are using (ie. Mouse Events would still require the as3 Event so for some instances it might be a bit of extra work), but I've found signals a lot cleaner to implement, and for custom events, it is my preferred choice.
using a signals I usually set up one static var that acts as the main controller. I find this is better than the interconnected chain of Event Listeners and Dispatchers. You could have all the commands driving your app/game/website going through this one funnel.
The reason I'm bringing this up is that if you go this route, you essentially have a listener before you have the event. So if an object is created after the event has taken place, you could have it poll for whether an event occoured, and the addOnce() function is good for loaders and other events that are expected to happen once only. So while this does not answer your question, I hope it adds to the confusion :)
there's a link here to give you an idea of how it works
http://johnlindquist.com/2010/01/21/as3-signals-tutorial/