Dynamic Flash

Confessions of a serial code abuser
  • rss
  • Home
  • MTASC
  • Archives
  • About me
  • Goodies
    • Base64 encoder/decoder class
  • My Bookshelf
  • My Talks

ClassFinder class

Thursday, 10 March 2005

In a recent project I needed to instantiate a number of objects of various classes based on configuration data coming from an XML file. Unfortunately instantiating a class at runtime is not straight forward if all you've got to work with is a string. What I needed was some way of getting a reference to the constructor function of a class given the fully qualified class name. Ten minutes of tinkering later, I came up with the ClassFinder class.

PLAIN TEXT
Actionscript:
  1. class com.dynamicflash.utils.ClassFinder {
  2.   public static function find(package:String) : Function {
  3.     var packageParts:Array = package.split(".")
  4.     var obj:Object = _global;
  5.    
  6.     for (var i:Number = 0; i <packageParts.length; i++) {
  7.       obj = obj[packageParts[i]];
  8.     }
  9.    
  10.     return Function(obj);
  11.   }
  12. }

Feeding the ClassFinder.find() method with a fully qualified class name will return a reference to the constructor of the class. You can use this to instantiate an object of that class using new and passing any arguments to the constructor as you would normally.

PLAIN TEXT
Actionscript:
  1. import com.dynamicflash.utils.ClassFinder;
  2.  
  3. var myClass:Function = ClassFinder.find("com.dynamicflash.SomeClass");
  4.  
  5. var instance = new myClass("Test");

Classes are stored in _global with nested objects representing the package hierarchy. All ClassFinder.find() does is split the package name into chunks and descent the nested objects one at a time to find the class constructor function.

So what's the catch? Because of the way the Flash compiler works, any classes that aren't explicitly referenced in any of your code at compile time will not be included in the SWF. This means that ClassFinder won't be able to find them, returning undefined instead. If you want to trick the compiler into including such classes, you need to make a dependancy link to those classes from a class that is explicitly referenced in your code.

PLAIN TEXT
Actionscript:
  1. class com.dynamicflash.SomeOtherClass {
  2.   public function SomeOtherClass () {
  3.     ...
  4.   }
  5.  
  6.   // Create dependancy link
  7.   private static var SomeClassDependancy = com.dynamicflash.SomeClass;
  8. }

This method is used in Macromedia's V2 component core classes to make sure they're all included in the SWF if just one of them is referenced.

--Update--

I've just realised that a very similar class is included with Flash MX 2004 Professional, but adding it to your projects isn't exactly intuitive. You have to open up the Classes common library (via Window » Other panels » Common libraries » Classes in the main menu) and drag the UtilsClasses symbol into your library. You can then use
mx.utils.ClassFinder.findClass() instead of my class.

Why Macromedia didn't just put these classes in the standard folder I don't know, but since using it requires extra work I'll stick with my version of ClassFinder.

Categories
Flash
Comments rss
Comments rss
Trackback
Trackback

« Flash Player Yahoo Toolbar FAQ MTASC 1.03 OS X Binary Release Package »

10 responses

I totally agree there, it's amazing just how these useful

Richard Leggett | Friday, 11 March 2005 | 1:04 am

I totally agree there, it’s amazing just how these useful classes aren’t documented (such as XPath). We had someone ask about it here:
http://flashmove.com/forum/showthread.php?t=17266

Apparently the guy re-wrote it too, must ask what happened to that re-write! I linked to another post on there that may be of interest to you as it’s kinda related, finding which class an object is an instance of (especially good for MovieClips), about halfway down the post.

Excellent tip about the class dependency with static member btw!

Thanks Richard. I'll have a look at this later.

Steve | Friday, 11 March 2005 | 9:36 am

Thanks Richard. I’ll have a look at this later.

Using dependancy links to classes also increases the swf filesize

Bob Donderwinkel | Friday, 11 March 2005 | 12:26 pm

Using dependancy links to classes also increases the swf filesize for each class included. So what’s your aim exactly with runtime instantiating the classes with xml, unless you know already which classes you are going to use?

