Index: binaries/data/mods/public/simulation/components/ProductionQueue.js =================================================================== --- binaries/data/mods/public/simulation/components/ProductionQueue.js +++ binaries/data/mods/public/simulation/components/ProductionQueue.js @@ -1,4 +1,3 @@ -var g_ProgressInterval = 1000; const MAX_QUEUE_SIZE = 16; function ProductionQueue() {} @@ -34,6 +33,11 @@ Resources.BuildSchema("nonNegativeDecimal", ["time"]) + ""; +/** + * Interval of timer where the queue is updated. + */ +ProductionQueue.prototype.PROGRESS_INTERVAL = 1000; + ProductionQueue.prototype.Init = function() { this.nextID = 1; @@ -63,7 +67,7 @@ // "timeRemaining": 10000, // msecs // } - this.timer = undefined; // g_ProgressInterval msec timer, active while the queue is non-empty + this.timer = undefined; // PROGRESS_INTERVAL msec timer, active while the queue is non-empty this.paused = false; this.entityCache = []; @@ -356,8 +360,6 @@ // thing twice. var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager); cmpTechnologyManager.QueuedResearch(templateName, this.entity); - if (this.queue.length == 0) - cmpTechnologyManager.StartedResearch(templateName, false); this.queue.push({ "id": this.nextID++, @@ -382,12 +384,8 @@ Engine.PostMessage(this.entity, MT_ProductionQueueChanged, { }); - // If this is the first item in the queue, start the timer if (!this.timer) - { - var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); - this.timer = cmpTimer.SetTimeout(this.entity, IID_ProductionQueue, "ProgressTimeout", g_ProgressInterval, {}); - } + this.ProgressTimeout(); } else { @@ -538,16 +536,12 @@ this.CalculateEntitiesList(); }; +/** + * Reset the queue to refund any resources when destroyed. + */ ProductionQueue.prototype.OnDestroy = function() { - // Reset the queue to refund any resources this.ResetQueue(); - - if (this.timer) - { - var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); - cmpTimer.CancelTimer(this.timer); - } }; /* @@ -679,18 +673,20 @@ // Check if the production is paused (eg the entity is garrisoned) if (this.paused) return; - // Allocate the 1000msecs to as many queue items as it takes + + // Allocate the 1000msecs to as many queue items as it takes // until we've used up all the time (so that we work accurately // with items that take fractions of a second) - var time = g_ProgressInterval; + let time = this.PROGRESS_INTERVAL; + var cmpPlayer = QueryOwnerInterface(this.entity); - while (time > 0 && this.queue.length) + while (this.queue.length) { var item = this.queue[0]; if (!item.productionStarted) { - // If the item is a unit then do population checks + // If the item is an unit then do population checks. if (item.unitTemplate) { // If something change population cost @@ -712,9 +708,10 @@ // Unset flag that training is blocked cmpPlayer.UnBlockTraining(); + + Engine.PostMessage(this.entity, MT_TrainingStarted, { "entity": this.entity }); } - - if (item.technologyTemplate) + else if (item.technologyTemplate) { // Mark the research as started. var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager); @@ -722,17 +719,18 @@ } item.productionStarted = true; - if (item.unitTemplate) - Engine.PostMessage(this.entity, MT_TrainingStarted, { "entity": this.entity }); + + if (!this.timer) + break; } // If we won't finish the batch now, just update its timer if (item.timeRemaining > time) { item.timeRemaining -= time; - // send a message for the AIs. + // Send a message for the AIs. Engine.PostMessage(this.entity, MT_ProductionQueueChanged, { }); - break; + return; } if (item.unitTemplate) @@ -740,14 +738,11 @@ var numSpawned = this.SpawnUnits(item.unitTemplate, item.count, item.metadata); if (numSpawned == item.count) { - // All entities spawned, this batch finished + // All entities spawned, this batch finished. cmpPlayer.UnReservePopulationSlots(item.population * numSpawned); - time -= item.timeRemaining; - this.queue.shift(); - // Unset flag that training is blocked + // Unset flag that training is blocked. cmpPlayer.UnBlockTraining(); this.spawnNotified = false; - Engine.PostMessage(this.entity, MT_ProductionQueueChanged, { }); } else { @@ -771,7 +766,7 @@ cmpGUIInterface.PushNotification(notification); this.spawnNotified = true; } - break; + return; } } else if (item.technologyTemplate) @@ -788,43 +783,60 @@ if (cmpSoundManager) cmpSoundManager.PlaySoundGroup(template.soundComplete, this.entity); } + } - time -= item.timeRemaining; - - this.queue.shift(); - Engine.PostMessage(this.entity, MT_ProductionQueueChanged, { }); - } + // Directly process to the next item. + time -= item.timeRemaining; + this.queue.shift(); + Engine.PostMessage(this.entity, MT_ProductionQueueChanged, { }); } - // If the queue's empty, delete the timer, else repeat it + // Start the timer when its the first item added to production. + if (!this.timer) + this.StartTimer(); + + // If the queue's empty, delete the timer. if (this.queue.length == 0) { - this.timer = undefined; + this.StopTimer(); // Unset flag that training is blocked // (This might happen when the player unqueues all batches) cmpPlayer.UnBlockTraining(); } - else - { - var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); - this.timer = cmpTimer.SetTimeout(this.entity, IID_ProductionQueue, "ProgressTimeout", g_ProgressInterval, data); - } }; ProductionQueue.prototype.PauseProduction = function() { - this.timer = undefined; this.paused = true; + this.StopTimer(); }; ProductionQueue.prototype.UnpauseProduction = function() { this.paused = false; - var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); - this.timer = cmpTimer.SetTimeout(this.entity, IID_ProductionQueue, "ProgressTimeout", g_ProgressInterval, {}); + this.StartTimer(true); }; +ProductionQueue.prototype.StartTimer = function() +{ + if (this.timer || this.paused) + return; + + let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + this.timer = cmpTimer.SetInterval(this.entity, IID_ProductionQueue, "ProgressTimeout", this.PROGRESS_INTERVAL, this.PROGRESS_INTERVAL, {}); +}; + +ProductionQueue.prototype.StopTimer = function() +{ + if (!this.timer) + return; + + let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + cmpTimer.CancelTimer(this.timer); + this.timer = undefined; +}; + ProductionQueue.prototype.OnValueModification = function(msg) { // if the promotion requirements of units is changed,