Project: Apollo Pre-Alpha Update

I just posted a refresh of the Project: Apollo pre-alpha technical demo. No promises about the reliability of different browsers at this point, but observe:

http://pre-alpha.project-apollo.appspot.com/

Key Features to Note

  1. Portions of the UI have been built and are functional
  2. You can’t see it or manipulate it, but there is a playlist engine running with two tracks programmed in
  3. Abstracted audio rendering engine is working; the system will choose the best way to play audio based on your browser and the media you want to play*
  4. Keyboard shortcuts! Try [space] to toggle play/pause, [,] to skip back and [.] to skip forward; [v] toggles a visualizer, but it’s currently disabled

Of the sample audio, the first track is in Ogg Vorbis format and relies on HTML5 <audio> tags to render, which will likely only work if you are in Firefox 3.5+, or Chrome 6+. It works in Safari also if you are on a Mac and have the XiphQT components installed for Ogg media. The second track is in MP3 which should work in all browsers since it currently defers to the Flash implementation which most browsers can handle.

Please don’t be shy to leave your comments below!

* This was one of the hardest things to build. There is an enormously complicated permutation set of browsers and the media formats they support. The current options for playing audio are limited to Flash-based engines such as the one provided by Longtail Video, Silverlight by Microsoft, or native HTML5 audio tags. I’ve implemented all but the Silverlight option up to now. I haven’t setup any rules telling the engine when to use what implementation yet but will soon.

Pre-Alpha Preview of Project: Apollo

Last night I put together and deployed a pre-alpha build of Project: Apollo to demonstrate the progress I’ve made thus far. The label “pre-alpha” should pretty well indicate the state of things.

There are some browser-specific quirks to address that pertain to the deployment strategy I am currently using, but those are of low concern at this [pre-alpha] stage.

Since most of what is working is under the hood, I’d like to highlight a few of the accomplishments in this release.

Fully Abstracted Player Framework

The underlying mechanism for rendering audio is completely abstracted and decoupled from the application itself. I am currently using JW Flash Player to do the heavy lifting but as you can see it’s pretty well hidden from view. The next step is to start working on alternative rendering engines to increase compatibility. More on that later.

100% HTML/CSS/JavaScript UI

All of the interactive UI elements are HTML/CSS/JavaScript, including the play/pause butons, the time display and the scrub bar.

Growable Application Structure

I spent a lot of time tooling and retooling the basic foundations of this project to ensure I was comfortable with the architecture. It was very important to me to build a good base upon which to build the rest of the application.

Building an application completely in client-side JavaScript is a very different beast than traditional MVC web apps. Project: Apollo represents (even at this early state) a milestone for me in terms of the way an application of this size and scope is constructed.

I am particularly pleased with the implementation of certain design patterns in the code. For example, state changes are conveyed using the observable pattern via an event bus and the JW Flash Player is cleverly integrated through the use of a Façade and Bridge. I am equally pleased with the separation of concerns in the GUI layer; building entirely new runtime-swappable skins for the application should be a breeze later on thanks in part to GWT’s Deferred Binding mechanisms.

Room for Improvement

There are certainly areas of the application which I would still like to improve. One area is on resource injection. In the past, I have used tools like Gin to perform dependency resolution and injection similar to what Spring provides. So far in Project: Apollo I have opted to forego any DI tools and do so myself. Where appropriate, I’ve used constructor arguments or setters to facilitate testing and singleton patterns in other places to allow access to global resources such as the event bus.

The primary reason I chose to pass on DI mechanisms is that my application simply isn’t complex enough to need them, yet. I’m sure at some point down the line, managing the creation of all my dependencies in the module entry point will prove too cumbersome, but for now, it’s simple enough to take care of those chores manually.

Lessons Learned

The biggest take-away I’ve gotten out of Project: Apollo thus far is a sense of value for certain programming paradigms. As I mentioned above, I opted not to use Gin in this project, but only after some internal debate. Initially I had included it in the project but I removed it when I realized the only reason I included it to begin with was because I had been trained to do so. I hadn’t thought it through for myself!

Using a design pattern does not mean using a library or framework! There’s more than one way to implement a pattern, it turns out.

I’ve also taken a bigger appreciation for the use of design patterns and when to use them. In previous projects, I’ve wasted tons of time trying to shoehorn every aspect of a project into a uniform pattern. For example, I have worked and reworked my own implementation of an MVP framework but ultimately I @deprecated the MVP interfaces in Project: Apollo. Simply put, not everything can be classified as a model, a view, or a presenter, and it’s important to recognize that fact.