It would mean you have to include each class as a dependancy in the swf manually in any case, negating the runtime instantiating benefit perhaps. And if you would use a basic class making dependancy links to all classes you could possibly need, the filesize could get bigger then needed since you perhaps wont use all the classes.

Nice work though. I’m guessing your ClassFinder is more streamlined then mx.utils.ClassFinder :).

Why aren't you just using eval? var myClass:Function = Function(eval("fullyQualifiedClassName")); I mean,

Simon Wacker | Friday, 11 March 2005 | 12:45 pm

Why aren’t you just using eval?
var myClass:Function = Function(eval(”fullyQualifiedClassName”));
I mean, you do not do any extra checking whether a class with the given name does even exist and that like.
You are also not checking whether the passed-in class name is null or undefined.
The as2lib does also offer that functionality together with a lot more. Take a look at the Reflection API (org.as2lib.env.reflect). Note that the current version is rather heavy weight. We are going to release an improved and lighter reflection api (together with as2lib 0.1 final) in about 1 month.

@Bob: I'm not too worried about file size here as

Steve | Friday, 11 March 2005 | 1:57 pm

@Bob: I’m not too worried about file size here as the classes I’m choosing between are very lightweight. The reason I need runtime instantiation is that I don’t know which of my classes I need to instantiate until I load the class name from the configuration XML file.

@Simon: Though eval() would indeed work, I try to avoid using it wherever possible. I can’t really explain why, it just feels a little dirty ;) Having said that (and without checking )I guess using eval() would make ClassFinder more efficient, but unless you’re instantiating thousands of objects this way it wouldn’t really be noticable.

Right. If file size would be an issue you could

Bob | Monday, 14 March 2005 | 10:58 am

Right. If file size would be an issue you could perhaps load the dependancy classes in the main swf through a seperate swf, specified by the XML.

That would allow for dynamic updating of the main swf, and a smaller file size as well :).

Bob: Absolutely! In fact, we're going to be doing just

Steve | Monday, 14 March 2005 | 1:18 pm

Bob: Absolutely! In fact, we’re going to be doing just that for our application just as soon as we ship the new version. Now if only I could find an efficient (both byte- and processor-wise) component set with a DataGrid replacement, I’d be laughing.

"Though eval() would indeed work ... it just feels a

Dave | Wednesday, 29 March 2006 | 12:37 pm

“Though eval() would indeed work … it just feels a little dirty”

I know what you mean, but why make work for yourself? As long as code strikes a good balance between readability and efficiency it shoud be a go-er…

Great site by the way.

Great find. Inspired by Spring (http://www.springframework.org/) in Java development, I implemented

Troy | Sunday, 12 November 2006 | 7:35 pm

Great find.

Inspired by Spring (http://www.springframework.org/) in Java development, I implemented an similar (using eval()) because it was easy, so the implementation is xml configrable, allowing debugging versions of the code, dropped in without recompiling.

One plus about your approach is eval() is not supported in Flash9, so your method is probably better.

I use the static reference links to setup a code library that is created by MTASC and pulled in via a skin file on the fly.

[...] http://dynamicflash.com/2005/03/class-finder/ [...]

Actionscript Classes » ClassFinder | Saturday, 16 December 2006 | 5:14 am

[...] http://dynamicflash.com/2005/03/class-finder/ [...]

Leave a comment

You can use these tags : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

About Dynamic Flash

Steve Webster is a Senior Web Developer for Yahoo! in London, UK.

He is more than a little concerned that he defines himself in terms of his career, and that he talks about himself in the third person.

Find out more

Recent Posts

  • Read and write local files with Flash Player 10
  • The problem with SproutCore
  • Yahoo! London seeks Junior Developers
  • I am Singularity
  • Yahoo! Astra component library 1.1 released

Tags

Accessibility ActionScript actionscript3 actionscript 3.0 air apple astro book conference designer filereference file upload Flash flex framework internet internet explorer JavaScript jobs junior microsoft opportunities ria singularity08 skin tutorial urlrequest web developer web development Web Standards Yahoo!

del.icio.us-ed

Stuff

Singularity?
Flex.org - The Directory for Flex
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox