Introduction

Flash is a lightweight cross-platform runtime for rich media, enterprise applications and mobile applications, as well as an integrated development environment. Flash can be programmed in ActionScript 1/2/3.

Archive for the ‘Flash’ Category

Thursday, October 13th, 2005

As2ant 1.0 beta, Released!

Changes include:

* Better readability of generated commandline output.
* Support for local variable inference: -infer
* Support for package-attribute: -pack
* New way of specifying sources, via XML

The new way of specifying sources via XML is especially important. Because this allows you to write a xml log configuration for the As2lib logging framework and specify this xml log configuration as source xml in your mtasc or swf tasks.

Check it out yourself!

Download As2ant 1.0 beta.

The next release will contain

* a task for As2api,
* fixes for all the bugs you encounter and
* implementations of new features you need.

I hope you enjoy working with the tasks!

Wednesday, September 28th, 2005

As2ant - Swf, Swfmill and Mtasc Ant Tasks

As2ant - Apache Ant Tasks for MTASC and Swfmill - has finally been released officially. It is a sub-project of the As2lib and provides convenient Ant integration for MTASC and Swfmill together with a Swf Task that is a mixture between the Mtasc and Swfmill Tasks and allows for easier usage.

Download As2ant 1.0 alpha.

For further information on Ant take a look at the OSFlash Page: Ant [Open Source Flash]

If you find any errors please report them. If you want a new feature tell me about it. If you need support contact me. ;)
I hope you’ll love working with the tasks.

Friday, August 19th, 2005

As2lib 0.9.2, Released!

We have just released a new version of the as2lib - Open Source ActionScript 2.0 Library - 0.9.2.

Highlight of this release is the revised Aspect Oriented Programming (AOP) framework.

  • WithinPointcut - Capture join points based on their lexical-structure.
  • NotPointcut - Capture pointcuts based on characteristics they are not allowed to have.
  • ’super’ - Advised join points can use ’super’ now.
  • And of course a lot of bug fixes were made.

All Features at a Glance

  • Event Handling - org.as2lib.env.event
  • Exception Handling - org.as2lib.env.except
  • Logging - org.as2lib.env.log
  • Overloading - org.as2lib.env.overload
  • Reflections - org.as2lib.env.reflect
  • Aspect Oriented Programming (AOP) - org.as2lib.aop
  • Data Holders/Structures and Iterators - org.as2lib.data.holder
  • Numerical Types - org.as2lib.data.type
  • Connections - org.as2lib.io.conn
  • Unit Testing - org.as2lib.test.unit
  • Mock Object - org.as2lib.test.mock
  • Speed Testing (Profiler) - org.as2lib.test.speed
  • Application (Process and Configuration) - org.as2lib.app
  • Utilities for Arrays, Strings, Classes, … - org.as2lib.util

Download As2lib Release 0.9.2.

View the API Documentation online.

If you find bugs, if you need a new feature, if you need help or if you want to discuss functionalities or anything else with us, please use the appropriate response mechanism: Response.

We depend on the feedback from the community to improve the framework.

I hope you enjoy this new release (and remember we are not far away from release 1.0 ;).

Monday, July 4th, 2005

As2lib 0.9.1 Release

As2lib Version 0.9.1 with the latest bug fixes and new features is finally available for download.

Download As2lib 0.9.1.

New as2lib features include:

  • Support for list data structures/holders (org.as2lib.data.holder.list).
  • Filter support for log handlers (org.as2lib.env.log.handler).
  • Logging support for the Log4F Logging Framework from Peter Armstrong.
  • Logging support for the as2logger Framework from Ralf Siegel.
  • Logging support for ZTOR Log4f from Andrey Orlov.
  • Logging support for Fludge.
  • Logging support for the new and old version of Flashout.
  • Logging support for the new version of Alcon.

The as2lib is:

  • Mtasc, Flash and Flex compatible.
  • Unit tested and stable.
  • Modular.
  • Well documented: API documentation.

The most noticeable features of the as2lib are:

  • An event api split into three parts to serve different preferences and needs - org.as2lib.env.event
  • An exception api that gives comprehensive information about the problem through a detail message, an exception cause and a stack trace - org.as2lib.env.except
  • An improved logging api that is easy to use and fast; It allows for easy inclusion of other logging apis and consoles - org.as2lib.env.log
  • Better overloading capabilities of the overloading api - org.as2lib.env.overload
  • Fast and easy to use reflection api - org.as2lib.env.reflect
  • A comprehensive set of data holders/structures and iterators needed in daily work - org.as2lib.data.holder
  • Different mainly numerical type formats - org.as2lib.data.type
  • A local connection api that allows for return values and even sends exceptions over the wire - org.as2lib.io.conn.local
  • A unit testing api that allows for easy asynchronous testing - org.as2lib.test.unit
  • A mock object api that can be easily integrated with the unit testing api - org.as2lib.test.mock
  • A speed test api (profiler) - org.as2lib.test.speed
  • Support for processes and easy configuration - org.as2lib.app
  • Different utilities for strings, objects, classes, arrays and a date formatter that do simple but often needed tasks - org.as2lib.util

