Index: ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js +++ ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js @@ -9,14 +9,11 @@ /** * This object represents an item in the queue. - */ -ProductionQueue.prototype.Item = function() {}; - -/** + * * @param {number} producer - The entity ID of our producer. * @param {string} metadata - Optionally any metadata attached to us. */ -ProductionQueue.prototype.Item.prototype.Init = function(producer, metadata) +ProductionQueue.prototype.Item = function(producer, metadata) { this.producer = producer; this.metadata = metadata; @@ -192,30 +189,31 @@ return this.originalItem; }; +ProductionQueue.prototype.Item.prototype.SerializableAttributes = [ + "entity", + "id", + "metadata", + "originalItem", + "paused", + "producer", + "started", + "technology" +]; + ProductionQueue.prototype.Item.prototype.Serialize = function() { - return { - "id": this.id, - "metadata": this.metadata, - "paused": this.paused, - "producer": this.producer, - "entity": this.entity, - "technology": this.technology, - "started": this.started, - "originalItem": this.originalItem - }; + const result = {}; + for (const att of this.SerializableAttributes) + if (this.hasOwnProperty(att)) + result[att] = this[att]; + return result; }; ProductionQueue.prototype.Item.prototype.Deserialize = function(data) { - this.Init(data.producer, data.metadata); - - this.id = data.id; - this.paused = data.paused; - this.entity = data.entity; - this.technology = data.technology; - this.started = data.started; - this.originalItem = data.originalItem; + for (const att of this.SerializableAttributes) + if (att in data) + this[att] = data[att]; }; ProductionQueue.prototype.Init = function() @@ -224,29 +222,35 @@ this.queue = []; }; +ProductionQueue.prototype.SerializableAttributes = [ + "autoqueuing", + "nextID", + "paused", + "timer" +]; + ProductionQueue.prototype.Serialize = function() { - const queue = []; + const result = { + "queue": [] + }; for (const item of this.queue) - queue.push(item.Serialize()); + result.queue.push(item.Serialize()); - return { - "autoqueuing": this.autoqueuing, - "nextID": this.nextID, - "paused": this.paused, - "timer": this.timer, - "queue": queue - }; + for (const att of this.SerializableAttributes) + if (this.hasOwnProperty(att)) + result[att] = this[att]; + + return result; }; ProductionQueue.prototype.Deserialize = function(data) { - this.Init(); + for (const att of this.SerializableAttributes) + if (att in data) + this[att] = data[att]; - this.autoqueuing = data.autoqueuing; - this.nextID = data.nextID; - this.paused = data.paused; - this.timer = data.timer; + this.queue = []; for (const item of data.queue) { @@ -328,8 +332,7 @@ return false; } - const item = new this.Item(); - item.Init(this.entity, metadata); + const item = new this.Item(this.entity, metadata); if (!item.Queue(type, templateName, count)) return false; Index: ps/trunk/binaries/data/mods/public/simulation/components/Researcher.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Researcher.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Researcher.js @@ -175,8 +175,8 @@ Researcher.prototype.Item.prototype.Deserialize = function(data) { - for (const att in data) - if (this.SerializableAttributes.includes(att)) + for (const att of this.SerializableAttributes) + if (att in data) this[att] = data[att]; }; Index: ps/trunk/binaries/data/mods/public/simulation/components/Trainer.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Trainer.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Trainer.js @@ -401,8 +401,8 @@ Trainer.prototype.Item.prototype.Deserialize = function(data) { - for (const att in data) - if (this.SerializableAttributes.includes(att)) + for (const att of this.SerializableAttributes) + if (att in data) this[att] = data[att]; }; Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/setup.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/setup.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/setup.js @@ -100,6 +100,12 @@ "configurable": false, "enumerable": false, "writable": false + }, + "_cmpName": { + "value": name, + "configurable": false, + "enumerable": false, + "writable": false } }); @@ -135,3 +141,26 @@ return this; }; + +global.SerializationCycle = function(cmp) +{ + let data; + if (typeof cmp.Serialize === "function") + data = cmp.Serialize(); + else + { + data = {}; + for (const att of cmp) + if (cmp.hasOwnProperty(att)) + data[att] = cmp[att]; + } + + const newCmp = ConstructComponent(cmp.entity, cmp._cmpName, cmp.template); + if (typeof newCmp.Deserialize === "function") + newCmp.Deserialize(data); + else + for (const att in data) + newCmp[att] = data[att]; + + return newCmp; +}; Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js @@ -81,3 +81,11 @@ cmpProdQueue.ProgressTimeout(null, 0); TS_ASSERT_EQUALS(cmpProdQueue.GetQueue().length, 0); + + +// Simple deserialisation test. +cmpProdQueue.AddItem("some_template", "unit", 2); +const deserialisedCmp = SerializationCycle(cmpProdQueue); +TS_ASSERT_EQUALS(deserialisedCmp.GetQueue().length, 1); +deserialisedCmp.ProgressTimeout(null, 0); +TS_ASSERT_EQUALS(deserialisedCmp.GetQueue().length, 0); Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Researcher.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Researcher.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Researcher.js @@ -40,7 +40,7 @@ "GetCiv": () => "iber" }); -const cmpResearcher = ConstructComponent(entityID, "Researcher", { +let cmpResearcher = ConstructComponent(entityID, "Researcher", { "Technologies": { "_string": "gather_fishing_net " + "phase_town_{civ} " + "phase_city_{civ}" } @@ -147,6 +147,8 @@ TS_ASSERT_EQUALS(cmpResearcher.Progress(id, 500), 500); TS_ASSERT_EQUALS(cmpResearcher.GetResearchingTechnology(id).progress, 0.5); +cmpResearcher = SerializationCycle(cmpResearcher); + spyTechManager = new Spy(techManager, "ResearchTechnology"); TS_ASSERT_EQUALS(cmpResearcher.Progress(id, 1000), 500); TS_ASSERT_EQUALS(spyTechManager._called, 1); Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Trainer.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Trainer.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Trainer.js @@ -26,7 +26,7 @@ "GetTemplate": name => ({}) }); -const cmpTrainer = ConstructComponent(entityID, "Trainer", { +let cmpTrainer = ConstructComponent(entityID, "Trainer", { "Entities": { "_string": "units/{civ}/cavalry_javelineer_b " + "units/{civ}/infantry_swordsman_b " + "units/{native}/support_female_citizen" } @@ -246,6 +246,8 @@ "PickSpawnPoint": () => ({ "x": 0, "y": 1, "z": 0 }) }); +cmpTrainer = SerializationCycle(cmpTrainer); + TS_ASSERT_EQUALS(cmpTrainer.Progress(id, 1000), 500); TS_ASSERT(!cmpTrainer.HasBatch(id)); TS_ASSERT(!cmpEntLimits.AllowedToTrain("some_limit", 5)); @@ -268,6 +270,8 @@ TS_ASSERT_EQUALS(cmpEntLimits.GetCounts().some_limit, 3); TS_ASSERT_EQUALS(cmpEntLimits.GetMatchCounts()["units/iber/infantry_swordsman_b"], 3); +cmpTrainer = SerializationCycle(cmpTrainer); + // Check that when the batch is removed the counts are subtracted again. cmpTrainer.StopBatch(id); TS_ASSERT_EQUALS(cmpEntLimits.GetCounts().some_limit, 1);