Getting autocomplete of object-keys in flashbuilder - actionscript-3

Is it possible to get autocomplete-functionality on objects keys?
var obj:Object = new Object();
obj.name = "AName";
obj.weight = "100";
When I type obj. -> i would like to see the keys(name,weight);
Thanks

Flash builder autocompletes only those properties/methods that are defined in the class (Defined might be a wrong word here, but I guess it is clear what I meant.) It does not autocomplete properties added in this way. As far as I know, this is not possible with flash builder.

create a class :
package {
public class NameWeightVO {
public var name : String;
public var weight : Number;
public function NameWeightVO(pName : String = "", pWeight : Number = 0) {
}
}
}
then you can create a new NameWeightVO Object with autocomplete functionality:
var nameWeightVO : NameWeightVO = new NameWeightVO();
nameWeightVO.name = "name";
nameWeightVO.weight = 10;

Related

Classes vs Objects? as3

I creat two people that are instances of the Person Class
var personOne = new Person;
var personTwo = new Person;
later I create an Object called Chuck;
var Chuck = {age:32, name:"Chuck"}
Now I want to make personOne be a "person" with the properties of "chuck:Object";
Cannot convert Object to Display Object. // Output
If you want to set properties of an object when it is created, you can let the constructor accept them as parameters.
For example:
package
{
public class Person
{
private var _age:uint, _name:String;
public function Person (age:uint, name:String)
{
_age = age;
_name = name;
}
}
}
You use it like so:
var chuck:Person = new Person(32, "Chuck");
This is probably not what you need, but it is what you asked.
var personOne :Person = new Person();
var object:Object = { age:23, name:"efefw" };
for (var prop:String in object)
{
personOne[prop] = object[prop];
}
This will only work for public properties.

AS3 Inspectable Font Chooser

I'm building a component and need to be able to select fonts from a font list. I have the font list showing up but I'm unsure of what the proper datatype is or how I should be setting it. I've tried String and Font and I seem to be getting an error.
private var _tfFormat:TextFormat;
_tfFormat = new TextFormat();
This will produce an 1067: Implicit coercion of type String to unrelated flash.text:Font.
private var _font:Font = null;
_tfFormat.font = font.fontName;
[Inspectable(type="Font Name", name="font", defaultValue="Arial")]
public function get font():Font
{
return _font;
}
public function set font(value:Font):void
{
_font = value;
invalidate();
}
This gives me a 1065 Variable is not defined.
private var _font:String = "";
var __cls:Class = getDefinitionByName(font) as Class;
var __fnFont:Font = new __cls() as Font;
_tfFormat.font = __fnFont.fontName;
[Inspectable(type="Font Name", name="font", defaultValue="")]
public function get font():String
{
return _font;
}
public function set font(value:String):void
{
_font = value;
invalidate();
}
I feel I'm pretty close and it's something ridiculously easy that I'm overlooking. Any set of eyes would be appreciated. Thanks.
Ok I solved the issue.
I changed the data type of the font back to String. As it turns out, if using an embedded font, Flash adds an asterisk to the name; eg: ArialBold* But that asterisk isn't included in the linkage identifier for the font. So in my setter I removed the asterisk and then create a class from string as normal. Here's the (shortened) code.
If there's a better way, I'm still all ears. :)
private var _font:String = "";
private var _tfFormat:TextFormat;
_tfFormat = new TextFormat();
var __cls:Class = getDefinitionByName(font) as Class;
var __fnFont:Font = new __cls() as Font;
_tfFormat.font = __fnFont.fontName;
[Inspectable(type="Font Name", name="font", defaultValue="")]
public function get font():String
{
return _font;
}
public function set font(value:String):void
{
_font = value.split("*").join('');
invalidate();
}

Serializing object using messagepack and as3

This is a vary simple question, but can't find any docs on it.
I have a simple class:
public class User
{
public var name:String;
public var age:int;
}
I would like to serialize it using this:
var user:User = new User();
user.age = 15;
user.name = "mike";
//now serialize
var bytes:ByteArray = MessagePack.encoder.write(vo);
But I get an error:
Error: MessagePack handler for type base not found
How do I let MessagePack know what the User class is, how to serialize it?
MessagePack doesn't look like being able to serialize Class, like most serializer.
I suggest you to add a toObject method to your User class :
public function toObject():Object
{
return {age:this.age, name:this.name}:
}
Then you can serialize your user :
var bytes:ByteArray = MessagePack.encoder.write(user.toObject());
You can also add a static fromObject method which takes an object and returns a new User initialized with this object.
static public function fromObject(o:Object):User
{
var u = new User();
u.age = o.age;
u.name = o.name;
return u;
}

Storing parameter templates to create new entities from?

