Gotcha, bitch!
Blog
-
Symbol Naming Strategy for Flash
My co-worker, Tony Martin, found a weakness in the mx.core.UIObject symbolName pattern that we have been using. It’s really frustrating because we’re already half-way into the project, and I wished I could of known about it at the beginning so I could formulate a less sweeping refactoring change. How many times have you heard that before?
To give you some background, one of the problems with early Flash Development was the fact that visual elements in Flash can be stored as symbols. These symbols can be reused, much like a class can be reused as instances. Early on, designers started making these symbols do common things, and even started associating code with them, the first components. These MovieClips quickly became problem prone because of the lack of initialization order control, and keeping both linkage name and class name in sync. Linkage names were utilized to name a symbol. That way, when you wanted to attach it visually, you had a name to identify it with. Some people would make both the name of the class and the symbol the same, which was a pretty good convention.
ActionScript 2 came along and introduced packages, much like Java. The early framework thus kept the same scenario where your package name was the same as your symbol name. The occasional issue arose where the 64 character limits on symbol names would cause an unexpected refactoring, but other than that, she worked good.
…till today. I’ve seen the questions in the past on the Flashcoders list of how you associate another Symbol with the same class. There are a couple ways. You can either simply put the class in the AS2 class name in the linkage panel, or associate it at runtime via Object.registerClass.
I never understood the point, though. To me, it didn’t make any sense; why would you create a brand new asset, but re-use the old class that had specific functionality? Why not just do a new class, problem solved? I saw one scenario where the mx framework actually did this, utilizing mx.skins.SkinElement in this way. It was an extremely lightweight class that had like 3 properties, and 3 methods. It acted like a UIObject, but didn’t have all the extra baggage.
Today, we’ve coded a generic List renderer, and our design comps show 2 kinds; one that is thick, and one that has no background and is just text and an arrow. Tony, being prudent, asked if we could just use the same class we already wrote. It was a specific class, inherited a lot of nice functionality from base classes, and the only thing we were changing was artwork and animations. Seemed logical to me.
The problem? The static symbolName property. Typically, when extending UIObject, you implement a symbolName property as a static class member. This typically is the same as your class, only a String. You then copy and paste it into both the linkage ID and AS2 class name fields for the MovieClips. That way, all 4 are in sync. The compiler doesn’t check for a missing symbol name, so if it doesn’t work, you misspelled it; basically ensuring you don’t have a magic string. Secondly, you can utilize the symbolName in the attachMovie and ensure you never misspell it, like:
attachMovie ( MyClass.symbolName, "mc", 0 );
The problem is, “static is the new _global”, and you can’t change static on the fly without affecting all other creations of the components. Even if you made it a class property, you’d have the same problem; anytime a new class would be created, it’d be referencing the new symbolName. Could you change it back? Sure… I guess. I mean, Flash Player is single-threaded, so you could technically time it I guess, but that’s not a risk I want to take.
It gets worse when some of our container classes actually depend on this property, and thus you realize your kind of stuck with it.
We built our lightweight lists around the same way the DataGrid works with cellRenderers; you basically pass in a class you want it to “make”. It works like:
my_list.childClass = Label;
It internally knows that it is dealing with our base component class, so knows to look for the symbolName.
So how’d we get around it? Uber-hack:
var newSymbolForClass:Function = function(){}; newSymbolForClass.symbolName = "AnotherListRenderer"; ourList.childClass = newSymbolForClass;
Voodoo, but it works. All the symbolName really is a String that tells attachMovie what MovieClip to attach; it doesn’t care if it’s an anonymous function or a true class.
This does, however, pose the challenge. Now that I finally understand the use case for allowing multiple MovieClip symbols to utilize the same class, how does one utilize the symbolName strategy to get rid of the magic strings, but be flexible enough to support different symbols for the same class? How does this work in container classes that “know” they are dealing with these types of classes?
For now, I’m thinking we’ll keep the above hack, but in the future, it may be better to make it an instance level property. This, however, makes it harder to pass generic classes to the components who will create them in a factory type fashion. They no longer need only the class, but now need to know which symbol to make. Step backwards, but certainly gives the flexibility that design projects need. Forcing people to create a new class just for new artwork is ridiculous, so maybe this is the best compromise.
This is pointless in ActionScript 3 since everything is a class, and there are no symbol names anymore. You’ll have to basically write a parent class that allows multiple child classes to be drawn into it via Composition.
-
A New Flash Framework?
I figured I’d take the spare 30 minutes or so I have at the airport to write about an idea I’ve had for the past 2 weeks. Any seasoned programmer will see duplication and seek to destroy it. I’ve seen duplication in the Flash work I’ve done over the years and I want to provide a better way of doing things.
Some context. I went from being a Flash Developer to a Flex developer in the past 2 years because of workflow & industry norms. The workflow in Flex from a programmer’s perspective is superior to Flash’. Additionally, the typically jobs one gets using Flex have extended deadlines compared to the typically design / deadline driven worlds of Flash work. Thus, you have more of an opportunity to apply tried and true programming concepts when creating software. Make no mistake: Both industries create software. The Flash websites and the Flex intranet apps all have similar goals of creating GUI controls, connecting to back-end data via middleware or static data such as XML, and require code to make those things happen. The difference, at least in my experience, is deadline. In the past, it was price. Now that Flex is now priced within the reach of the majority of companies, as well as the framework & compiler being free for those who do not wish to use Eclipse, true options exist.
To me, though, the lines really aren’t that blurred. If you are in the creative industry, you’ll continue to use Flash, and if you are in the software industry, you’ll continue to use, or start to use, Flex. Granted, there can be mutually beneficial crossover, hence the point of my presentations the past month & at Adobe MAX this year.
There is a problem with the Flash industry, though. Flex has 2 frameworks, ARP & Cairngorm, deadlines that support such large project scoped frameworks, and code only based approaches to development. Traditional, predictable, diffable, ASCII, and centralized.
Flash is none of those. While it has ARP, and a variety of other component sets and frameworks, each addresses a singular problem, and doesn’t scale, those that I’ve battle tested. For example, ARP is a great framework for Flash, but when you have 4 weeks, and are only reading data from the server, it’s hard to justify writing 6 classes just to load an XML file into a text field. My current project, for example, has a hardcore set of priorities. I’ve written them on our whiteboard in the corner for our team to refer to in conversations. They are, in order of priority:
- Deadline
- Creative
- Bandwidth
- Maintainability
As you can see, that is an extremely harsh reality for traditional software developers. Most would look at that and reply, “F that”; probably more tactfully. Most do, hence my continued employment in this industry. Anyone who has done more than 1 software project knows NOTHING is on time. If it is, something is wrong with it. Software Development is an art, not a science. You cannot place a deadline on a subjective endeavor. It is merely for team morale, focus, and business acumen.
Secondly, most all programmers are interested in developing for maintainability. As you can see here, it is the LAST thing we think about. The Flash world in some circles has indeed reached the coveted “disposable software” stage coined by I believe Kevin Lynch back in the Central days. If you are going to throw the software away in 6 months, do you really care about encapsulation, OOP, and strict typing? How much is really enough and how much is too much? Where is the defining balance?
The flip-side is things like prototypes and “tracer bullets” (Pragmatic Programmer) become a way of life, not tools to develop software; they ARE the software. They are “good enough” for the job at hand, are completed (generally) when the deadline comes, and are cast aside when the next site refresh arrives. The attitude one adapts for creating a prototype, like letting strict-typing slide, breaking encapsulation, and other minor points of good software development give you a burst in speed in development. Some have argued that strict-typing does in fact help them code faster. I’ve never seen those comments, however, flushed out. Faster how? Faster to debug? Does that equate to less overall development time? What if you never had to debug? Would it matter then?
I contend that as long as your magic strings are numbers are var’d, you’re good to go, strict-typing be damned. I still use it, though, because I can type fast and it’s just a built-in habit since I spent years learning how to make it one. Kind of hard to unlearn something you devoted half-a-decade to ingraining in your everyday routine.
It’s got to look good, not work good. Meaning, if it works well, but doesn’t convey the brand, doesn’t correctly represent the Art Director’s vision, or doesn’t sell the product in someway, then a working list box is useless. To a programmer, that’s harsh. Suddenly, you are given the impression that all of your hard work, creative problem solving, and talent was for naught. It’s frustrating, makes you 2nd guess yourself into insecurity, and develop an apathetic attitude towards tasks you used to get excited about. When the color of something is more important to the functionality of something, it requires a major perspective adjustment. Some rules are suddenly meaningless, some ideals become ivory tower ideals, and some workflows degrade into “programmatic barbarism”. That’s ok. If you complete it on time, and the designers are happy, you win. Success is defined by hitting the priorities above.
Bandwidth is the most harsh of all. When you are removing loading bars just to grasp at every minute once of “speed perception” you can see to what lengths people will go to keep it fast, or keep it looking fast. This pretty much destroys most battle tested Flash Development strategies. Suddenly, you can’t use a single SWF that preloads everything on frame 2, classes included. When loading bars are bad, things become less in touch. Things in Flash less in touch are inversely proportional to the amount of developer / designer maintenance of the assets. For example, a single SWF is easy to maintain. All code, all internal assets, and symbols are all in the same FLA file. Flash the IDE is made to help navigate the FLA format and organize it. Programmers have dissed FLA’s for years as being binary, and thus impossible to diff via source control, and various other problems. Designers have always known, however, how useful they are for keeping needed assets localized, not forced to map to the actual project folder structure in which the FLA resides, and the flexibility to make another one load another one.
This is a programmer’s nightmare. While Remote Shared Libraries are a great idea, there are no good tools to make them easy to manage. When people like Darron Schall have a bead of sweat fall from his brow upon “getting them to work good”, you know you have a problem. So, what is the best way keep small, quickly loadable SWF’s without causing code spaghetti? Exclude files. As long as all SWF files are from the same sub-domain, they can share classes. The classes don’t have to physically exist in the SWF itself, they just retain pointers to their names and have faith they’ll be available when loaded into a base SWF who DOES have them. An exclude file is an XML file that defines classes that you don’t want compiled into the SWF when you compile. It has the same name as a FLA and lists all classes you don’t want in the SWF. The Flash IDE will check for the existence of this when you test movie / publish / compile.
One technique that I’ve seen is to basically spell out all of your classes into the _root of your FLA without imports. Flash interprets this as a usage, and thus will compile the class into the SWF. This FLA which has no library contents will merely have classes in it. You can optionally put a function on frame 2 that emits some sort of event or calls a function in the _parent to alert those who care that it’s ready to be used as a “DLL” of sorts. The base SWF then acts like a Java Classloader of sorts, and loads this bad boy in first, and then loads in those SWF’s who depend on that framework.swf.
Finally, maintainability is the last thing we think about. As you can see, all of the above does everything it can to pretty much sabotage any hope of maintainability. Really all that matters in this line of work is it being maintainable enough until you get done with production, and out of QA. At that point, smoke ’em if ya’ got ’em.
As you can see, there are a lot of challenges to doing Flash Development compared to Flex Development, with very little conventional solutions to tackle it all in one fell swoop. Those that do exist don’t account for the common situations and challenges listed above. There is no fallback plan, no Plan B when the deadline starts to squeeze, no exit strategy when you’ve coded yourself into a corner to please your designer overlords.
What has tried? A variety of things, and some I’m sure I don’t know about. ARP did a lot to get Flash Developers on the right track of using a framework which has a ton of benefits across the board. ARP does not, however, currently possess a conventional, documented practice of using it across dynamically loaded content.
EnFlash is a really neat Flash component set that has a lot of the content dynamically drawn. Since you cannot share assets across Flash Player 8 libraries are runtime in normal way (there are weird ways to use bitmaps and sounds), EnFlash works well because there are no design dependencies. The problem? All Flash Design work I’ve been involved in uses dynamically drawn, customizable vector gradients 1% of the time. Everything is a custom design, everything has usually already been documented or spelled out in the comp by the designer, and thus all of those code is useless.
Most of the component sets I’ve seen and had the pleasure to use were built to satisfy a different style and perception by their developers. mCom (aka Glic) was built to utilize some of the common programming concepts Grant Skinner and friends enjoyed. The Bit components by Keith Peters I’ve also used as well. They were actually very skinnable. Not skinnable enough, however, from what I’ve played with. Additionally, anything that doesn’t do the same thing as Macromedia’s framework causes licensing issues as well as skill transference issues. For example, while I personally found the Bit components easy to get into, when you have 4 weeks, it’s a big risk to take having your developers learn a whole new set of components. Furthermore, a lot of designers don’t give a flying flip about “components” and thus don’t build to their specs. For example, I’ve yet to find a designer who gives me the 8 states I need for the Button component, Flash or Flex. Should they? I’ve found I’ve always successfully implemented a designers vision when I coded to the design, not the other way around. That is a horrible thing to do programmatically, but I direct your attention to the aforementioned list. For example, “I don’t care that the border is a rectangle built dynamically upon focus in mx.skins.halo.RectBorder… just make the damn border always glow yellow with the bottom left point, and do it by the deadline!” is a common frustrating interlude between the two disciplines.
There was often a confusing response to questions about “using components?” on the Flashcoders mailing list. Some would quickly respond, “roll your own”. Those of us who were learning to utilize the built-in functionality would cringe at the poor souls writing code which was already written for them, but was either poorly documented so they didn’t know it existed, or just didn’t have time to learn about. This, however, was a clouded perception. Some of us, at the time, were splitting industries. Some were remaining in the design driven world where others were heading into application development. Those are 2 very different disciplines with very different perceptions towards components, both very valid.
Therefore, rolling your own is definitely justifiable when there is a snowball’s chance in hell that you’ll “get to work with the designer”. Some companies are setup with that level of team accessibility, or where the designs are outsourced to some contractor you’ll never meet nor talk to. When a client signs off on the design, you can pretty much ensure that the fact that the component you are using only supports 4 skins only confirms your late nights of creating a new one that does the same thing, but works with the design.
This isn’t sad or a broken process, it’s just the way it is in some companies. You either get stressed the f’out and leave, or find a way to make it work.
I’m interested in finding a way to make it not just work, but work better. While I have no intention of continuing my career in Flash Development vs. Flex Development, I certainly didn’t expect to be doing Flash work in Detroit once I signed up with a Flex Consulting firm either.
I’ve always been pretty sure I’d never want to be involved in framework development. There is too much drama, too much time spent in meta-programming discussions that one is hard pressed to find value in at the end, and overall very little reward for all the hard work put in, at least in my perception. For example, it’s easy for me to bitch about how Cairngorm is implemented in some sections. I have the luxury to pick it apart, and mod it for my projects to my hearts content. I don’t have to worry about backwards compatibility, developer API understandings, and various other community future implications that Steven does. To me, it’s perceived as a thank less job that does a lot of qualitative good that can sometimes be unfairly overshadowed.
I have a feeling, however, that there is still some things I contribute that would help at least alleviate some suffering I’ve personally experienced, I know others currently experience, and some will continue to endure into the foreseeable future. There is a certain set of principles you can develop to in Flash, but scale up and down to your deadline, your design’s intricacy, and your team’s size & skill set. The latter I can’t really do much about. I’m not into training, and it’s a lot to ask someone already in a high pressure environment to change the way they do things.
There are a myriad of problems. There is no component set I’ve seen that was specifically built to be shared across multiple SWF’s. I think Aral Balkan, Peter Hall, and some other dudes actually separated the MX 2004 framework to be in single SWF’s to prevent the large initial download size. The problem? The framework was built to use styles. This implementation brings with it a TON of extra file size that isn’t needed in an environment that already uses it’s own design based on pre-created comps. The way one builds components isn’t really defined, and the ones that are don’t really scale to git r’ done scenarios. For example, while the Flex 2 way of setting dirty flags, and then redrawing your component once per frame is great and built specifically for the way the Flash Player works, it’s certainly asking a lot of already time pressured developers to double the amount of variables in their classes via a set of dirty flags, 1 per settable property, extracting redraw functions into 3 sets, let alone optimization in general. Most don’t have time to think, let alone think about optimizing.
Is it even worth it? I feel like this kind of work will in fact continue, thus there is value in contributing to making a workflow & framework that fits it. There is definitely a need for a framework that is specifically built to satisfy the following goals:
- Usable via multiple SWF’s.
- Small file size.
- Supports beginner and advanced component developers.
- Packaged utility classes for common scenarios.
Why those 4? Let’s elaborate.
Loaded movies are very important to design intensive Flash sites. During development, they allow multiple people to work on disparate elements at the same time, thus increasing productivity. Secondly, they expedite creating assets that take longer to compile. For example, using Flash to compress your sounds to mp3, a lot of images, or embedded video can greatly increase the amount of time it takes Flash to make your SWF. Being forced to go through this long compile time just because you changed 1 line of code is unacceptable during deadline driven development. Thus, you can create a SWF with the media content once, and merely load it later into some more volatile to develop section. This also makes it easier to update later without having to recompile the whole thing.
At runtime, loaded movies help lessen the download damage. Instead of downloading the parts of the site / app the user won’t see till they actually navigate there, it works much like a webpage and downloads as needed. This allows a multi-meg site to be given in increments yet appear fast to the user.
Small file size is important to ensure the above is successful. One of the reasons the MX 2004 & 8 framework is so big is because of styling. Both the symbol assets as well as code behind it adds a lot of kilobytes that a lot of designers will never use. Granted, the font control is nice, but the trade off in file size isn’t worth it. Since a lot of sites are custom designed, styling is to generic of an implementation. You are typically using custom image assets garnered from a Photoshop or Illustrator file that a designer has already created. The colors, fonts, and styles are already done and decided upon. Most won’t be dynamic. If it is, the designer has already created it.
Secondly, the site is already strained from using image assets above that have to be embedded bitmaps and not loaded externally, especially pre-Flash 8 where you can only load non-progressive JPEG’s at runtime vs. GIF’s & 32 bit PNG’s in Flash Player 8. Since the only real optimization you can to code is compression via LZW, you have to ensure the code you do write does just what you wrote it to do, and nothing more. Flash does help you some, like not embedding imports that you don’t use, only including a class once in the same SWF, and the ZIP compression is pretty good on duplicate includes. Regardless, the designer created content has already taken up most of the bandwidth room; there is very little leeway for code in the already tight space.
Flash Development attracts a wide skill set from animators, compositors, painters, and good ole designers. You also have the other side of the fence where back-end developers are utilized as temporary front end coders for Flash. They have their own background and coding style. Thus, the level of code ability varies wildly, and is hard to predict. It is important, then, to allow the beginners to code with simple to understand methods, and easy ways to “make it work”. It’s hard enough to enforce the no code on frames mentality; the least you can do is make your classes easy to use for those who don’t have a lot of time to learn them. On the same token, it is unfair to codify traditional programmers into intentionally non-efficient methods if they know what they are doing. For example, one of the ways to modify how View’s are written in Flex 2 and Flash 8 is to simple ignore dirty flags, and instead just redraw. So you call the resize function 3 times on the same frame, thus making 2 of them useless since Flash Player only redraws once per frame. Is that REALLY that bad for a component that just shows a label in a nicely designed panel? I’d say hell no, no problem, move on. In a Flex app, you’d quickly go, “Nope, you need to set a dirty flag for the label, call invalidateProperties, inspect it in commitProperties, and call any setters or invalidation routines there to ensure efficient redraws.” That is overkill for a lot of Flash projects, but there are justifiable use cases where you have a really big and/or complicated component that could benefit from such efficiencies. If you have the code talent on hand, why not utilize it? Designing view classes that allow beginners to easily code their views as well as programmers to go all out, and have both play nice with others is a challenge, but can be done with a few conventions. This also allows everyone to easily fallback to a more simplified coding style when the deadline tightens the noose.
Finally, including a set of utility classes, with a Creative Commons license, to accomplish the most common tasks that Flash Designer & Developers are faced with in Flash sites is the final touch. It’s one thing to establish a set of coding standards, it’s another to have helpful code. Having code handle common tasks ensures you can handle the more important problems you are having with a deadline vs. re-writing the same function queue for the 5th project this year.
The cons? Training. Yeah, you can document a framework, but I’ve found it most rewarding to work with people to show the pros and cons of a particular way of development, especially compared to the way they traditionally do things. In doing, they recognize value in the new way. Second, you empower them to train others, and convey that value in a language they understand, typically in some context applicable to their business and/or type of work.
I’ve also found it hard to get people to change the way they do things when they already have no time. Taking big development change risks is a major deal when you are always behind. Being able to integrate framework B into an existing framework A is challenging, and is sometimes the only way. Just like how programmers constantly refactor, so too is the way you can implement a framework bit by bit, assuming it doesn’t have a lot of dependencies preventing you from doing so.
Finally, there is currently no easy way to create exclude xml files and keep them in sync. The same management nightmare one gets with Remote SharedLibraries is the same thing you’ll eventually get with exclude xml files. Is this class still valid? Did I refactor it and change it’s name? Does it really belong in this SWF?
I think the challenges are no small thing. The amount of information that describes how to do things could fill a book based on my experience which unfortunately is aimed at people who don’t have the time to read a book. New tools (Flash Panel?) would have to be written to help designers and programmers stay focused and help them accomplish their goals.
Hopefully at the very least I can keep blogging what I’ve found to be the good and bad decisions since Flash Development is fraught with subjectivity.
-
Flash & Flex Powerpoint Uploaded
I’ve uploaded my Powerpoint presentation about using Flash and Flex together, that I’ve done twice now and modified twice as well. First at the Adobe Atlanta Users’ Group, and then last Monday at the Flex Seminar. Things of use include CSS Class selectors (basically, using a Class name in CSS to globally affect all instances in your Flex application), font embedding code, and a breakdown of Flash pieces used for a Flex app.
Powerpoint – FlashPaper | PPT in ZIP.