On feedback of every kind, be it bugs, new features or questions, give it. We are always eager to answer questions and to improve the As2lib Framework by fixing bugs or adding new features.
You may also want to discuss features with us or join the mailing list to stay up-to-date.

The API documentation of the last release, version 0.9, is still available: As2lib 0.9 API Documentation.

Visit our homepage for more information: www.as2lib.org.

I hope you enjoy this latest release.

Tuesday, June 7th, 2005

As2lib Reflection API

What are reflections? Is Flash supporting reflections? What functionalities is the As2lib Reflection API (org.as2lib.env.reflect) offering me and how can I use these functionalities?

Note that this article has also been published on the official as2lib homepage: As2lib Reflection API.

Reflection Basics

What are reflections? How do reflections help me with development? What other programming languages support reflections?

Reflections help you find out everything about your API at run-time; your API is reflected. For example the name of a class an instance was instantiated of or all methods declared by a class that match a given naming pattern. In theory there are nearly no bounds. In languages that support reflections by default, like Java or C#, it is even possible to find out about the parameters of methods and their types.

As I now already stated, the programming languages Java and C# have reflections support. The reflection mechanism of these languages is built-in. These reflection APIs are thus in some respects more powerful than the one I will present in this article.

The most common usage of reflections is to generate good string representations of objects. These string representations can then be used for logging and in error/detail messages. But you can also use reflections to map from a XML file, database or property file to an object. Another common usage is the creation of dynamic factories (GoF, Factory Design Pattern) that resolves classes by name at run-time or instantiates passed classes.

If you are an experienced ActionScript programmer you may have noticed that all these things are possible with a ‘little’ knowledge of ActionScript 1.0 and Flash right now; except finding out class, properties and methods names. But what is missing is a good API that accomplishes these tasks in a performant and save way. Performance is gained by caching results and by good algorithms, safety by comprehensive test suites, a well-typed API, good run-time checks and the assurance that everything works fine in Flash, Flex and with MTASC.

In case you have been hooked: go-on reading and step directly into the As2lib Reflection API.

The Reflection Utility

What is the light-weight reflection utility? What services does it offer? What are its advantages?

The As2lib Reflection API is split into two parts, a light-weight and a heavy-weight one. The light-weight part exists only of one class, the ReflectUtil. This class offers basic methods to look up names of types and methods and to find out whether a specific method is static (per class) or is a constructor.

Its advantages are:

  • It is light-weight. This means that the class has little dependencies and the SWF file size is thus only increased by a minimum.
  • Its usage is quite simple. You do not have to deal with multiple classes and instances, but only invoke static methods.
  • It is fast. Note that the heavy-weight part is also fast, but maybe a little slower because of more delegation. But this speed difference is really at a minimum.

Its disadvantages are:

  • It may not offer all needed functionalities.
  • It does not cache results.
  • It offers only a low-level API.
  • It is neither flexible nor extensible.

Depending on your needs this class may be all you need. The As2lib always uses this class internally to look up API names that are in most cases included in log or error messages.

The most common usage is to look up type names. You have two options: you can either get the type name directly for a class (this is a function in ActionScript) or for an instance of a class.

  1. import org.as2lib.env.reflect.ReflectUtil;
  2. import com.mydomain.myapplication.MyClass;
  3.  
  4. // traces the name of the class looked up by a class
  5. trace("By Class: " + ReflectUtil.getTypeName(MyClass));
  6.  
  7. // traces the name of the class looked up by an instance
  8. var myInstance:MyClass = new MyClass();
  9. trace("By Instance: " + ReflectUtil.getTypeName(myInstance));
  10.  

The output of the above code is:

  1. By Class: com.mydomain.myapplication.MyClass
  2. By Instance: com.mydomain.myapplication.MyClass

The same approach applies to looking up method names. You again have the option between using a class or an instance as basis. Note that either the class itself or any super-class must implement the searched for method. Note that the following example is not a real-life example but just a demonstration of the different ways of performing the wanted task.

  1. import org.as2lib.env.reflect.ReflectUtil;
  2. import com.mydomain.myapplication.MyClass;
  3.  
  4. // traces the name of the per class method looked up by class and method
  5.  
  6. trace("By Class: " + ReflectUtil.getMethodName(MyClass.myStaticMethod, MyClass));
  7.  
  8. // traces the name of the per instance method looked up by class and method
  9. trace("By Class: " + ReflectUtil.getMethodName(MyClass.prototype.myMethod, MyClass));
  10.  
  11. // traces the name of the per instance method looked up by instance and method
  12. var myInstance:MyClass = new MyClass();
  13. trace("By Instance: " + ReflectUtil.getMethodName(myInstance.myMethod, myInstance));

