Actionscript:
-
package {
-
-
import flash.display.Sprite;
-
import flash.utils.describeType;
-
-
public class Main extends Sprite {
-
-
public function Main(){
-
var test:Test = new Test();
-
var desc:XML= describeType(test);
-
// public vars
-
for each (var v:XML in desc.variable){
-
trace(v.@name, test[v.@name]);
-
}
-
// getters
-
for each (v in desc.accessor){
-
trace(v.@name, test[v.@name]);
-
}
-
}
-
-
}
-
}
-
-
class Test{
-
public var a:Number = 123;
-
public var b:Number = 100;
-
private var _getterVal:Boolean = false;
-
public function get getter():Boolean{
-
return _getterVal;
-
}
-
}
-
/*
-
outputs:
-
b 100
-
a 123
-
getter false
-
*/
I'm working on a few libraries, QuickBox2D and a library for auto-generated UI stuff... this technique just came in handy. It shows how to use describeType() to loop through public vars and getters of a given class.
The title of this post should really be Loop Through All PUBLIC properties of a class.... but it was long enough as it is....
Note: this should be run as document class
Also posted in OOP, Object, dynamic | Tagged actionscript, flash |
By Zevan | February 6, 2009
Actionscript:
-
// for simplicity I left this XML inline, this will work exactly the same if it were external
-
var program:XML=<body>
-
<draw>
-
<![CDATA[
-
beginFill(0xFF0000);
-
drawCircle(100,100,50);
-
endFill();
-
lineStyle(0, 0x666666);
-
moveTo(100, 100);
-
lineTo(200, 200);
-
moveTo(300, 200);
-
curveTo(350, 300, 400, 200);
-
lineStyle(0, 0x0000FF);
-
drawRect(200, 50,100,100) ;
-
]]>
-
</draw>
-
</body>;
-
-
// parse and run the Graphics class commands from the XML
-
render(parseFunctions(program.draw.toString()));
-
-
function parseFunctions(dat:String):Array{
-
var a:Array = dat.split(";") ;
-
for (var i:int = 0; i<a.length-1; i++){
-
a[i] = a[i].split(/\(\)|\(|\)/g);
-
var f:String = a[i][0] = a[i][0].replace(/\s/g,"");
-
a[i] = a[i].splice(0, a[i].length - 1);
-
if (a[i].length> 1){
-
a[i] = a[i][1].split(",");
-
a[i].unshift(f);
-
}
-
}
-
return a.splice(0,a.length - 1);
-
}
-
function render(p:Array):void {
-
for (var i:int = 0; i<p.length; i++) {
-
graphics[p[i][0]].apply(graphics,p[i].splice(1));
-
}
-
}
The above code builds on yesterdays post by showing how one could potentially store graphics class method calls in XML using a few regular expressions and Function.apply().
The parseFunctions() function reads through the CDATA string and formats it in a 2D array that looks like this:
Actionscript:
-
[[beginFill, 0xFF0000], [drawCircle, 100, 100, 50], etc...]
The render() function reads through this 2D array, using the first value of each nested array as the function and the remaining values as arguments...
As is this won't really work with most of the new fp10 graphics methods...
By Zevan | December 30, 2008
Actionscript:
-
var backgroundColor:uint = 0xEFEFEF;
-
var borderColor:uint = 0xFF0000;
-
var buttonOverColor:uint = 0x0000FF;
-
var buttonOutColor:uint = 0x00CCCC;
-
-
var uiColors:XML = <ui>
-
<default color="0xCCCCCC" />
-
<background color = { backgroundColor } />
-
-
<!-- note hexidecimal formatting code -->
-
<border color={ ("0x" + borderColor.toString(16)) } />
-
-
<button overColor={ buttonOverColor} outColor={ buttonOutColor } />
-
</ui>
-
-
trace(uiColors.toXMLString());
-
-
/*outputs:
-
<ui>
-
<default color="0xCCCCCC"/>
-
<background color="15724527"/>
-
<border color="0xff0000"/>
-
<button overColor="255" outColor="52428"/>
-
</ui>
-
*/
The first time I needed to use an ActionScript variable within inline XML I was stumped. I couldn't figure it out and I wasn't able to easily find it on google. I eventually found it somewhere (don't remember where... possibly hidden away in the docs).
Now a search for "insert actionscript variables into e4x" on google gives plenty of results. But I figure it's worth a post.
I use actionscript to generate XML all the time so this comes in handy. I also store color values in automatically generated XML all the time. If I'm feeling organized I'll use something like what you see on line 10:
Actionscript:
-
<border color={ ("0x" + borderColor.toString(16)) } />
If you look at the output you'll see this formats the uint so that it's readable as a hex number. By default (as you can see in the output) uints will show up in decimal notation. This really doesn't make any difference if you don't care about XML readability ... or if you just don't care about the readability of the colors stored in your XML.....
By Zevan | December 29, 2008
Actionscript:
-
var userInfo:XML = <users>
-
<user fname="joe" lname="smith" age="31" />
-
<user fname="mildred" lname="calder" age="64" />
-
<user fname="ben" lname="nathanson" age="20" />
-
<user fname="james" lname="biuford" age="19" />
-
<user fname="nick" lname="calhoun" age="45" />
-
</users>;
-
-
-
trace("Users over 20:\n");
-
trace(userInfo.user.(@age> 20).toXMLString());
-
-
trace("\nUsers with the name nick:\n");
-
trace(userInfo.user.(@fname == "nick" ).toXMLString());
-
-
// use regular expressions with e4x
-
trace("\nUsers with name starting with j:\n");
-
trace(userInfo.user.(/^j/.test(@fname)));
-
-
/*
-
outputs:
-
-
Users over 20:
-
-
<user fname="joe" lname="smith" age="31"/>
-
<user fname="mildred" lname="calder" age="64"/>
-
<user fname="nick" lname="calhoun" age="45"/>
-
-
Users with the name nick:
-
-
<user fname="nick" lname="calhoun" age="45"/>
-
-
Users with name starting with j:
-
-
<user fname="joe" lname="smith" age="31"/>
-
<user fname="james" lname="biuford" age="19"/>
-
-
*/
One of the nicest features of E4X is filtering. The above code shows a few simple examples ... the last example makes use of regular expressions -- I first read using regular expressions and E4X somewhere on http://www.darronschall.com/.
I usually prefer to use a database for any kind of info I'll be searching... but if you know you have a relatively small amount of data XML can be a fine way to go.