I have a Flash application that creates a sort of powerpoint presentation.
All the ‘slides’ are stored in an XML files which is read and processed.
I’m trying to build the presentation using this XML file.
At the moment, my main class has it’s initial function main and a static function processXML
main initiates my database class with a function called initDB. One of my issues is that initDB forgoes processing because it’s dependant on an event listener. On completion of loading the XML files, the event listener initiates my static function on my main to create objects from this file.
The issue is that because the event listener continues the processing (after an indeterminate amount of time), the functions are no longer controlled by the main class.
Normally, in this situation, I’d avoid the use of statics because I’d control processing from the main function by using returns on processing – i.e. a function that returns a value to pull control back to the caller class.
Now, all this has had a knock on effect and I can’t use addChild calls, or indeed any similar calls because the function is static.
If you could spare some time, I really need to re-think the way my files work.
Main Class
public static var databaseXML:XML;
public var database:ContentDatabase = new ContentDatabase();
public function main()
{
database.initDB();
}
public static function processXML()
{
//Get First Slide
var introSlide:SlideLayout = new SlideLayout();
var allSlides:XMLList = main.databaseXML.children();
var introSlideXML:XML;
for each (var slide:XML in allSlides)
{
introSlideXML = slide;
break;
}
var theSlide:MovieClip = introSlide.createSlide(introSlideXML);
addChild(theSlide); //Fails, Obviously
}
ContentDatabase Class
private var xmlLoader:URLLoader;
public function initDB()
{
xmlLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE, onComplete, false, 0, true);
xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError, false, 0, true);
xmlLoader.load(new URLRequest("resources/slides.xml"));
}
private function onComplete(e:Event):void
{
try
{
main.databaseXML = new XML(e.target.data);
xmlLoader.removeEventListener(Event.COMPLETE, onComplete);
xmlLoader.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
main.processXML();
}
catch (err:Error)
{
trace('broke: ' + err.message);
}
}
private function onIOError(e:IOErrorEvent):void
{
trace('broke: ' + e.text);
}
I’m open to all ideas about how I structure this project to allow me this kind of communication.
Ideally, I’d like the ContentDatabase class to hold nothing but XML processing.
Your Main & ContentDatabase classes are too tied up!
Your data is contained in an XML file, practically you need to first load the file, parse , organize & store the data, then you can manipulate this data.
I disagree with Sr.Richie, a Singleton is really not needed here.
ContentDatabase should simply care about loading the XML , ideally the source url shouldn’t be hardcoded in the class.
For instance , you could pass the url as a parameter to the initDb method
After the data has been loaded, good practice would be to dispatch an event to inform the Main class that the data is ready. You could use a CustomEvent or use a Signal and pass the data as an Object. In this way you wouldn’t have unnecessary dependencies between the Main and the ContentDatabase classes.
Then in your Main class
There are several ways to dispatch & listen to Events between the Main class & the ContentDatabase. As mentioned above , you could use Signals. You could also create a light dependency by passing an event dispatcher to the ContentDatabase. You do that to ensure that the same dispatcher listens to and dispatches event.
Then in the ContentDatabase contstructor…
then in processXML()
And of course in your Main class
Although it is possible to use an XML as a native AS3 object, I often prefer to create my own Object or Class, populate it with the XML data so that I can call its properties directly , instead of having to query the XML , but that’s personal taste…