If you run the above code you get the following output:

  1. By Class: myStaticMethod
  2. By Class: myMethod
  3. By Instance: myMethod
  4.  

A futher important method is the “getTypeAndMethodInfo” method. This method returns all needed information about the type and the method. This is whether the method is static (per class), the fully qualified name of the type and the name of the method. You may wonder why not just using the available methods to fulfill all these tasks step-by-step. This would work, but it is slower and needs more method calls. Another more important issue is that the method may not be directly implemented by the passed type, but by its super-type. In such a case you’d want the type name to be the one that implements the method and not the passed one. All this is taken into account by this method, which makes it important to mention.

  1. import org.as2lib.env.reflect.ReflectUtil;
  2. import com.mydomain.myapplication.MyClass;
  3.  
  4. // gets the type and method information
  5. var info:Array = ReflectUtil.getTypeAndMethodInfo(MyClass, MyClass.myStaticMethod);
  6.  
  7. // if the method is static ‘info[0]’ is ‘true’ otherwise ‘false’
  8. var output:String = info[0] ? "static " : "";
  9.  
  10. // adds the fully qualified type name
  11. output += info[1];
  12.  
  13. // adds the method name
  14. output += "." + info[2] + "()";
  15.  
  16. // traces the output
  17. trace(output);

The output is:

  1. static com.mydomain.myapplication.MyClass.myStaticMethod()

If the method were not static and were implemented by a super-class the output would have looked something like this:

  1. com.mydomain.myapplication.MySuperClass.myMethod()

For the full-range of methods and their usage take a look at the API documentation. Now let’s go-on to the full-featured API.

The Class Info

How can I find out everything about a class? What methods and properties does it declare? What are its super-classes? What is its namespace and of which package is it a member of? How can I get all its methods and properties that match a given criteria?

When you use the As2lib Reflection API the first thing you need is in most cases a ClassInfo instance. Given this instance for a specific class you can perform almost all operations offered by the API related to your class. Note that the “ClassInfo” represents classes as well as interfaces because a differentiation is not possible at run-time. To get a “ClassInfo” instance for your specific class you need either the class itself, an instance of that class or the name of the class.

  1. import org.as2lib.env.reflect.ClassInfo;
  2. import com.mydomain.myapplication.MyClass;
  3.  
  4. // gets a class info by class
  5. var classInfoByClass:ClassInfo = ClassInfo.forClass(MyClass);
  6.  
  7. // gets a class info by instance
  8. var myInstance:MyClass = new MyClass();
  9. var classInfoByInstance:ClassInfo = ClassInfo.forInstance(myInstance);
  10.  
  11. // gets a class info by name
  12. var classInfoByName:ClassInfo = ClassInfo.forName("com.mydomain.myapplication.MyClass");
  13.  

All these class infos are functionaly the same, they are even the same instances; the only thing that differs is how they were obtained. Given such a class info instance you can get the following basic information.

  1. trace("The class’s name: " + classInfo.getName());
  2. trace("The class’s fully qualified name: " + classInfo.getFullName());
  3. trace("The super class’s fully qualified name: " + classInfo.getSuperType().getFullName());
  4. trace("The class’s namespace: " + classInfo.getPackage().getFullName());
  5. trace("The class’s constructor: " + classInfo.getConstructor());
  6. trace("The declared methods: " + classInfo.getMethods(true));
  7. trace("The declared properties: " + classInfo.getProperties(true));
  8.  

If you like to you can also create a new instance of the represented class.

  1. var newInstance:MyClass = classInfo.newInstance("arg1", 2);

To get a MethodInfo instance that represents a method of your class or any super-class you have the name of or the concrete method as function you can use the “ClassInfo.getMethod” method. Note that the following works totally the same for properties, but with a PropertyInfo and the “ClassInfo.getProperty” method.

  1. import org.as2lib.env.reflect.MethodInfo;
  2.  
  3. // gets a method info by name
  4. var methodInfoByName:MethodInfo = classInfo.getMethod("myMethod");
  5.  
  6. // gets a method info by concrete method
  7. var myInstance:MyClass = new MyClass();
  8. var concreteMethod:Function = myInstance.myMethod;
  9. var methodInfoByConcreteMethod:MethodInfo = classInfo.getMethod(concreteMethod);
  10.  

