Flex 360 tickets selling fast

Down to the last 5 (Cheap) tickets left for 360|Flex. Register now, save $100 and get the same awesome content for a little less coin. Act fast, these last tickets won't last. When they're gone, the regular price of $599 kicks in.

Come on out and hear me give advice how not to hurt yourself with code, in my "Ouch, it hurts when i do that" talk.

Wanna know more about how not to code flex apps?

I'll be presenting my freshly revised "How Not To Code Flex Applications" twice in the next few days. Tomorrow, in the boston area at RIA-Unleashed and then next week at Flash Camp Wall Street.

c'mon by and see us at one, if not both of these great events

Free Flex 4 Training in Chicago

I'll be giving a free full-day, hands-on training session, where experienced ColdFusion Developers can learn how to build their first Flex application using the latest Flash Builder 4 beta software. This training is designed to help experienced ColdFusion developers get started in understanding how to add rich UI to existing and new ColdFusion applications.

Date / Time Thursday, November 19
Hyatt Regency Chicago on the River Walk,
151 East Wacker Drive,
Chicago, IL 60601
Registration: 8:30am

Registration
http://www.adobe.com/go/flextrainingforcfdevelopers

Fun with custom preloaders in Flex

As you probably know, its pretty easy to use a custom preloader in flex to replace the built in preloader shown as a flex application loads. There are a few tricks to remember with a custom preloader though, remember that the preloader is built to be displayed until the flex framework is done downloading. As such, the preloader won't display until all the classes needed by the preloader are done downloading. For this reason, its really important to remember that your custom preloader class doesn't make use of the flex framework, because if it does, the users will see nothing until enough of the framework has been loaded to display the preloader, and the preloader will only be displayed while the remainder of the framework is downloaded. Fortunately, the DownloadProgressBar class makes little use of the flex framework, as it extends Sprite, instead of UIComponent, and only utilizes a few event classes from flex, which don't require any additional framework classes. A quick google search can show you dozens of examples on subclassing DownloadProgressBar to create a preloader which matches your application. A larger challenge is faced when you have additional needs from a preloader. Frequently, we are tasked with writing a preloader which is shown during the initial download, as well as remaining displayed until some startup procedures are complete within the application. Some might try to approach by referencing Application.application within the preloader, to listen for a custom event indicating that the startup procedures are complete. Of course, this is not an ideal solution, as referencing the Application class will link in the mx.core.Applicaiton class, which in turn links in around 170k worth of the Flex framework. A better approach is to create a new class, which is not linked to the flex framework, which can act as an event bus between the main application and the preloader. If this class is built as a singleton, you can be assured that both the main application and the preloader are accessing the same instance, allowing for a simple and convenient mechanism for the preloader to listen to the main application, without needing any reference to the application or the flex framework.

package net.digitalprimates.preload
{
   public class PreloadEventBus extends EventDispatcher
   {
      public var isReady:Boolean = false;
      
      private static var _instance:PreloadEventBus;
      
public static const READY:String = "READY";
      
      public static function getInstance():PreloadEventBus
      {
         if (!_instance)
         {
            _instance = new PreloadEventBus(new SingletonEnforcer());
         }
         return _instance;
      }
               
      public function PreloadEventBus(singletonEnforcer:SingletonEnforcer)
      {
         if (!singletonEnforcer)
         {
            throw new Error("PreloadEventBus is a singleton class, use getInstance() instead");
         }
      }
   }
}

class SingletonEnforcer {}

With this class, when the main application is done with its startup procedure, it's a simple process to get a reference to the PreloadEventBus, set isReady to true, and dispatch an event.

