Flash Lite 2: Low RAM, Optimizing via Degraded Ego

Can’t sleep, so here are a couple trends I keep noticing I do in my Flash Lite 2 development.

First off, I keep running out of RAM. The forms I had the designer create from my wireframes won’t work because the wireframes were flawed. In designing them, I had no idea that some of the designs simply wouldn’t work based on the fact that there were too many GUI controls on the screen at one time. The negative is that I am forced to create more classes that represent forms… which actually use RAM by their very existence. Classes in ActionScript 2 are actual prototype objects vs. blueprints like in other languages, and thus physically exist as objects. In effect, I’m merely delaying the inevitable, and making it harder for others to play later. The positive is, my GUI’s are forced to be extremely simple. Simple is good, right? Screen 7 of the wizard? *sigh*…

Related to the above, some controls I’ve been creating hit limits mainly with regards to CPU before RAM. When I fix the CPU problems, which usually are stack overflows or script timeout limits (which on my phone feel like 2 seconds, not 15), I then start to run out of RAM again. Thus, I have to start optimizing my code before it’s even written.

How do you optimize ActionScript 2? Same way you optimize ActionScript 1, with the addition that you have to “drop the ego” as Branden Hall said to me in the past. I’m not sure he meant it in this context, but it fits. This hurts more in AS2 than in AS1. Ego meaning, “loyalty to good programming practices”.

For example, using vector vs. bitmap graphics because vectors use less RAM doesn’t make me hurt. But, these do:

Less Inheritance

Prototype chain lookups are slow. Therefore, the more inheritance I use, the more I hurt myself. Huh!?!?!

For example, I wrote a Calendar component. Getting that S.O.B. to run on a variety of phones out there and NOT CRASH was a feat unto itself. While neato, it still didn’t play nice with others… since it used about 1200k of RAM; that’s a meg and 200k. My Nokia 6680 only has 2 megs. So, putting a design + a button and some labels wouldn’t fly if a developer wanted to do so. That’s just uncool. A component set should make the developer feel happy to use various controls together, not scared. I must crush all fear.

Solution? Reduce the OOP’ness of CalendarDay. What’s CalendarDay? A Calendar is typically a control that draws a bunch of weeks in rows, and each row has a bunch of days, like Sunday, Monday, Tuesday, etc. These 7 days are put in 6 rows. That way, you can safely show most months with last month’s week at the top, and next month’s week at the bottom. These day’s are effectively a bunch of MovieClip’s, 42 to be precise, drawn in a grid. The CPU required to draw 30 of anything in Flash is insane pre-Flash Player 9, let alone 42. …and this is on an ARM processor.

So, it takes me 5 passes to draw things. Create data, attach mc’s, position mc’s, set mc’s data, and finally color mc’s. That equates to 14 seconds in total on my phone (you see it draw at 9), and 8 seconds total on faster N90’s and E70 models.

These mc’s are an instance of CalendarDay. He originally was all cool, had public setters for his data and colors, which all would invalidate at the proper time, and were extremely flexible; ripe for use in a Calendar. Problem? They were cool. I ripped it all out, extended MovieClip instead of my (custom) base UIComponent class, and provided simple methods with no invalidation. I refused to change the package name, though. That, plus some other minor modifications & optimizations netted me:

342k total used RAM.

w00t! In my drunken stupor of celebrating, I notice the code was… well, it sucked. But it works. I’ve always been the biggest proponent that the metric for cool code is code that works vs. code that looks great, but doesn’t do anything. Why, then, do I have such a problem not smiling when I dive into that “class” now?

EventDispatcher is Slow

Almost a second or more dispatching events; remember, I only have about 2 seconds per stack process per frame, so I’ve been trying to use callbacks where possible which equate to only 1 object capable of listening for the event vs. multiple like EventDispatcher supports. Thankfully, this is a rare use case, but… more code for me to write, and still have 2 extra variables + method call to make. EventDispatcher via it’s decoration of objects actually adds enough stuff to equate to this, but at least I don’t have to see it, hehe.

I haven’t succumbed to having children calling known methods on parents yet via _parent.onSomeEvent. I don’t think interfaces could even justify that move… but… it’d save writing 2 properties and a method. That’s 3 slots, per instance used… ugh.

There was a reason EventDispatcher was ported to native C code in Flash Player 9; it’s the main workhorse for GUI coders and was the main bottleneck in pre-Flash Player 9 large projects.

Shorter Method and Property Names

Since Flash Lite 2 runs in the interpreted AVM, the length of the string name used to find the method / property name directly affects the speed in which it takes to run. Shorter method names? Faster to run. Less RAM, and more compact bytecode which equals faster code.

Problem? When I started programming, I read in books, blogs, and websites that encourage short, concise method names that used abbreviations and said those were good to do. Now, I think all the people who wrote the books, blogs, and websites are crackheads and I pray to God I never have to maintain their code in a future project. My methods and properties are about as verbose as can be without being audacious. If you ever question what a property is, or what a method does, I consider that a failure on the programmer’s part in naming.