(That isn’t to say that I don’t intelligently separate business logic from design and view logic. I do. But only enough to facilitate good structure and programming practices; no more, no less.)

Without further adieu…

I’m glad you’re still with me. As a reward for so patiently reading my entire rant, you may now proceed to demo the pre-alpha release of Project: Apollo! Disclaimer: I am aware of many of the bugs already and this being a pre-alpha release, I’m not too concerned about them at this time.

http://pre-alpha.project-apollo.appspot.com/

Rendering Media in Project: Apollo

Just wanted to document a few nuances that I ran into while working on some of the UI features in Project: Apollo.

Flash movies must be visible

I was hoping to use CSS to set the <embed> element for a Flash movie to something like:

embed {
  display: none;
}

As it turns out, a Flash movie that isn’t displayed isn’t rendered at all; the plugin control is killed off it becomes invisible. This may not be the case in all browsers, but it is the case in FireFox. As an aside, you can set the visibility to “hidden”, but the Flash object will generally still participate in DOM layout.

This was a problem because for audio visualization or video playback as I wanted to have the player hidden until the visuals were requested by the user. Unfortunately, in this case, playback does not occur.

The solution to this problem was to use absolute or fixed positioning to station the visuals where I wanted them. When not wanted, I positioned the element somewhere off-screen.

embed {
  position: absolute;
  left: -100px;
  top: 0px;
  width: 0px;
  height: 0px;
}

There may be some fudgery necessary to keep the window from unnecessarily adding scroll bars, but I am using GWT’s LayoutPanel so this was not an issue (or at least, accounted for automatically).

This also had the side effect of complicating my thoughts around a skinnable UI. Because of this visibility bug, I can’t depend on the skin to manage the container for the MediaControl. To do so would expose too much risk of a skin setting the Widget invisible or otherwise running amuck.

Instead, I relied on a less-pretty-but-more-reliable approach of providing limited access to a managed container in the DOM. The skin can never remove this element from the DOM and so the risk of runamuckery is greatly reduced. My managed container exposes just the functions of LayoutPanel I want exposed to the skin. If the need arises, I may switch this to a singleton interface, but for now, static methods suffice.

As another aside, a fully functional and fleshed out technical demo of the ControlBar is coming soon. Just have a few more items to wrap up.

Using GWT’s Application Framework Judiciously

I am very excited to see the inclusion of a proper application framework in the upcoming Google Web Toolkit 2.1 release. The addition of this framework is a clear signal that GWT is a serious library for enterprise scale applications.

As a seasoned developer, I am very familiar with the traditional Model-View-Controller approach to building web applications. The MVC approach works great for server-based frameworks like Spring MVC or Struts. However, ever since I started working with GWT way back at version 1.4, I’ve had a hard time mapping MVC into a truly client-side application where the entire GUI is built in GWT.

The MVC approach is tried and true in the desktop software world. But on the web, there are a few extra quirks that make traditional MVC a little tricky. Here are some of the challenges I’ve run into.

History Management and Support

Because it is a web application running in a browser, there is an implied expectation that the forward and back buttons work, regardless of whether your web application is mostly client- or server-side. This presents a unique challenge to MVC because most desktop applications don’t have forward or back buttons.

Bookmark Support

Another important feature to any good web application is the ability to bookmark or share the link you’re currently viewing. It should be possible to bookmark a page or paste the current URL into an email, for example, and restore the state of the application based solely on that URL.

Composite View Structure

When working with traditional MVC frameworks like Spring MVC, the process is pretty straight forward. For any given URL, only a single Controller responds to the request. The Controller prepares a single Model and that Model is handed off to a single View. Common elements of the UI can be rendered with include statements, but the View generally has a very direct relationship with the URL.

Conversely, with a more desktop-like application built in GWT, the UI is frequently built as a Composite. There are several components in play at any given time and there isn’t necessarily a straight forward relationship between the current URL and the current set of components viewable to the user. This makes intra-application messaging and navigation a bit more challenging; you can’t just rely on a DispatcherServlet, for example, to coordinate user interaction.

Enter the GWT Application Framework

Clearly, the new App module in GWT is designed to address many of these concerns. It’s great to see History Management and the notion modular composite structure being supported as first class features.

The application framework in GWT is all new to me, though, and it isn’t really MVC. Instead, it’s more of a Model-View-Activity (or -Presenter) approach. In this case, the Activity takes the place of the Controller and is responsible for only the slice of the UI represented by its View. This MVA approach handles application navigation very well, assuming your application is, like a traditional web application, a series of screens or “activities” through which the user navigates linearly.