Now let us come to a little more complex method, the “ClassInfo.getMethods” method. In its simplest from, which I used in an example at the beginning, this method simply returns either only the methods declared by the class itself or this method and the one of all super-classes. But it is also possible to use your own filter criteria. You must therefore at first create a class that implements the TypeMemberFilter interface. You can then implement your filter criteria in the “filter” method that returns “true” if the passed-in type member shall be excluded/filtered or “false” if not. Let us say we want to filter all methods that do not start with the string “add”.

  1. import org.as2lib.env.reflect.TypeMemberFilter;
  2. import org.as2lib.env.reflect.TypeMemberInfo;
  3.  
  4. class MyMethodFilter implements TypeMemberFilter {
  5.  
  6.     public function TypeMemberFilter(Void) {
  7.     }
  8.  
  9.     public function filter(typeMember:TypeMemberInfo):Boolean {
  10.         if (typeMember.getName().indexOf("add") == 0) {
  11.             return false;
  12.         }
  13.         return true;
  14.     }
  15.  
  16.     public function filterSuperTypes(Void):Boolean {
  17.         return false;
  18.     }
  19. }
  20.  

You can now use an instance of the filter “MyFilter” as parameter for the “ClassInfo.getMethods” method to receive only methods that have the prefix “add”.

  1. var methods:Array = classInfo.getMethods(new MyMethodFilter());
  2.  

The above mechanism for methods works the same for properties. You only have to use the equivalent property methods. Take a look for these in the API documentation of the “ClassInfo” class.

The Package Info

How can I find out everything about a package? What members, classes and packages, does it have? What are its parent packages? How can I get all its members that match a given criteria?

As with class infos you can get PackageInfo instances either by a concrete package or by name.

  1. import org.as2lib.env.reflect.PackageInfo;
  2.  
  3. // gets a package info by concrete package
  4. var packageInfoByPackage:PackageInfo = PackageInfo.forPackage(com.mydomain.myapplication);
  5.  
  6. // gets a package info by name
  7. var packageInfoByName:PackageInfo = PackageInfo.forName("com.mydomain.myapplication");
  8.  

The two returned package infos are functionally and physically the same, they are the same instance. Given either of these instances you can find out the following basic information.

  1. trace("The package’s name: " + packageInfo.getName());
  2. trace("The package’s fully qualified name: " + packageInfo.getFullName());
  3. trace("The parent package’s name: " + packageInfo.getParent().getName());
  4. trace("Is this package a/the root package?: " + packageInfo.isRoot());
  5. trace("The package’s member classes: " + packageInfo.getMemberClasses());
  6. trace("The package’s member packages: " + packageInfo.getMemberPackages());

A specific member class or package can also be obtained either by concrete class or package or by name.

  1. import org.as2lib.env.reflect.ClassInfo;
  2. import com.mydomain.myapplication.MyClass;
  3.  
  4. // gets a class member by name
  5. var classMemberInfoByName:ClassInfo = packageInfo.getMemberClass("MyClass");
  6.  
  7. // gets a class member by concrete class
  8. var classMemberInfoByClass:ClassInfo = packageInfo.getMemberClass(MyClass);
  9.  
  10. // gets a package member by name
  11. var packageMemberInfoByName:PackageInfo = packageInfo.getMemberPackage("mymodule");
  12.  
  13. // gets a package member by concrete package
  14. var packageMemberInfoByPackage:PackageInfo = packageInfo.getMemberPackage(com.mydomain.myapplication.mymodule);
  15.  

In the previous article on class infos we talked about getting methods or properties that match a given criteria. This is also possible with package infos but the criteria must now be met by member classes and member packages. We do again need a filter that filters/excludes unwanted package members. This filter must implement the PackageMemberFilter interface. This time we want to include all abstract classes that start with the “Abstract” string to be included in the result; sub-packages shall also be searched through.

  1. import org.as2lib.env.reflect.PackageMemberFilter;
  2. import org.as2lib.env.reflect.PackageMemberInfo;
  3.  
  4. class MyClassMemberFilter implements PackageMemberFilter {
  5.  
  6.     public function PackageMemberFilter(Void) {
  7.     }   
  8.  
  9.     public function filter(packageMember:PackageMemberInfo):Boolean {
  10.         if (packageMember.getName().indexOf("Abstract") == 0) {
  11.             return false;
  12.         }
  13.         return true;
  14.     }
  15.  
  16.     public function filterSubPackages(Void):Boolean {
  17.         return false;
  18.     }
  19. }

We can now use our filter as follows:

  1. var classMemberInfos:Array = packageInfo.getMemberClasses(new MyClassMemberFilter());

Exactly the same mechanism can also be applied to member packages. Take a look at the API documentation of the “PackageInfo” class for the appropriate methods.