…yet, here I am thinking of changing setCurrentFromDate to setCurFrD, or even scfd. Properties are even worse; __currentDate to cd. The only thing left to make sense of the cryptic hieroglyphics I’ll write will be the strong typing, but that merely helps confirm suspicions, not convey facts. Horrible… but hey, it’s compact, low RAM, and runs well right? Did anyone get a post-processor for ActionScript 1 / 2 bytecode for Christmas they don’t want? I could use one. Flasm doesn’t count.

What the 3 main issues above effectively make me do is constantly have to re-work my UI. For example, Google Calendar has these text fields for choosing a date. It shows something like “11/5/2006” in the field. If you click it, a Calendar component drops down below it so you can choose a value for the field to hold. I can do that in Flash. I can do that in Flex.

Flash Lite 2? Hah, you’re smokin’ dope, dude. Well, sure, I could do it… if those were the ONLY 2 components on stage. Bleh.

…thus, I have to beg the designer to discuss “solutions”. It’s rough, I’ve already ravaged the design enough, and will have to devote at least a week (last week in February) to make sure the design is up to the designer’s standards before I submit to the Flash Lite contest.

I swear, I’m this close to making a branch in SVN, and creating a “AS2 coder friendly” branch and a “AS1, fugly but optimized” branch for the component framework. This stuff is hard, yo. Purely masochistic at this point. I wanted a challenge and I sure got one. It’d be easier if I could just drop the ego like Branden said, and code lightweight AS1. So… hard… to let… go…

Flash Lite 2: SetInputTextType & Slash Syntax

Flash Lite 2/2.1 has an fscommand2 called “SetInputTextType”. One of the reasons for its existence is that TextField.restrict is not supported in Flash Lite 2 / 2.1. My guess is, to make it easier for the Flash Lite Player engineers to support some forms of TextField restriction values, they found what was commonly supported on devices, and gave those as options. That way, they don’t have to write crazy parsing routines to translate your restrict values, which are typically just a string of accepted characters in a semi-RegEx like format.

Instead, you pick from 6 options like “Numeric”, “Alphanumeric”, etc. and make sure your phone actually supports the mode you are using.

For example, I’m creating a NumericStepper. Normally, one would assume you could go TextField.restrict = “0-9”. If you export for ActionScript 2 or 1, this will allow only numbers to be entered into the TextField by the user. However, as previously stated, it’s not supported in Flash Lite 2 / 2.1.

The problem with SetInputTextType, though, is that it relys on the Flash 4 targeting syntax which we all love to loathe (even though it made most of our careers). While the docs give an example, it’s on _root, and doesn’t take into account the way variables work in slash syntax vs. dot syntax. As soon as you nest yourTextField into another MovieClip, you need to take this into account.

Basic steps:

– give your textfield’s variable property a name with a suffix of “_var”
– for the 2nd argument of SetInputTextType, go:

_target + ":" + yourTextField.variable

The _target property will hold the old slash syntax to get to your component, and the colon is used for accessing variables in slash syntax (vs. a dot like in dot syntax).

So, in my case:

__valueField.variable = "__valueField_var";
fscommand2("SetInputTextType", _target + ":" + __valueField.variable, "Numeric");

I sure hope if they make Flash Lite 3 use ActionScript 3, it also uses the ActionScript 3 clean api mentality of abandoning this slash syntax crud. Currently, it makes all the new fscommand2 calls feel legacy. Slash syntax throws me for a loop every time.

Flash Lite 2 is a Presentation Layer

It may seem like an obvious statement, but it’s not. Flash Player has been a presentation layer for years. The difference? Nowadays, even without a backend, you can create some all encompassing applications. Utilizing the stateful client aspect, you can parse data, and show that parsed data. You can really push visualizations driven by data.

Flash Lite 2 has major limits to the above. For example, for and while loops; dangerous, will most likely crash. Think on that; could you live without for and while loops in your code? Your only recompense is using an onEnterFrame loop handler. A setInterval doesn’t count because it can fire multiple times in one frame, thus either overflowing the stack, or making your insanely low scriptTimeout limit to take too long. Can you do loops? Yes. In real world applications that you are used to in Flash? No. So far, the only surviving one I have is in re-drawing a List component’s children.

Data parsing. Data parsing, like sifting through XML, or converting strings, uses a lot of the above. Additionally, it has “a lot of data”. A lot of anything pre-Flash Player 9 is bad. Since Flash Lite 2 is basically 7, you have to not only keep that in mind, but also that you have about 2 megs of RAM. This makes even GETTING the data into Flash a challenge. For example, I’m learning to parse XML in PHP currently because Flash can’t do it reliably. It’s a good excuse to learn, but… dammit, 4 years of study, no longer applicable. Yes, yes, knowledge transfer will help in PHP, no doubt, but still, frustrating I have these insane powers that are now useless.

