Added recursive serialization
This commit is contained in:
parent
508f2e3f94
commit
fd9bdfffdd
|
@ -3,11 +3,12 @@ module SpaceTac.Game {
|
|||
|
||||
// Serializer to cascade through Serializable objects
|
||||
export class Serializer {
|
||||
// List all classes that implement "Serializable", with their full path in SpaceTac.Game namespace
|
||||
collectSerializableClasses(container: any = null, path: string = ""): {[index: string]: typeof Serializable} {
|
||||
if (container) {
|
||||
var result: {[index: string]: typeof Serializable} = {};
|
||||
for (var obj_name in container) {
|
||||
if (obj_name) {
|
||||
if (container.hasOwnProperty(obj_name)) {
|
||||
var obj = container[obj_name];
|
||||
var obj_path = path + "." + obj_name;
|
||||
if (typeof obj === "object") {
|
||||
|
@ -23,10 +24,11 @@ module SpaceTac.Game {
|
|||
}
|
||||
}
|
||||
|
||||
// Get the full path in SpaceTac namespace, of a serializable object
|
||||
getClassPath(obj: Serializable): string {
|
||||
var classes = this.collectSerializableClasses();
|
||||
for (var class_path in classes) {
|
||||
if (class_path) {
|
||||
if (classes.hasOwnProperty(class_path)) {
|
||||
var class_obj = classes[class_path];
|
||||
if (class_obj.prototype === obj.constructor.prototype) {
|
||||
return class_path;
|
||||
|
@ -36,19 +38,52 @@ module SpaceTac.Game {
|
|||
return null;
|
||||
}
|
||||
|
||||
// Serialize an object to a string
|
||||
serialize(obj: Serializable): string {
|
||||
var data = {
|
||||
path: this.getClassPath(obj),
|
||||
fields: obj
|
||||
};
|
||||
var data = this.toData(obj);
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
// Load an object from a serialized string
|
||||
unserialize(sdata: string): Serializable {
|
||||
var data = JSON.parse(sdata);
|
||||
var result = this.fromData(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
private toData(obj: Serializable): any {
|
||||
var fields = {};
|
||||
for (var field_name in obj) {
|
||||
if (obj.hasOwnProperty(field_name)) {
|
||||
var field_value = obj[field_name];
|
||||
if (field_value instanceof Serializable) {
|
||||
fields[field_name] = this.toData(field_value);
|
||||
} else {
|
||||
fields[field_name] = field_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var data = {
|
||||
path: this.getClassPath(obj),
|
||||
fields: fields
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
private fromData(data: any): Serializable {
|
||||
var class_info = this.collectSerializableClasses()[data.path];
|
||||
var obj = Object.create(class_info.prototype);
|
||||
obj = Tools.merge(obj, data.fields);
|
||||
for (var field_name in data.fields) {
|
||||
if (data.fields.hasOwnProperty(field_name)) {
|
||||
var field_value = data.fields[field_name];
|
||||
if (typeof field_value === "object" && field_value.hasOwnProperty("path")) {
|
||||
obj[field_name] = this.fromData(field_value);
|
||||
} else {
|
||||
obj[field_name] = field_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,5 +55,15 @@ module SpaceTac.Game.Specs {
|
|||
expect(loaded).toEqual(obj);
|
||||
expect((<SerializableTestObj2>loaded).prepend("this is ")).toEqual("this is a string");
|
||||
});
|
||||
|
||||
it("serializes and deserializes nested typescript objects", () => {
|
||||
var serializer = new Serializer();
|
||||
var obj = new SerializableTestObj1(8, new SerializableTestObj2("test"));
|
||||
var dumped = serializer.serialize(obj);
|
||||
var loaded = serializer.unserialize(dumped);
|
||||
|
||||
expect(loaded).toEqual(obj);
|
||||
expect((<SerializableTestObj1>loaded).b.prepend("this is a ")).toEqual("this is a test");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue