PropertyListSerializer

Author: capnbishop

Description
The PropertyListSerializer.js script is used to load and save an XML property list file to and from a hierarchical hashtable (in which the root hashtable can contain child hashtables and arrays). This can provide a convenient and dynamic means of serializing a complex hierarchy of game data into XML files.

When loading, the resulting hashtable can include 8 different types of values: string, integer, real, date, data, boolean, dictionary, and array. Data elements are loaded as strings. Dictionaries are loaded as hashtables. Arrays are loaded as arrays. Each value is loaded with an associating key, except for elements of an array. Thus, each child hashtable and array also have associating keys, and can be combined to create a complex hierarchy of key value pairs and arrays.

When saving, the resulting XML file will contain the same hierarchy of data. All data will end up being stored as a string, but with an associated value type. Strings, integers, and decimals values are stored as such. Dates are stored in ISO 8601 format. Hashtables are stored as a plist key/value dictionary, and arrays as a series of keyless values.

The loader passes a lot of values by reference, and performs a considerable amount of recursion. Primitive values had to be passed by reference. Unity's JavaScript only passes objects by reference, and cannot explicitly pass a primitive by reference. As such, we've had to create a special ValueObject, which is just an abstract object that holds a single value. This object is then passed by reference, and the primitive value is set to its val property.

This plist loader conforms to Apple's plist DOCTYPE definition: http://www.apple.com/DTDs/PropertyList-1.0.dtd

Usage
To load a plist, call the LoadPlistFromFile(String, Hashtable) function and pass it the path to a plist file and a hashtable that will be populated with the plist data. LoadPlistFromFile(String, Hashtable) will return true if the operation was successful. The plist passed must not be null, as it has to be passed by reference.

The easiest way to create a plist is with Apple's Property List Editor, which is a part of the Xcode developer tools.

LoadPlistFromFile needs to be passed an already instantiated hashtable, because that hashtable is passed by reference. Because of this, it is also able to be passed an already populated plist hashtable. This is fine, and the script will mesh the two hashtables by overwriting the values of existing keys along the hashtable tree structure. For sub-hashtables, the overwriting will follow the structure, and only overwrite the existing keys within the sub-hashtables. Essentially, sub-hashtables themselves aren't overwritten, but the key/value pairs within them can be. Elements of arrays are simply appended to the existing array, and not overwritten at all.

To save a hashtable to file, call the SavePlistToFile(String, Hashtable) function and pass it the path to the destination plist file, and the hashtable to be saved. SavePlistToFile(String, Hashtable) will return true if the operation was successful.