1
0
Fork 0

Added initial work for game data serialization

This commit is contained in:
Michaël Lemaire 2015-03-02 01:00:00 +01:00
parent 8c85102ccc
commit 508f2e3f94
7 changed files with 146 additions and 2 deletions

View file

@ -1,8 +1,10 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// Template used to generate a loot equipment
export class LootTemplate {
export class LootTemplate extends Serializable {
// Type of slot this equipment will fit in
slot: SlotType;
@ -35,6 +37,7 @@ module SpaceTac.Game {
// Create a loot template
constructor(slot: SlotType, name: string) {
super();
this.slot = slot;
this.name = name;
this.requirements = [];

View file

@ -1,8 +1,10 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// Range of number values
export class Range {
export class Range extends Serializable {
// Minimal value
min: number;
@ -11,6 +13,7 @@ module SpaceTac.Game {
// Create a range of values
constructor(min: number, max: number = null) {
super();
this.set(min, max);
}

View file

@ -0,0 +1,7 @@
module SpaceTac.Game {
"use strict";
// Base class for serializable objects
export class Serializable {
}
}

View file

@ -0,0 +1,55 @@
module SpaceTac.Game {
"use strict";
// Serializer to cascade through Serializable objects
export class Serializer {
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) {
var obj = container[obj_name];
var obj_path = path + "." + obj_name;
if (typeof obj === "object") {
result = Tools.merge(result, this.collectSerializableClasses(obj, obj_path));
} else if (typeof obj === "function" && obj.prototype instanceof Serializable) {
result[obj_path] = obj;
}
}
}
return result;
} else {
return this.collectSerializableClasses(SpaceTac.Game, "SpaceTac.Game");
}
}
getClassPath(obj: Serializable): string {
var classes = this.collectSerializableClasses();
for (var class_path in classes) {
if (class_path) {
var class_obj = classes[class_path];
if (class_obj.prototype === obj.constructor.prototype) {
return class_path;
}
}
}
return null;
}
serialize(obj: Serializable): string {
var data = {
path: this.getClassPath(obj),
fields: obj
};
return JSON.stringify(data);
}
unserialize(sdata: string): Serializable {
var data = JSON.parse(sdata);
var class_info = this.collectSerializableClasses()[data.path];
var obj = Object.create(class_info.prototype);
obj = Tools.merge(obj, data.fields);
return obj;
}
}
}

View file

@ -16,5 +16,16 @@ module SpaceTac.Game {
return objectCopy;
}
// Merge an object into another
static merge(base: any, incoming: any): any {
var result = Tools.copyObject(base);
for (var obj_name in incoming) {
if (obj_name) {
result[obj_name] = incoming[obj_name];
}
}
return result;
}
}
}

View file

@ -0,0 +1,59 @@
/// <reference path="../../definitions/jasmine.d.ts"/>
/// <reference path="../Serializable.ts"/>
module SpaceTac.Game.Specs {
"use strict";
export class SerializableTestObj2 extends Serializable {
a: string;
constructor(a: string = "test") {
super();
this.a = a;
}
prepend(prefix: string): string {
return prefix + this.a;
}
}
export class SerializableTestObj1 extends Serializable {
a: number;
b: SerializableTestObj2;
constructor(a: number = 5, b: SerializableTestObj2 = null) {
super();
this.a = a;
this.b = b;
}
}
describe("Serializer", () => {
it("collects serializable classes", () => {
var serializer = new Serializer();
var classes = serializer.collectSerializableClasses();
expect(classes["SpaceTac.Game.Specs.SerializableTestObj1"]).toBe(SerializableTestObj1);
expect(classes["SpaceTac.Game.Specs.SerializableTestObj2"]).toBe(SerializableTestObj2);
expect(classes["SpaceTac.Game.Range"]).toBe(Range);
expect(classes["SpaceTac.Game.Equipments.GatlingGun"]).toBe(Equipments.GatlingGun);
});
it("gets an object's full path in namespace", () => {
var serializer = new Serializer();
expect(serializer.getClassPath(new SerializableTestObj1())).toBe("SpaceTac.Game.Specs.SerializableTestObj1");
});
it("serializes and deserializes simple typescript objects", () => {
var serializer = new Serializer();
var obj = new SerializableTestObj2("a string");
var dumped = serializer.serialize(obj);
var loaded = serializer.unserialize(dumped);
expect(loaded).toEqual(obj);
expect((<SerializableTestObj2>loaded).prepend("this is ")).toEqual("this is a string");
});
});
}

View file

@ -28,5 +28,11 @@ module SpaceTac.Game.Specs {
expect(cop.get()).toEqual("test");
});
it("merges objects", () => {
expect(Tools.merge({}, {})).toEqual({});
expect(Tools.merge({"a": 1}, {"b": 2})).toEqual({"a": 1, "b": 2});
expect(Tools.merge({"a": 1}, {"a": 3, "b": 2})).toEqual({"a": 3, "b": 2});
});
});
}