protected function applicationCustomStartupDone(event:Event)
{
   var bus:PreloadEventBus = PreloadEventBus.getInstance();
   bus.isReady = true;
   bus.dispatchEvent( new Event ( PreloadEventBus.READY );
}

In the custom preloader, you can override the set preload method, and instead of listening for the complete event as the base class does, listen for the INIT_COMPLETE event, which indicates that the application has loaded, and had its initialize event dispatched. In the event handler for this method, you will get a reference to the PreloadEventBus, check if the application has already set the isReady flag to true, and if not, listen for the READY event.


private function bus:PreloadEventBus = PreloadEventBus.getInstance();

override public function set preloader( value:Sprite ):void
{
   preloader.addEventListener( FlexEvent.INIT_COMPLETE , initComplete);
}

An important thing to note is the lack of call to super.preloader in this overridden setter. If the base classes setter is allowed to run, the preloader will act as initially intended, such that it disappears when the application is done downloading. As the purpose of this preloader is to allow for the application to determine when to hide the preloader and start the app, its important we override this functionality. You may find that you need to listen for other events here, such as ProgressEvent.PROGRESS, FlexEvent.INIT_PROGRESS or Event.COMPLETE. This example shows the bare minimum you would need to make use of the preloader


private function initComplete( event:Event ):void
{
if (bus.isReady)
{
   completePreloader(event)    
}
else
   {
   bus.addEventListener(PreloadEventBus.READY, completePreloader);
}
}

While its not expected that the application will be done with its initialization procedures before the INIT_COMPLETE, but, based on how the application is built, it is possible. To avoid this race condition, the isReady property of the PreloadEventBus is used, so that the preloader only listens for the READY event if the application is not already done with its startup.

Last but not least is the completePreloader method, which is called when the preloader has determined that the application is ready. With the logic in initComplete, this same method will be used, regardless whether the state of the application was determined by the isReady property, or by listening for the PreloadEventBus.READY event.


private function completePreloader(event:Event):void
{
   dispatchEvent( new Event( Event.COMPLETE ) );   
}

Event.COMPLETE is used, as this is the event for which the system manager listens, to know that the preloader is done with its job. By preventing its normal mechanism of dispatching, and only dispatching it when the application determines it is ready, you have a nice clean approach to allow the the preloader to display as long as it needs to.

I'll be speaking at Adobe MAX again this year

For the 9th year of the last decade I'll be speaking at Adobe MAX, being held this year in Los Angeles, between October 3rd and October 7th. This time, adobe has asked me to present two sessions, one an "Intro to Flex 4," and the other a session on "How not to code Flex Applications." You can find information on registration and everything else at max.adobe.com

If the schedule stands as planned, I'll present my "How not to code" 10/6 at 3pm, and my "Intro to Flex 4" 10/5 at 11:30am



In case you are wondering, here is what I have spoken on in years past...

  • 2009 - Los Angeles - How Not To Code Flex, Intro to Flex 4
  • 2008 - San Francisco - Intro to Flex 3
  • 2007 - Chicago - Intro to Adobe AIR / Building Desktop applications with HTML and AIR
  • 2006 - Las Vegas - Getting Started with Flex Development
  • 2005 - Anaheim - Creating Better Performing Flex Applications
  • 2004 - New Orleans - Using ColdFusion to Power Flex and Flash Applications
  • 2003 - Salt Lake City - XML in ColdFusion / Building Components in Flash
  • 2002 - Orlando - Styling a Flash Application
  • 2001 - Orlando - Did not speak
  • 2000 - Washington DC - Planning a Spectra Application

FlexUnit 4 feature overview

How not to code Flex Applications

Do you want FlexUnit 4 support in FlexBuilder 4?

The Flex Builder needs to know if you, the flex community want FlexUnit 4 to be supported in FlexBuilder 4.
Spend a few minutes reading about FlexUnit 4, and if you would like flexbuilder to support it, you can cast your vote for it here

Have you bought your Flex 36o Indy tickets yet?

They are selling fast, and it promises to be jam packed with geeky fun! I'll be giving my session on How Not to Code Flex Applications, and doing a joint presentation with Mike Labriola on cleaner living with Flex Unit 4.

What does $550 buy you at 360|Flex Indy? - http://tinyurl.com/rxtkb9

  • Almost 60 sessions of Flex, AIR and ActionScript goodness
  • 4 days of conference sessions
  • 4 days of lunch (great for networking)
  • 3 evening receptions at Rock Bottom (again, great for networking)
  • 2 (maybe more) product launches (Axiis and others)
  • 1 Bug Quash event on Sunday (come make Flex better)
  • 1 Flex 101 hands-on also on Sunday (to get you prepped for the week)
  • 1 Charity Code Jam over the course of the show (to earn some Karma points)
  • 1 USB drive jam packed with copies of the sessions and code samples, plus some extra surprises
  • A chance to attend the only 360|Flex of 2009

So stop reading this and buy your tickets already, ok?

What is so difficult about broadcasting MLB.TV?

As a member of the development team for the Major League Baseball MLB.TV project, I've had a somewhat unique perspective on the successes and failures of the project. There is a bit of backlash in the blogosphere about the technologies surrounding the players, and the inherent superiority of one technology over the other. This post examines only the technologies involved in the situation, and not any of the underlying business decisions surrounding it.

So, what is so difficult about broadcasting MLB.TV? Funny you should ask, regardless of all the Flash vs Silverlight debate that has surrounded the MLB.TV launch this year, the player itself represents only about 10% of the complexity. So, how does it all work? There are a series of inter-related processes involved.

  1. Acquisition of feeds – Home and away video feeds from the ball park are provided by the networks covering the games. If there are problems with those feeds, the video/audio never makes it to MLB. As an example of this, in one of the opening games, an unplugged cable in the feed truck was responsible for lack of an audio feed in the MLB.TV player. There are any number of things which could go wrong at the ball park or in the broadcast trucks to provide the signal. Assuming all is acquired properly, the next step is...
  2. Encoding of feeds – The video and audio content streams from the broadcasters at the ballpark across the network to the MLB Advanced Media offices in New York City. There, the data is encoded into various formats for the various players, including MLB.TV, Gameday Audio, iPhone, etc. For MLB.TV, the stream is encoded at 7 different bit-rates, so the proper quality of video can be delivered, based on the end users connection speed to the internet.
  3. Provisioning – As a game starts, all of the data about the game and the feeds available for it needs to be provisioned into internal systems at MLB. This data is used by all the various applications to determine what game's are available, what feeds are available for each game, and which qualities are available for each feed. If one of the encoders fails, or one of the feeds drops, or anything else goes wrong in steps 1 and 2, the data needs to be re-provisioned to reflect the current accurate data for a game.
  4. Services - There are a series of Java based services which consume the provisioned data, and make it available to the player and other applications. Amongst the jobs the services provide are login, authentication, geo detection (to help enforce blackout restrictions), managing stream security and more. Of course, these services are dependent on the data about each game being available and accurate.
  5. Streaming Servers – There are dozens of Flash Media Servers at the Content Delivery Network (CDN) partner of MLB, from which all the video and audio (and lots of other things too) are streamed to the end user. The CDN has the capacity to stream hundreds of thousands of games at once.
  6. MLB.TV player – While this is the only part of the process most end users see, this is merely a front end to all the systems described above. While we are constantly finding problems, fixing them, making improvements, testing to ensure we haven't caused other problems, 99% of all bugs reported in the Forums and MLBlog actually relate to one of the "upstream" elements of this system. As I mentioned earlier, an unplugged cable caused hundreds to complain that our flash version of the media player couldn't properly play sounds. Obviously, that wasn't the problem, as all the other games, and even the other feed for that game properly had the audio channels playing, it's simply a matter of the player playing the content which was provided to it.
So, let's stop all the Silverlight vs Flash bickering shall we? Both are capable of doing the job. This year, MLB chose flash, last year they chose Silverlight. Neither decision should be used to bludgeon the other over the capabilities or lack thereof that the technology represents. Both would have a similar set of problems displaying streams that aren't properly acquired or encoded. Both would similarly display correct or incorrect information about blackouts, based on what the services layer provides.
All told, I'm honored to be a part of the team which made this all possible, am proud that the vast majority of users are able to view high quality content of the games as they are played, and will work tirelessly to help fix the problems reported by the others.

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.9.001.