Communication. I spent 2 days messing around with Google’s Calendar API. The amount of header finagling, and HTTP Status response tweaking is insane. It certainly makes you appreciate companies like Yahoo who expose standard middle-tier API’s that you can call… and they… say it with me… “WORK!”. To be fair, there is this dude on the Google help forum who is a champ. I think he’s one of the dudes writing it too. Problem is, Flash & AS2, even with Fiddler, ServiceCapture, and Ethereal installed on my comp don’t fix the whack ass errors I’m getting. Instead, I search Google and find a plethora of PHP API’s for it. And after 10 minutes of tweaking someone else’s code into my own, walla, I’m up and running. I’m sure someone with something to prove could get it to work, but fuggit… Flash displays stuff well; let it do that. PHP is doing just fine getting data, handing Google happy headers, and sending the appropriate data to Flash. Since I used ARP, it wasn’t that big of a deal to change my Flash Lite AS2 code.

Since Flash Player 9 can JIT to ARM (phone processors), I really question if the above really will become obselete or not assuming Flash Lite 3 is some sort of Flash Player 9 build (at least gets the new AVM if not Flash Player 8’s display capabilities). Since ActionScript compiled to machine code is just that more lightning fast, does it really remove my loop barriers? Can I continue using XML DOM parsing (which is faster than E4X) once AVM+ comes alone? Flash Player 8’s new garbage colletor I’m sure might help, but frankly I’ve been seriously impressed with Flash Lite 2’s ability to reclaim memory after I destroy stuff. As usual, my biggest bottleneck is the phone’s slow arse processor, and my next to nothing sequestered RAM food tablet for the day. Does insane speed fix these problems?

I think not. 5 milliseconds vs. 15 seconds to use too much RAM is just a shorter time to use too much RAM. XML parsing would be nice to have back; I can rip out the data I need, and kill the XML reference, hoping that the GC removes it quickly. Even so, the amount of XML cannot be helped; some RSS / Atom feeds which are used in lieu of a lot of XML-RPC interfaces nowadays are pretty verbose. When a lot of these API’s are aimed at Java developers… well, I’m at the short end of the totem pole, and thus request the help of a middle-tier to do some of the heavy lifting; in this case, PHP parsing XML and making pretty headers.

Anyway, summary: If anyone tells you Flash Lite 2 can be used to make apps, they are incorrect without including some other part that does the heavy lifting like some middle-tier, or if the SWF is embedded in a Java / C shell on the phone / device. My definition of app is an application you’d make on the desktop, only for the phone. For example, her majesty’s blackberry has a Java app that Google makes that allows you to check your GMail. It’s pretty slick, works, and is a great app. Nothing complicated compared the actual web interface of GMail.

This is the 3rd time I’ve had both swords unsheathed, and charged full steam ahead, letting loose my nordish battle cry. All with a gung ho attitude at creating something cool with Flash Lite 2. Each time, I’ve hit a brick wall when it comes to data parsing and anything to do with loops.

It’s all good, it’s still a very valid presentation layer, and middle-tiers abound with heavy lifting & parsing abilities. Besides, ARP works just fine in Flash Lite 2, and I’ve got enough UI components to be dangerous. My advice; plan in advance to have a backend along with your Flash Lite 2 front-end.

MovieClipLoader Oddity in Flash Lite 2

Jeff from Custom Logic posted on the Flash Lite mailing list about a problem with MovieClipLoader. Basically, if you remove the MovieClip via removeMovieClip that is used in the load operation for the MovieClipLoader.loadClip, as soon as the image loads, you’ll get a “Unable To Load Data” error. For some reason this race condition is handled fine in Flash Player 9 and below, as well as the Flash Lite emulator in Flash 8, but not in Flash Lite 2.

Solution is to encapsulate the load operation & removing of the MovieClip in a class that generates an event upon success since it cannot happen immediately.

Non-class example (tested and works):

function init()
{
        mcl = new MovieClipLoader();
        mcl.addListener(this);
        
        load_btn.onPress = function()
        {
                this._parent.doLoad();
        };
        
        kill_btn.onPress = function()
        {
                this._parent.doKill();
        };
        
        // keep state
        abortFurtherLoading = false;
        isLoading = false;
        
        fscommand2("FullScreen", true);
        
}
function doLoad()
{
        // only load if we aren't already doing so
        if(isLoading == false)
        {
                isLoading = true;
                if(image_mc) image_mc.removeMovieClip();
                createEmptyMovieClip("image_mc", 0);
                mcl.loadClip("http://www.some.com/image.jpg", image_mc)
        }
}
function onLoadInit(p_mc)
{
        isLoading = false;
        // if we should abort, go ahead and remove
        // the clip
        if(abortFurtherLoading)
        {
                abortFurtherLoading = false;
                removeTheClip();
        }
}
function doKill()
{
        // if we are loading...
        if(isLoading == true)
        {
                // ...wait till we're done
                abortFurtherLoading = true;
        }
        else
        {
                // ...otherwise, kill immediately
                removeTheClip();
        }
}
function removeTheClip()
{
        image_mc.removeMovieClip();
        delete image_mc;
}

init();