Added initial work for game data serialization
This commit is contained in:
parent
8c85102ccc
commit
508f2e3f94
|
@ -1,8 +1,10 @@
|
||||||
|
/// <reference path="Serializable.ts"/>
|
||||||
|
|
||||||
module SpaceTac.Game {
|
module SpaceTac.Game {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Template used to generate a loot equipment
|
// Template used to generate a loot equipment
|
||||||
export class LootTemplate {
|
export class LootTemplate extends Serializable {
|
||||||
// Type of slot this equipment will fit in
|
// Type of slot this equipment will fit in
|
||||||
slot: SlotType;
|
slot: SlotType;
|
||||||
|
|
||||||
|
@ -35,6 +37,7 @@ module SpaceTac.Game {
|
||||||
|
|
||||||
// Create a loot template
|
// Create a loot template
|
||||||
constructor(slot: SlotType, name: string) {
|
constructor(slot: SlotType, name: string) {
|
||||||
|
super();
|
||||||
this.slot = slot;
|
this.slot = slot;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.requirements = [];
|
this.requirements = [];
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
/// <reference path="Serializable.ts"/>
|
||||||
|
|
||||||
module SpaceTac.Game {
|
module SpaceTac.Game {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Range of number values
|
// Range of number values
|
||||||
export class Range {
|
export class Range extends Serializable {
|
||||||
// Minimal value
|
// Minimal value
|
||||||
min: number;
|
min: number;
|
||||||
|
|
||||||
|
@ -11,6 +13,7 @@ module SpaceTac.Game {
|
||||||
|
|
||||||
// Create a range of values
|
// Create a range of values
|
||||||
constructor(min: number, max: number = null) {
|
constructor(min: number, max: number = null) {
|
||||||
|
super();
|
||||||
this.set(min, max);
|
this.set(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
src/scripts/game/Serializable.ts
Normal file
7
src/scripts/game/Serializable.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
module SpaceTac.Game {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Base class for serializable objects
|
||||||
|
export class Serializable {
|
||||||
|
}
|
||||||
|
}
|
55
src/scripts/game/Serializer.ts
Normal file
55
src/scripts/game/Serializer.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,5 +16,16 @@ module SpaceTac.Game {
|
||||||
|
|
||||||
return objectCopy;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
src/scripts/game/specs/Serializer.spec.ts
Normal file
59
src/scripts/game/specs/Serializer.spec.ts
Normal 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");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -28,5 +28,11 @@ module SpaceTac.Game.Specs {
|
||||||
|
|
||||||
expect(cop.get()).toEqual("test");
|
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});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue