The other day I found myself with nothing do in the late evening and thought and improving book might be just thing. I find a good software manual the perfect subject for a prerequiste to slumber.
The choice was a title I had lying a round for a while. But, had not had the mental agility to tackle earlier. I had gotten a few good naps from the title earlier before moving on to other topics.
The subject of loaders had been coming up all week. I had been working with the Load_Content class with my students, I had also created an AS3 version of the venerable ImageStreak class, and moved on to a, soon to be realease, image loading masking effect thing.
At this point the material in the book was finally hitting home. The book by the way is: Advanced Actionscript 3.0 with Design Patterns. We’ll just stick to calling this title “The Book” for the rest of this post. The name seems to be doing pretty well for itself so far. And it’s growing on me.
The Book, says there are several different types of Class files that you can write. The first time through I figured this stuff was for those smart guys that really knew what they were doing. Or, for the larger more involved projects written by people that like to type for days.
It was the loader class that really made the ideas hit home. Imagine you want to load an image. In AS you need to create an instance of the Loader class. Create an instance of the URLRequest class. Then follow these up with a listeners. More work than the old AS2. But worth it.
For example:
var loader = new Loader();
loader.load( new URLRequest( url ) );
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, on_complete );
loader.contentLoaderInfo.addEventListener( ProgressEvent.PROGRESS, on_progress );
Of course then you go and make a class that loads an image and works with it. Like the ImageStreak. Then, you go and do it again with another class. Of course you are writing the few lines and you’re just happy to see it all work.
But it it could work better! Back to The Book. An important idea presented is the Abstract class. This is a class that presnts the base properties and methods of a class. It sounds like the Abstract is usually meant to be extended. Think about it in terms of class that load images. All of these classes would need the same basic functionality. They need to load an image. Other classes that need to load an image could extend this class.
The Abstract Loader class would need to provide only the load method. Of course this means that all these many loader classes that will be extending Abstract Loader will also need to include a load method. Of course this easy to remember. Expecially when you have such an excellent new compiler error system, and it’s fanciful messages. 1067: Implicit coercion of a value of type foo to an unrelated type bar anyone?
Of course The Book again comes through with a better way! The interface. An interface is not some fancy new button motion that’s sure to move your new site up the ranks of the FWA. Instead it defines a programming interface. A programming interface describes the method names, parameters and return types for a class. Or any number of classes.
Think about the many and varied image loading classes that you are going to create, by extending the Abstract Loader. They will all need to make use of Abstract Loaders load function. By defining it in interface and making all variants implement this interface you can be sure that your classes will all work correctly.
So what doesn it all look like, sleepy yet?
First step, we want to make a class that loads an image. Then we want to follow it up with a series of classes that extend this class and load images in new and interesting ways. All the classes will need to provide the same method to load images. So, and here’s the good part, we write an interface!
Here’s the interface, we’ll call it ILoader (the I is for interface):
package {
public interface ILoader {
function load( url:String ):void;
}
}
The interface defines a single function, it’s parameter and it’s return type. Note, that it doesn’t define the code block for the function. This is left to classes that implement ILoader.
The next step is to define the Abstract class. This will be a class that defines the basic functionality used by all the classes that will extend it. We’ll call this one AbstractLoader.
package {
import flash.display.*;
import flash.events.*;
import flash.net.*;
public class AbstractLoader extends Sprite implements ILoader {
public function AbstractLoader( url:String = null ) {
if ( url != null ) {
load( url );
}
}
public function load( url:String ):void {
var loader = new Loader();
loader.load( new URLRequest( url ) );
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, on_complete );
loader.contentLoaderInfo.addEventListener( ProgressEvent.PROGRESS, on_progress );
}
protected function on_complete( e:Event ):void {
dispatchEvent( new Event( Event.COMPLETE ) );
e.target.removeEventListener( Event.COMPLETE, on_complete );
e.target.removeEventListener( ProgressEvent.PROGRESS, on_progress );
addChild( e.target.content );
}
protected function on_progress( e:ProgressEvent ):void {
dispatchEvent( new ProgressEvent( ProgressEvent.PROGRESS, false, false, e.bytesLoaded, e.bytesTotal ) );
}
}
}
This class wraps the Loader class. It creates a loader instance and creates it’s own URLRequest Object. It also sends out it’s event messages for PROGRESS and COMPLETE events.
It also implements ILoader, implements is key word. This tells the Flash compiler to check this class against the interface it implements. This makes usre that this class provides the functions, parameters, return types, and class properties defined in the interface.
For all that extra work what do you get, Still awake? Answer, some pretty good error checking, but you knew that would be the case. With the creation of the Abstract class, you get all of the base functionality for many classes. This simplifies writing those new classes. No need to rewrite what you’ve alreay written. Where it really pays off is when you want to make a change. Adding a feature to the Abstract class adds that feature to all classes that inherit from it.
Wow, what fun. Take a look at the ImageStreak and CircleMask classes.