Today's New Content
Search CMX

Advanced Search

Latest Free Content
View All
Free Content
Accessibility

Migrating a Configuration Class to AS3

By: Danny Patterson

Page 2 of 3

Set for printing

Previous Next

Migrating to AS3

Every project you migrate from AS2 to AS3 will be different. There are some things that are the same in every project, like adding a package definition to each of you class files and making you classes public. But there are some changes that require a switch in API or even logic. The remainder of this article will identify the areas that need to be migrated in our Settings class and look at how each of those migration points can be addresses.

Proxy

In our AS2 Settings class we used a special method of the native Object class called __resolve to proxy calls to undefined properties. When an undefined property was called on our class, we would like up that properties value in our XML data object. If that is found in our XML data, then we return that value as the properties value. In this way, our class acts as a proxy to the XML data via simple property accessors.

In AS3 we no longer have a __resolve method in the native Object class. This functionality has been placed in a native class appropriately named Proxy. Our class will extend Proxy and we will override the method used to resolve undefined properties. This method is called getProperty. This all seems very simple, however overriding methods is not as easy in AS3 as it was in AS2. We must use the override keyword in front of our method definition.

Well, that's not so hard, but then we have one additional thing we must do. In order to avoid name conflicts with subclasses, the methods of the Proxy class have been put into a special namespace called flash_proxy. A namespace is a new idea in AS3. It allows for custom visibility of method and property definitions within a class. Actually, public and private are forms of namespaces. Namespaces work a little differently with Proxy than other implementations. In order to use the flash_proxy namespace in our subclass, we simply import it from the flash.util package and use it in place of the public keyword in our method definition.

Also, just like AS2 we must make our class dynamic in order for other classes to call methods that are not defined. The following code shows a simplified version of our Settings class with just the Proxy specific code included:

package com.dannypatterson.config {
  
  import flash.util.flash_proxy;
  import flash.util.Proxy;
  
  
  dynamic public class Settings extends Proxy {
    
    override flash_proxy function getProperty(name:Object):Object {
      return null;
    }
    
  }
  
}

Code 4: Example of a class that extends Proxy and overrides the getProperty method.

Event Dispatching

Event management is now built into the Flash Player. Therefore, we need to make some changes to take advantage of this new feature. Within the Flash Player there is a new class called EventDispatcher and a new interface called IEventDispatcher. Much of the time you will be able to simply extend the EventDispatcher class to add event functionality to your class. However, since we are already extending the Proxy class and AS3 doesn't support multiple inheritance; we must implement the IEventDispatcher interface and add the event functionality through composition.

Composition is a form of inheritance. Where true inheritance (using the extends keyword) creates an "is a" relationship with the base class, composition creates a "has a" relationship. The following code shows a simple class with only the event functionality added via composition:

package com.dannypatterson.config {
  
  import flash.events.Event;
  import flash.events.EventDispatcher;
  import flash.events.IEventDispatcher;
  
  
  public class Settings implements IEventDispatcher {
  
    private var eventDispatcher:EventDispatcher;
    
    
    public function Settings() {
      eventDispatcher = new EventDispatcher();
    }
    
        
    public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0):Void {
      eventDispatcher.addEventListener(type, listener, useCapture, priority);
    }
    
    public function dispatchEvent(event:Event):Boolean {
      return eventDispatcher.dispatchEvent(event);
    }
    
    public function hasEventListener(type:String):Boolean {
      return eventDispatcher.hasEventListener(type);
    }
    
    public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):Void {
      eventDispatcher.removeEventListener(type, listener, useCapture);
    }
    
    public function willTrigger(type:String):Boolean {
      return eventDispatcher.willTrigger(type);
    }
    
  }
  
}

Code 5: Example showing how to add native event functionality to your class using composition.

E4X

E4X is an exciting new feature that has been added to AS3. E4X stands for ECMAScript for XML and is a new way to handle XML in all ECMAScript-based languages. Many developers have been anxiously awaiting E4X since it was announced by ECMA International in the summer of 2004. Since ActionScript is based on ECMAScript and Macromedia had made it public that their goal was to make ActionScript fully comply to the ECMAScript 4 Proposal; it was assumed that ActionScript would one day have E4X. Well That day has finally come.

In our AS2 version of the Settings class, we used the XPath library from XFactorStudio to retrieve the proper XML data based on the undefined property name in the __resolve method. Because E4X includes filter functionality within its specification, we no longer need to use XPath. E4X also supports the use of XML namespaces. Therefore, we can use that when constructing our E4X expression since our XML configuration data uses a namespace.

AS3 also loads data differently than AS2. In AS2 we used the actual load method of the XML class to load an external file. AS3 introduces a couple new classes that now handle the request and load of external files. Using the new URLRequest and URLLoader classes built into the player we can write some very simple code that makes the request, listens for the complete and error events, and loads in the external file.

The following code shows a simple class that loads in the XML data and then has an E4X expression that extracts the value attribute of the property node with an id of test:

package com.dannypatterson.config {
  
  import flash.events.Event;
  import flash.events.ErrorEvent;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import flash.util.trace;
  
  
  public class Settings {
  
    private var urlLoader:URLLoader;
    private var data:XML;
    static public var URL:String = "";
    
    
    public function Settings() {
      var urlRequest:URLRequest = new URLRequest(Settings.URL);
      urlLoader = new URLLoader();
      urlLoader.addEventListener("complete", onXMLDataLoaded)
      urlLoader.addEventListener("ioerror", onXMLDataFailed)
      urlLoader.load(urlRequest);
    }
    
    
    private function onXMLDataLoaded(event:Event):Void {
      data = XML(urlLoader.data);
      var cs:Namespace = data.namespace("cs");
      trace(data.cs::properties.cs::property.(@id = "test").@value);
    }
    
    private function onXMLDataFailed(errorEvent:ErrorEvent):Void {
      trace(errorEvent);
    }
      
  }
  
}

Code 6: Example of how to load in XML and use create an E4X expression in AS3.

Page 2 of 3 Previous 1 2 3 Next


download
Download Support Files


Keywords
AS2, AS3, ActionScript, ActionScript 3, Zorn, Flex, Flex 2, Flex Builder 2, Zaphod, Flash Player 8.5, Flash, E4X, Proxy, EventDispatcher, Migrate, Migration, Migrating