Index: binaries/data/mods/public/simulation/components/GuiInterface.js =================================================================== --- binaries/data/mods/public/simulation/components/GuiInterface.js +++ binaries/data/mods/public/simulation/components/GuiInterface.js @@ -511,7 +511,7 @@ let cmpResourceTrickle = Engine.QueryInterface(ent, IID_ResourceTrickle); if (cmpResourceTrickle) ret.resourceTrickle = { - "interval": cmpResourceTrickle.GetTimer(), + "interval": cmpResourceTrickle.GetInterval(), "rates": cmpResourceTrickle.GetRates() }; Index: binaries/data/mods/public/simulation/components/ResourceTrickle.js =================================================================== --- binaries/data/mods/public/simulation/components/ResourceTrickle.js +++ binaries/data/mods/public/simulation/components/ResourceTrickle.js @@ -11,12 +11,13 @@ ResourceTrickle.prototype.Init = function() { + this.trickleInterval = +this.template.Interval; this.CheckTimer(); }; -ResourceTrickle.prototype.GetTimer = function() +ResourceTrickle.prototype.GetInterval = function() { - return +this.template.Interval; + return this.trickleInterval; }; ResourceTrickle.prototype.GetRates = function() @@ -64,23 +65,43 @@ ResourceTrickle.prototype.CheckTimer = function() { + let cmpTimer; if (!this.ComputeRates()) { - if (this.timer) - { - let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); - cmpTimer.CancelTimer(this.timer); - delete this.timer; - } + if (!this.timer) + return; + + cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + cmpTimer.CancelTimer(this.timer); + delete this.timer; return; } - if (this.timer) + let oldTrickleInterval = this.trickleInterval || 0; + this.trickleInterval = ApplyValueModificationsToEntity("ResourceTrickle/Interval", +this.template.Interval, this.entity); + if (this.trickleInterval < 0) + { + cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + cmpTimer.CancelTimer(this.timer); + delete this.timer; return; + } + + if (this.timer) + { + if (this.trickleInterval == oldTrickleInterval) + return; + + if(oldTrickleInterval > 0) + { + cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + cmpTimer.UpdateRepeatTime(this.timer, this.trickleInterval); + return; + } + } - let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); - let interval = +this.template.Interval; - this.timer = cmpTimer.SetInterval(this.entity, IID_ResourceTrickle, "Trickle", interval, interval, undefined); + cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + this.timer = cmpTimer.SetInterval(this.entity, IID_ResourceTrickle, "Trickle", this.trickleInterval, this.trickleInterval, undefined); }; Engine.RegisterComponentType(IID_ResourceTrickle, "ResourceTrickle", ResourceTrickle); Index: binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js +++ binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js @@ -560,7 +560,7 @@ }); AddMock(10, IID_ResourceTrickle, { - "GetTimer": () => 1250, + "GetInterval": () => 1250, "GetRates": () => ({ "food": 2, "wood": 3, "stone": 5, "metal": 9 }) }); Index: binaries/data/mods/public/simulation/components/tests/test_ResourceTrickle.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_ResourceTrickle.js +++ binaries/data/mods/public/simulation/components/tests/test_ResourceTrickle.js @@ -56,7 +56,7 @@ let QueryOwnerInterface = () => cmpPlayer; Engine.RegisterGlobal("QueryOwnerInterface", QueryOwnerInterface); TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 300, "metal": 300 }); -TS_ASSERT_EQUALS(cmpResourceTrickle.GetTimer(), 200); +TS_ASSERT_EQUALS(cmpResourceTrickle.GetInterval(), 200); // Since there is no rate > 0, nothing should change. TS_ASSERT_UNEVAL_EQUALS(cmpResourceTrickle.GetRates(), {}); @@ -88,3 +88,90 @@ cmpTimer.OnUpdate({ "turnLength": turnLength }); TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 301, "metal": 300 }); +ApplyValueModificationsToEntity = (valueName, currentValue, entity) => { + if (valueName == "ResourceTrickle/Interval") + return currentValue + 200; + if (valueName == "ResourceTrickle/Rates/food") + return currentValue + 1; + + return currentValue; +}; +Engine.RegisterGlobal("ApplyValueModificationsToEntity", ApplyValueModificationsToEntity); +cmpResourceTrickle.OnValueModification({ "component": "ResourceTrickle" }); +TS_ASSERT_EQUALS(cmpResourceTrickle.GetInterval(), 400); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 301, "metal": 300 }); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 302, "metal": 300 }); + +// Interval becomes a normal timer, thus cancelled after the first execution. +ApplyValueModificationsToEntity = (valueName, currentValue, entity) => { + if (valueName == "ResourceTrickle/Interval") + return currentValue - 200; + if (valueName == "ResourceTrickle/Rates/food") + return currentValue + 1; + + return currentValue; +}; +Engine.RegisterGlobal("ApplyValueModificationsToEntity", ApplyValueModificationsToEntity); +cmpResourceTrickle.OnValueModification({ "component": "ResourceTrickle" }); +TS_ASSERT_EQUALS(cmpResourceTrickle.GetInterval(), 0); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 302, "metal": 300 }); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 303, "metal": 300 }); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 303, "metal": 300 }); + +// Timer became invalidated, check whether it's recreated properly after that. +ApplyValueModificationsToEntity = (valueName, currentValue, entity) => { + if (valueName == "ResourceTrickle/Interval") + return currentValue - 100; + if (valueName == "ResourceTrickle/Rates/food") + return currentValue + 1; + + return currentValue; +}; +Engine.RegisterGlobal("ApplyValueModificationsToEntity", ApplyValueModificationsToEntity); +cmpResourceTrickle.OnValueModification({ "component": "ResourceTrickle" }); +TS_ASSERT_EQUALS(cmpResourceTrickle.GetInterval(), 100); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 305, "metal": 300 }); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 307, "metal": 300 }); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 309, "metal": 300 }); + +// Value is now invalid, timer should be cancelled. +ApplyValueModificationsToEntity = (valueName, currentValue, entity) => { + if (valueName == "ResourceTrickle/Interval") + return currentValue - 201; + if (valueName == "ResourceTrickle/Rates/food") + return currentValue + 1; + + return currentValue; +}; +Engine.RegisterGlobal("ApplyValueModificationsToEntity", ApplyValueModificationsToEntity); +cmpResourceTrickle.OnValueModification({ "component": "ResourceTrickle" }); +TS_ASSERT_EQUALS(cmpResourceTrickle.GetInterval(), -1); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 309, "metal": 300 }); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 309, "metal": 300 }); + +// Timer became invalidated, check whether it's recreated properly after that. +ApplyValueModificationsToEntity = (valueName, currentValue, entity) => { + if (valueName == "ResourceTrickle/Rates/food") + return currentValue + 1; + + return currentValue; +}; +Engine.RegisterGlobal("ApplyValueModificationsToEntity", ApplyValueModificationsToEntity); +cmpResourceTrickle.OnValueModification({ "component": "ResourceTrickle" }); +TS_ASSERT_EQUALS(cmpResourceTrickle.GetInterval(), 200); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 310, "metal": 300 }); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 311, "metal": 300 }); +cmpTimer.OnUpdate({ "turnLength": turnLength }); +TS_ASSERT_UNEVAL_EQUALS(cmpPlayer.GetResourceCounts(), { "food": 312, "metal": 300 });