My entity system for my game uses templates to lay out how entities are created. Something like:
EntityTemplateManager.register("zombie",
new PhysicsComponent(10), // speed
new SpriteComponent("zombie"), // graphic
new HealthComponent(100) // health
);
I like this part of the system because it makes sure I don't miss any parameters or screw up their type.
Then I can create a new entity like this:
entity : Entity = EntityTemplateManager.create("zombie");
Pretty straight forward.
What I do now, to actually create the entity, is have the EntityTemplateManager create 1 entity to use as a default, then I call clone() on the entity and it goes through and clone()s all of its components and returns the result.
Actual code:
public function clone() : Entity
{
var components : Vector.<Component> = new Vector.<Component>();
var length : int = _components.length;
for (var i : int = 0; i < length; ++i)
components.push(_components[i].clone()); // copy my local components to the new entity
return new Entity(_name, _type, components);
}
The problem is, every time I create (design) a new component, I have to write (design) a clone() method inside of it AND keep track of all the parameters that were called on the constructor to create a brand new, default stated component.
So I end up with junk like this:
public class ComponentX
{
protected var _defaultName : String;
protected var _defaultStartingAnimation : String;
protected var _defaultBroadcastAnimationEnded : Boolean;
protected var _defaultOffsetX : Number;
protected var _defaultOffsetY : Number;
// other stuff hidden
public function ComponentX(name : String, startingAnimation : String, broadcastAnimationEnded : Boolean = false, offsetX : Number = 0, offsetY : Number = 0) : void
{
super();
_defaultName = name;
_defaultStartingAnimation = startingAnimation;
_defaultBroadcastAnimationEnded = broadcastAnimationEnded;
_defaultOffsetX = offsetX;
_defaultOffsetY = offsetY;
}
public function clone() : Component
{
return new ComponentX(_defaultName, _defaultStartingAnimation, _defaultBroadcastAnimationEnded, _defaultOffsetX, _defaultOffsetY);
}
// other methods
}
I really don't like this -- it's wasteful and error prone.
How could I best store the parameters of the EntityTemplateManager.register() function (including the components' constructors parameters) and use that new storage to create entities from instead?
I've tried some generic clone() methods like with a ByteArray or describeType(), but they don't work with protected / private variables.
Ideas?
Few months ago I wrote my own Entity-Component manager too. I've done something like this (in your case):
EntityTemplateManager.register("zombie", [
{type: PhysicsComponent, attr: {speed: 10}},
{type: SpriteComponent, attr: {graphic: "zombie"}},
{type: HealthComponent, attr: {health: 100}}
]);
Registering a new template works as below:
private static var definitions:Dictionary = new Dictionary();
public static function register(templateName:String, componentDefinitions:Array):void
{
definitions[templateName] = componentDefinitions;
}
The create function retrieves the specified component template and create components like this:
var components:Vector.<Component> = new Vector.<Component>();
// Create all components
for each (var definition:Object in componentDefinitions) {
var componentClass:Class = definition.type;
var component:Component = new componentClass();
// Set default parameters
for (var prop:String in definition.attr) {
component[prop] = definition.attr[prop];
}
components.push(component);
}
// Then create the entity and attach the freshly created components.
// ...

Get AS3 instance method reference from Class object

class Foo {
public function bar():void { ... }
}
var clazz:Class = Foo;
// ...enter the function (no Foo literal here)
var fun:Function = clazz["bar"]; // PROBLEM: returns null
// later
fun.call(new Foo(), ...);
What is the correct way to do the above? The Java equivalent of what I want to do is:
Method m = Foo.class.getMethod("bar", ...);
m.invoke(new Foo(), ...);
Actual code (with workaround):
class SerClass {
public var className:String;
public var name:String;
private var ser:String = null;
private var unser:Function = null;
public function SerClass(clazz:Class):void {
var type:XML = describeType(clazz);
className = type.#name;
// determine name
name = type.factory.metadata.(#name=="CompactType").arg.(#key=="name").#value;
// find unserializer
var mdesc:XML = XML(type.method.metadata.(#name=="Unserialize")).parent();
if (mdesc is XML) {
unser = clazz[mdesc.#name];
}
// find serializer
var sdesc:XML = XML(type.factory.method.metadata.(#name=="Serialize")).parent();
if (sdesc is XML) {
ser = sdesc.#name;
}
}
public function serialize(obj:Object, ous:ByteArray):void {
if (ser == null) throw new Error(name + " is not serializable");
obj[ser](ous);
}
public function unserialize(ins:ByteArray):Object {
if (unser == null) throw new Error(name + " is not unserializable");
return unser.call(null, ins);
}
}
Here the function bar only exist when your class is instanciated :
var foo:Foo = new Foo()
var fun:Function = foo.bar // <-- here you can get the function from the new instance
if you want to access it directlty you have to make it static:
class Foo {
public static function bar():void{ ... }
}
now you can access your function from the class Foo:
var fun:Function = Foo.bar
or
var clazz:Class = Foo
var fun:Function = clazz["bar"]
I am not sure about what you are intending to do.
However AS3Commons, especially the reflect package have API's that let you work with methods, instances and properties of a class.
There are also API methods to create instances of certain class types on the fly and call their respective methods.
Cheers
It's not
fun.call(new Foo(), ...);
Use instead since no parameters are required for the function
fun.call(clazz);
The first parameter as specified by adobe docs.
An object that specifies the value of thisObject within the function body.
[EDIT]
Forgot to point out you have to instantiate a non-static class with the "new" keyword.
var clazz:Class = new Foo();
[EDIT2]
Ok I played around and think I got what you want.
base.as
package{
public class Base {
public function Base() {
trace('Base constructor')
}
public function someFunc( ){
trace('worked');
}
}
}
//called with
var b:Base = new Base( );// note I am not type casting to Class
var func:Function = b.someFunc;
func.call( );
My workaround is to store the function name instead of the Function object.
var fun:String = "bar";
// later...
new Foo()[fun](...);