Flash syncronicity problems
I’ve spent this week developing a Flash application that allows simple image-based exercises to be authored quickly; it uses an XML source file to create a manifest of exercises and images, with audio narration support and a magnification tool that allows users to explore graphs and diagrams. This specific application will be used for a WMG module where the students will explore six-sigma and other methods of quality control by going through a range of exercises.
For this application, I’ve been using Flash’s XML Connector component; I previously got very stuck using this, but this time I was able to easily configure the component to populate a combobox and to have changes on that combobox affect the contents of another. Thanks to the FAAD course I used event listeners and handlers to trigger all updates and used fake dispatchEvent handlers to trigger data population on load. This appeared to work fine, except for one thing; when triggering the update event to a combobox that used the XML Connector, an event from one combobox triggered an image reload from the other before it had a chance to refresh itself with new XML data – resulting in the requested image being the image already selected. Put simply, I had a timing problem. Tracing the event sequence proved this was the case.
At the same time, Paul sent me an example .fla he is working on that loaded images into a movie and performed a dynamic resize; this was having the same problem – performing the resize wasn’t working because the function was being invoked before the object had loaded, resulting in no resize. I had a resize function already working in my application but it was using onClipEvent(data) handlers directly on each loaded object to increment an ‘I’m loaded’ variable – not the best solution because it meant I had script and variables all over the place, and we were both having to create Library objects and have them physically on stage to hold each image – what if we need to dynamically create and load more image objects?
After an afternoon of scratching my head, and some doomed experiments with LoadVars, I found the answer; use createEmptyMovieClip as a holder for each image then use a simple preloader check. The MovieClip class has a couple of methods available to it that mean you can easily check if the image has loaded fully; getBytesLoaded() and getBytesTotal(). Do a small calculation using these (e.g. within an onEnterFrame function) and you can easily check to see if your image data is all there, then you can go ahead and perform functions on it.
For my application (the XML delay problem), I used a slightly different technique; in my fake event dispatcher from the combobox, I set a variable within a setInterval function that looped avery 500ms or so, checking the contents of the target combobox against the stored value on every loop; as soon as it sees a change (which means that the contents of the combobox have been updated), it actually dispatches the event, clears the interval timer, and the problem is fixed. It’s a hack, but it works
This is the first time I’ve come across these syncronicity issues in Flash, but they are likely to appear when external data needs to be imported. The rule is that objects or data that you are trying to load in from an external file or source are extremely likely to complete after your script executes, so you have to find ways of checking for the existence of your data before you can try and manipulate it. This will of course depend on the type of data you are loading; if it’s simple text or variables, LoadVars() is your friend; if it’s an image, write a preloader; if it’s XML or similar data, try an onLoad() event handler. And if all else fails, use setInterval timers to force your script to wait until you know for sure that you have your data.

