03.04.09
Have you ever had the need to make a line of code wait a second before executing? How did you go about trying to make that happen? Well, I for one did a Google search and came up with something using setInterval (AS 2.0), or using setTimeout (AS 3.0). Â Either solution will work, and probably looked something like this:
var wait1 = setTimeout(callback1, 3000);
function callback1():void {
trace("Wait 1");
};
The code above told Flash to wait three seconds before calling callback1, which traces "Wait 1". Â So, what if you needed to make two lines, or two blocks, or multiple blocks of code, you might have something that looked like this:
var wait1 = setTimeout(callback1, 1000);
function callback1():void {
trace("Wait 1");
};var wait2 = setTimeout(callback2, 2000);
function callback2():void {
trace("Wait 2");
};var wait3 = setTimeout(callback3, 3000);
function callback3():void {
trace("Wait 3");
};
Notice you have to manually add up the time delay to get the individual callbacks to fire at the right time. Â So, it'd be a great inconvenience if you needed to adjust the delay for wait 1, since you'll need to adjust the wait time for wait 2 and 3 as well. Â Plus, it's a hideous looking block of code. Â So, out of the goodness of our hearts, and for the benefit of all developerkind, we, Plexipixel, are going to make public one of the most useful utilities in our library, our Script class.
(Okay, it's not really for the benefit of mankind, or out of the goodness of our hearts, it's more like we wanted to drive some web traffic to our blog. Â So, thanks for visiting! Â Now, buy something, thank you.)
You can download the source code with examples here. Â The following code will do that same thing as the code above:
var cs:Script = new Script;
cs.call(this, function() {
trace("Start Script");
});
cs.wait(1.0);
cs.call(this, function () {
trace("Wait 1");
});
cs.wait(1.0);
cs.call(this, function() {
trace("Wait 2");
});
cs.wait(1.0);
cs.call(this, function() {
trace("Wait 3");
});
cs.start();
Besides being easier to read, you don't have to add up time. Â For space constraints I won't reprint the Script class itself here, but I will run through how to use it.
After you've imported the Script class and instantiated a Script object, you use wait, to add a wait, it takes time in seconds, so, half second would be 0.5.  Use call to call a function.  call takes two parameters, the first tells Script the scope of the function to be called.  The second parameter is the function to call, in the example above I used an inline function.  To call a function do the following:
var cs:Script = new Script;
cs.call(this, testFunction1);
cs.start();
function testFunction1():void {
trace("testFunction1 called");
}
So, what if you wanted the your application to wait for an indefinite time, like waiting for a MovieClipLoader to load something? Â We have that covered too:
var cs:Script = new Script;
var i:Number = 0;
cs.call(this, function() {
trace("i " + i);
i++;
if (i < 10) return false;
trace("Done");
});cs.start();
If you manually include a return false in your application it'll force the Script class to loop indefinitely, until you stop sending false, or send it a true.
Anyway, we hope you find this little utility helpful in your Actionscript endeavors.
Allen is a Flash Developer here at Plexipixel. When not hard at work, he enjoys long walks on the beach (no, not really), and journaling by the fireside (definitely not).
02.19.09
We were in need of a demo reel while the real one is being worked on, the closest thing we had was a slideshow that was part of a booth display, it was done in a hurry, with the intent of being shown on a local computer, and not over the web, composed of a player SWF externally loading multiple SWFs, varying between 40KB and 5MB, and of varying run time, totaling 35MB. To get it running smoothly for the web was going to be a challenge without completely redoing it.Â
To get the show on the web quickly, we first looked into converting the slideshow into either a FLV or QuickTime movie, to take advantage of the built in streaming abilities of the respective players. Even though the resulting movie ended up being smaller, the picture quality was unacceptable. The next step was to look into optimizing the player for web playback. Â
As a slideshow, there shouldn’t be any breaks in between the different SWFs, but with the player in it’s current state, the next SWF doesn’t get loaded until it is needed, which works in a local environment since loading a SWF is nearly instantaneous off a hard drive, but over the net, to say there’s a delay is an understatement. It’s obvious some sort of loader is needed.Â
We started with a simple loader that basically loads one SWF ahead of the currently playing SWF, it worked well enough for small SWFs, but when we hit the megabyters (SWFs of 1+ megabyte in size), we simply ran out of time before the next one is done loading. There were also instances where the next SWF is small and the current SWF is long in time, so we ended up with a lot of wasted time. So, we decided to get fancy and created what we’d like to call an “idle loader”.Â
The “idle loader” basically takes advantage of the Flash cache by loading additional SWF off stage whenever the next SWF is done loading and the current SWF is still playing, the “idle” part of “idle loader”. This loading scheme worked mostly, but had problems when multiple megabyters are queued up in a row. And code-wise, it felt needlessly complex, trying to balance what’s off-stage, dumping it, and loading it on-stage when needed. We’ve strayed from using a preloader because we wanted the experience to start right away, but at this point, looks like we’ll have to use a preloader.Â
We couldn’t just do a regular preloader and load all 35MB worth of SWFs at the start, because the wait time would be obscene even on a Comcastic® connection. We could just arbitrarily pick a number of SWFs to load, but it’s just not ideal since connection variances amongst our users. We have to get fancy once again, and create a semi-intelligent preloader, if we were to name it, it’d be called IntelliLoader®, but since Microsoft has the whole Intelli-Something cornered, we’ll just call it Steve®.Â
The first step to making Steve® intelligent would be finding out how fast the user’s internet connection is, similar to Netflix. At the start of every Netflix streaming movie, it pops up this little dialog that tells you it’s measuring your connection speed. Steve® measures the user’s internet connection speed by loading the first five SWFs, it starts a timer when the first SWF starts loading, and it adds up the individual SWF sizes while they’re loaded, at the end of the fifth SWF it does a quick totalBytesLoaded divided by totalLoadTime, to get a KB/s number. This bit of testing not only gets us the user’s connection speed but effectively preloads 5 SWFs without the user knowing it. Steve® is a clever lad.Â
Now that we know how fast the user’s connection speed is, we’ll need to figure out how many SWFs to preload for the internet speed. With the help of Firefox Throttle  and some manual testing, we came up with four speed tiers to account for, <50 KB/s (Tier1), 51-100 KB/s (Tier2), 101-150 KB/s (Tier3), and >151 KB/s (Tier4). With some more manual testing we’ve determined Tier1 needs about a 12 SWFs head start, Tier2 about 6, Tier3 4, Tier4 0. We ended up trimming it back to 10/4/3/0, just because 12 is a long wait.Â
So from here on, we added a loading indicator, status messages stating we’re buffering x of y, and percentage loaded of current SWF, so the user’s not in the dark about what’s happening, being verbose, Steve® is very talkative. Of course with this system there’s really not much you can do if the user’s connection slows down, so the buffering message will also pop whenever the user runs out of loaded SWFs.Â
And, there you have it, that’s how our current demo reel came about, and the birth of Steve®. You can see Steve® in action here: http://www.plexipixel.com/portfolio/roadshow/.Â
Â
 ![]()
Epilogue
Okay, if you’ve been keeping up, you’re probably thinking why don’t you just find out the total file size of all the SWFs and do some divisions from there, and you’ll know exactly how much to preload? The short answer is, Steve® is not that smart, the long answer? It’s the next step for Steve®. The concept is simple enough, create a loop to start loading the SWFs, grab totalFrames, grab the file size, then dump it. With the information gathered we can use some fancy math and figure out how much to load to keep in front of play head. The honest answer? We just thought of it, we’ll upgrade Steve® when we get a chance.Â
Allen is a Flash Developer here at Plexipixel. Â He enjoys long walks on the beach (no, not really), and journaling by the fireside (definitely not) when not at work battling the Adobe Flash IDE.
