I have a little problem.
The environment
Environment: Flex 3 (actually updated to Flex 4 SDK, but still using mx instead of spark)
IDE: Flash Builder 4.6.
Browser: Firefox 14.0.1
Flash player version: FP 11 Debugger - 11.2.202.235
States syntax: Flex 3 style syntax.
The application
I have an application.
This application has several states.
One of the states has, in turn, a "wrapperComponent
" with three different states: the base state (i.e. ""), "firstState
" and "secondState
".
Simplifying it a bit, pretty much what each of those states contains is a different custom component, like this:
- "
wrapperComponent
" -> "base comp.
" - "
firstState
" -> "first comp.
" - "
secondState
" and "second comp.
"
The following image shows the situation more clearly:
Then, when the user is using the "wrapperComponent
" it first reaches the "firstState
", then he uses the "base state
" and after that, he goes to the "secondState
", like the following picture shows:
So, the problem is...
So, the problem is that when the user reaches the third step in the flow, i.e. when he reaches the "secondState
" of the "wrapperComponent
" sometimes the "second comp.
" appears, and sometimes it does not appear.
The findings so far...
Discussion in Adobe forums: http://forums.adobe.com/message/4621058 3
After struggling with this for about two weeks, I came to the semi-conclusion that somehow, the internal flow of events in ActionScript is halted.
This means that, when my custom component called "second comp.
" doesn't show up on the screen:
- the transition from the "
base state
" to the "secondState
" is stopped/paused/halted, - only some of the events of the "
second comp.
" are dispatched ("preinitialize
", "initialize
", "add
", "added
" are dispatched) but some others are not: "addedToStage
" and "creationComplete
" are not dispatched. - the variable "
activeEffects
" of both the "base comp.
" and the "second comp.
" contains effects that are not played (like "RemoveChildActionInstance" or "AddChildActionInstance") and - the variable "
updateCompletePendingFlag
" variable of these same components' value is "true
", meaning that they haven't finished updating.
The ugly hack
I found a really horrible way of circumventing the problem, with this workaround:
- I set up a 500ms Timer that starts counting when the state has to change from "
baseState
" to "secondState
" (that is, from step 2 to step 3 in the image above) - When this Timer sets off, I check whether or not the components (i.e. "
base comp.
" or "second comp.
") have any pending effect or if their "updateCompletePendingFlag
==true
". - If the check yields true, then I force the call of a
validateDisplayList()
method on that particular component.
The code looks something similar to this:
...
if ( toState == STATE_SECOND ) {
var theTimer : Timer = new Timer(500,1);
theTimer.stop();
theTimer.addEventListener(
TimerEvent.TIMER_COMPLETE,
theTimer_complete_Hdl,
false, 0, true
);
theTimer.start();
currentState = STATE_SECOND ;
}
...
And the timer calls this function:
private function theTimer_complete_Hdl(event:TimerEvent):void
{
if (secondComp.updateCompletePendingFlag)
{
secondComp.invalidateDisplayList();
secondComp.validateDisplayList();
secondComp.validateNow();
this.invalidateDisplayList();
this.validateDisplayList();
}
...
}
Problems...
This is really dirty, unelegant code. Plus, it's giving me bad user experience, because it takes more than one second to refresh the screen, and the movement is not swift.
My guess is that it's somehow negatively affecting the performance.
**Any ideas on what could be happening or a better way to force FlashPlayer to continue playing the effects instead of killing them and forcing an updateDisplayList?**
Thank you guys!!! :-)