So what happens when the UI dictates that two or more of these activities be present at once? Well GWT can handle that as well by using multiple ActivityManagers. The ActivityManager is responsible for coordinating all of the Activities for a designated Display – the area of UI over which control can be delegated to an Activity.

This is all well and good, but Project: Apollo presented me with a unique challenge in this new MVA architecture. What do you do with UI components that are always present? Case in point: Apollo has a control bar that is always present in the UI, similar to the button on the front face of a DVD player.

The control bar allows the user to control playback and displays pertinent playback information such as the elapsed time and name of the current track. The control bar, by nature of its omnipresence, does not participate in the navigational functions of the ActivityManager, nor is there any other Activity that would fill its slot.

I’ve also gleaned through GWT code in trunk that the usual way of handling Activities is through an ActivityMapper; the ActivityMapper is responsible for resolving and creating instances of Activities and their corresponding Views. However, control bar isn’t managed as such. I have a self-imposed rule in development of Project: Apollo that UI components should be UiBinder compatible; I should be able to include the control bar in my UI declaratively through the constructs afforded by UiBinder. By contrast, Activities depend on the current state and history of the application, so their lifecycle would not be appropriate to manage through UiBinder, hence the Display slot concept.

Bring Back the Controller

The Java docs for Activity state:

Implemented by objects that control a piece of user interface, with a life cycle managed by an ActivityManager, in response to PlaceChangeEvent events as the user navigates through the app.

It’s easy to see that my control bar doesn’t strictly qualify as an Activity. In this case, MVA isn’t a good fit; I need a different approach. One option, for simpler components, is to let the UiBinder template be the “view” and the backing Widget code be the “controller”. For more complex components, though, I still want to break out application logic to a separate class and leave UI-centric logic in the View-backing code.

Taking a hint from previous iterations of GWT’s application framework, I am choosing to call my pseudo-controllers “delegates”. The Delegate represents a code structure to which the actual View will delegate user interaction for handling. Delegates contain familiar Activity-esque functions to facilitate lifecycle events where necessary.

public interface Delegate<W extends IsWidget> {
    void shutdown();
    void startup(W widget, EventBus eventBus);
}

For my control bar, then, I have broken the code into a ControlBarWidget (the View), a ControlBarDelegate (the Delegate), and a ControlBarModel (the Model).

To keep with my requirements that the control bar be UiBinder compatible, I am allowing the View to handle creation of a default implementation of the Delegate. I’m using GWT.create() to instantiate it so the actual implementation can always be easily swapped out later via deferred binding, but for now, the need to swap out implementations is low to non-existent.

The Judicious Part

The lesson I am driving at here is that the new application framework in GWT may be great for some portions of an application, but it probably isn’t appropriate for everything. Parts of the application that do not participate in history or navigation (such as global menus or controls) are not good candidates for Activities.

I think GWT and the new application framework represent a fantastic toolset for building user interfaces and entire applications. You just have to be smart about when and how you use them.

HTML5 Audio: Format Wars

I had originally planned to use HTML5’s new <audio> tag to actually render the audio in Project: Apollo. That went south, however, when I discovered a few critical problems with current implementations that disqualify the <audio> tag from contention.

Different Browsers, Different Formats

Both Mozilla and WebKit have already adopted at least some support for the <audio> tag. Unfortunately, Mozilla has decided to avoid potential licensing issues by omitting support for any audio codec that isn’t freely open source. This means no MP3, MP4 or AAC support, as those are proprietary codecs.

On the other side of the fence, WebKit (driven by Apple) has a substantial interest in seeing both MP3 and MP4 thrive on the web (maybe you’ve heard of iTunes?). Citing “simplicity”, Apple isn’t budging on adding support for the open standards Mozilla supports, such as Ogg Vorbis.

Google Web Toolkit

Unfortunately, there isn’t much support (yet) in Google Web Toolkit for HTML5, but it is coming. This makes it difficult to take advantage of HTML5 right now since my GWT is the main framework at play in Apollo. Specifically, I’m not sure how to go about listening for DOM events that are specific to HTML5, such as the ones fired by the <audio> element. This isn’t a huge hurdle, because I can always bridge to GWT with native JavaScript (ick). But it does add another hurdle to overcome.

The Solution, Sadly, is Flash

I have used Longtail’s JW Player for Flash in the past on other projects. Despite my reluctance to do so*, I have decided to implement JW Player 5 for Flash as the audio rendering engine. JW Player 5 has the best support of formats I called for in my key features, and it is relatively simple to use.

* Okay, I just have some minor gripes with JW. Namely, they documentation is always a sore spot as it’s often conflicting or missing. I also feel like I’m being nickel and dimed to death by their licensing terms.