Pet Theory header image 2

Building Pet 8: Structure for an HTML-Like All-Flash Site

May 19th, 2007 by matt

In the first post of this series, I explained why I wanted features like long-term flexibility, deep linking, history, and background loading for my new, all-Flash playground site, pet-theory.com. I also explained why I used design patterns to meet these requirements.

In subsequent posts, I explained how it was done, focusing on one design pattern per post: Strategy for navigation, Mediator for application files, Interface for loading, State for loading swfs, Composite for a background loading queue, and Command for history.

In this post, I’ll summarize the entire process. I’ll start by identifying the fundamental problem bedeviling all-Flash sites, and end by suggesting that my solution to this problem can be the basis of a flexible, lightweight, comprehensive framework.

Flash lacks a predetermined network structure

HTML has a standardized network syntax that includes two elemental nouns, the page and the hypertext reference, and one verb, to link. Here is a sample network that shows all possible navigations in a site:

picture-1.jpg

Now let’s examine the same site versioned in non-Flex Flash:

picture-2.jpg

Each color represents a different species of “page” and “link.” Look at all of them!

There are some commonalities in this structure: sibling nodes are alike, and the way the parent nodes link to each of their children is alike.

picture-3.jpg

But realize that not even this localized consistency is necessary for Flash:

picture-4.jpg

This freedom to knit a patchwork is both the glory and the curse of Flash. At its ideal best, it could lead to interfaces that exceed both HMTL and Flex in suppleness and usability. At its all-to-common worst, it leads to designs that are difficult to navigate, and code that is difficult to debug and extend.

This loosely defined network structure renders some built-in features of HTML tricky to implement in Flash.

picture-5.jpg

As you can see, Flash’s deep link is more complicated by multiples. The terminal node might be anything, and it might depend on previous nodes to exist, so the whole route from home to it must be traversed, across several kinds of nodes and transitions.

Now compare backtracking from this node to home:

picture-6.jpg

For HTML, history is just reloading a page held in a series. For Flash, there are no “pages” per se, and who knows if going to and going from will produce the same result?

picture-7.jpg

Organizing a Flash patchwork around a standardized network

HTML-like behavior requires HTML-like structure. So I knew that the backbone of my site would be a standardized network. Here was the first diagram I drew:

picture-8.jpg

As I looked at this diagram, I wondered: what are those red circles, if they are not pages or states? And what are those blue arrows, if they are not pages loading?

You might decide something different here. I decided that those red circles were “modules” defined by the fact that were destinations. What might arriving at any particular module entail? The answers to these 5 broad questions would supply each module’s character.

1) Do assets need to be loaded?

2) Does this module lead on to other modules?

3) Does this module have controls?

4) Should code run when this module is selected?

5) Does the module have any collateral material?

Once I had demarcated these five areas, I used the strategy pattern to create a strategy object for each: a loadable, a navigable, a controllable, a wakeable, an alertable (collateral material was going up in a pop-up window or alert). Each of these partitioned core functionality, making the composition of particular modules a piece of cake: a module might have a loadable, might have a navigable, etc. The BaseModule class assumed nothing, assigning null to them all.

picture-9.jpg

Navigable was the most important strategy object, because it kept a reference to every module’s children, and offered a platter of navigation methods: goto, navigate, navigateHistory, etc.

tree

Once a flexible structure for the site was laid out, the navigational logic was next. I knew that I wanted to centralize this logic, both to save typing, and because a command center would ease the way for a succession of navigations calls (a home or deep link), and ditto for keeping tabs on history.

I already had a Mediator class (based on the Mediator pattern) that coordinated the various components of the site (progress bar, control bar, home). So I added to its responsibilities that of handling selections. When a new module was selected, it recorded the selection for history, made sure the module was loaded, woke up its wakeable, listened to its navigable for more navigations…and when it was deselected, it drew in the shutters and invoked wakeable.sleep().

From what I’ve written so far, you might expect that the Mediator class is manageable only because the modules and transitions between them are fairly uniform.

Not at all! Each of the strategy objects, and the module itself, implement interfaces, so they support a variety of implementations. An ILoadable-implementing loadable, for instance, could load a video, or data, or a picnic-pack of both…all of which appear the same to the Mediator, which only needed to know loadable.load().

Furthermore, modules can assign their own methods as callbacks to their strategies. Each navigation method and each wake method, for instance, are set locally by their modules.

My point was never to duplicate HTML page or the Flex state, which would be boredom squared. My point was to graft the network functionality of HTML onto a still free-wheeling Flash:

picture-10.jpg

The Pay-Off

Here is the application architecture:

picture-11.jpg

The beauty of this architecture is that, with a little more work, it delivers not one but all my specs:

Deep linking Here is the territory that a Flash deep link must normally traverse:

picture-12.jpg

Within the modular system, the colors are homogenized, so the link can be accomplished with no local knowledge at all.

picture-13.jpg

Given certain coordinates (0, 5, 2, 8) (the indices of the succeeding child modules), the Mediator only needs to run through them one twice. First it loads what needs loading:

picture-14.jpg

Then it runs loops through the navigations:

picture-15.jpg

Voila!

History. Remember that every destination module (except the top, of course) is the child of a parent module, and is reached when the parent uses its navigable to navigate to the child.

So every navigation can be understood as a parent selecting its child, and recorded as such:

picture-16.jpg

Each navigation is encapsulated in a command object and pushed into a history array:

picture-17.jpg

Then, when the history back-button is clicked, history takes a step back and replays the command:

picture-19.jpg

Yes, it really is that simple.

Background loading. A hard-coded background loading queue is worthless on any site with a decent amount of content. What content should go first?

The most pressing priorities are set by user actions. Suppose a user selects a module. What should start loading in the background? Obviously, any loadable assets its children have, then any assets its siblings have:

picture-20.jpg

If you’ve read my post on the Composite pattern, you know that I’ve used a folder-like structure (actually, a composite whose leaf members are iterators/sorters) to group and order different loading logics: find children, find siblings, find any assets from the top of the tree down, find loadables in collaterial material:

folders.jpg

Flexible and Lightweight

Once I came up with this framework, it was a snap to use and remarkably flexible. And my app file, with the core framework classes as well as a bunch of extras, clocked in at a mere 26k.

If you are planning an all-Flash site with HTML-like functionality, I hope you found this series helpful.

Tags: patterns · code5 Comments

Leave A Comment

5 responses so far ↓

  • 1 Eric May 20, 2007 at 12:05 am

    brilliant~~nice article !!!

  • 2 Anty Jul 10, 2007 at 2:40 pm

    I just found out this blog and this is quite a treasure. I’ll read all those articles carefully. Thank you.

  • […] my last post, I reviewed the code architecture of my playground site. In this post, I’ll explain its […]

  • 4 goliatone Oct 25, 2007 at 7:58 am

    hola!!
    Great stuff all together, i enjoy the writing and the content. Good ideas well presented.
    By the way, where is building-pet-5? havent found it
    regards, goliatone

  • 5 goliatone Oct 25, 2007 at 8:10 am

    sorry for that…to early in the morning for me…i just did a search and found it (i didnt find it the first time, thou)