mikechambers / as3corelib

An ActionScript 3 Library that contains a number of classes and utilities for working with ActionScript? 3. These include classes for MD5 and SHA 1 hashing, Image encoders, and JSON serialization as well as general String, Number and Date APIs.
1.49k stars 448 forks source link

JSONEncoder now supports correct Vector json serialization #176

Open ghost opened 13 years ago

ghost commented 13 years ago

I add support for serialazing Objects that contains Vector properties

WORMSS commented 12 years ago

I am afraid to say you have not accounted for all types of vectors. If you do some tests you will finds that not all vectors extend Vector.<*>. Yes, I know, I know.. Its evil.

Use else if ( value is Array || value is Vector.<*> || value is Vector.<Number> || value is Vector.<uint> || value is Vector.<int> )

brianreavis commented 12 years ago

@WORMSS That's not the best approach, considering a vector can contain any type of object. Chaining together a giant if statement to handle vectors of ints, uints, Numbers, etc is going to get out of control really fast... and you'll always be missing user-defined types. A better way would be to use describeType() in flash.utils:

if (describeType(value).@name.toString().indexOf('__AS3__.vec::Vector.') == 0) {
   // ...   
}
IQAndreas commented 12 years ago

@brianreavis Actually, Wormss is correct.

Number, uint, and int Vectors are registered as completely different classes and optimized in some fashion to be as fast as possible. Every other Vector class extends Vector.<*>.

The method proposed by Wormss would also be much faster than using describeType.

WORMSS commented 12 years ago

@IQAndreas Thank you. I think the end of your message got cut off. (Atleast on my screen)

@brianreavis Not a giant IF, only 4 (5 including Array). There are only 4 types of Vectors, Number, uint, int and *(wildcard). Numbers are treated differently for performance considerations.

IQAndreas commented 12 years ago

@WORMSS I hit the submit button to early, but went back and edited the message. You were simply too quick to the keyboard. ;)

I noticed another problem with the proposed changes, you can't convert a Vector to an Array like this: vector as Array You simply get a null value (at least in my tests)

I modified the JSONEncoder class further to completely support Vectors now. I haven't actually tested it, but it should work in theory: https://github.com/IQAndreas/as3corelib/commit/27b43ea2b51f8bf57e2337292c7837d48f98835a Does anyone want to test it in a project and see if it works properly?

Also, what is the standard in case a "non-vector" is passed to the function vectorToString()? Should it return "" or "[]", or perhaps throw an error? It doesn't actually matter at the moment since the function is private, but still, it doesn't hurt to be proper. :-/

WORMSS commented 12 years ago

I removed the limit of arrayToString having to accept a Array and had it accept *. Since behide the scenes Array and Vector pretty much work in identical ways from a flash proxy point of view, I just used the same function for both.

Another solution would be to just make a vectorToArray, which is super easy to do, and then send the array via arrayToString.

No duplication of code for both types of list that way.

brianreavis commented 12 years ago

@IQAndreas @WORMSS There are more than four types of vectors. Try it:

var test:Vector.<FileReference>;
trace((test is Vector.<*>) ? "true" : "false");
trace((test instanceof Vector.<*>) ? "true" : "false");
// both yield "false"
IQAndreas commented 12 years ago

@brianreavis That's because the test variable is null.

You need to set it to a non-null value for the code to work properly:

var test:Vector.<FileReference> = null;

// all yield "false"
trace(test is Vector.<*>);
trace(test instanceof Vector.<*>);
trace(test is Vector.<FileReference>);

test = new Vector.<FileReference>();

// all yield "true"
trace(test is Vector.<*>);
trace(test instanceof Vector.<*>);
trace(test is Vector.<FileReference>);
brianreavis commented 12 years ago

Snap, you're right! Der, my bad.