Created
April 30, 2019 04:40
-
-
Save joeytwiddle/cb649dc34bc7a1bbddc6171cb29709cd to your computer and use it in GitHub Desktop.
Cooldown Monitor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
/* | |
Simulates an object which can heat up and overheat, but with a constant rate of cooling over time. | |
Useful for throttling when you want to provide an initial allowance. | |
For example, it could be used to manage the overheating of a weapon in a game, or to avoid errors from generating huge logfiles, but without throttling the first few errors. | |
*/ | |
const defaultOptions = { | |
// Initial allowance before overheating occurs | |
maxTemp: 5, | |
// Optional cooling rate, provide just one (the defaults shown will cool by 1 temperature unit per second) | |
//cooldownPerSecond: 1/60, | |
//cooldownPerMinute: 1, | |
//cooldownPerHour: 60, | |
}; | |
/* | |
Example usage: | |
// Allow 10 actions, but after that only allow 2 actions per minute | |
const cooldownMonitor = new CooldownMonitor({maxTemp: 10, cooldownPerMinute: 2}); | |
// ... | |
if (cooldownMonitor.isOverheated()) { | |
// do nothing | |
} else { | |
cooldownMonitor.warm(1); | |
doSomeAction(); | |
} | |
Notes: | |
With a cooldownPerMinute of 10, you may sometimes see more than 10 actions in one minute, due to the initial allowance (maxTemp). | |
*/ | |
const CooldownMonitor = function (_opts) { | |
const opts = Object.assign({}, defaultOptions, _opts); | |
let lastCheckTime = Date.now(); | |
let currentTemperature = 0; | |
//noinspection JSUnresolvedVariable | |
const coolingRatePerMs = opts.cooldownPerSecond ? opts.cooldownPerSecond / 1000 | |
: opts.cooldownPerMinute ? opts.cooldownPerMinute / 60 / 1000 | |
: opts.cooldownPerHour ? opts.cooldownPerHour / 60 / 60 / 1000 | |
: 1000; | |
// Check for valid value (not NaN) | |
if (coolingRatePerMs >= 0) { | |
// ok | |
} else { | |
throw Error("Something is wrong with the cooldown rate: " + coolingRatePerMs); | |
} | |
function doUncountedCooling () { | |
const currentTime = Date.now(); | |
const timeSinceLastCheck = currentTime - lastCheckTime; | |
const coolingAmount = coolingRatePerMs * timeSinceLastCheck; | |
currentTemperature -= coolingAmount; | |
if (currentTemperature < 0) { | |
currentTemperature = 0; | |
} | |
lastCheckTime = currentTime; | |
} | |
return { | |
/** | |
* @param [amount] - number of degrees to increase temperature by, defaults to 1 | |
*/ | |
warm: (amount) => { | |
if (amount == null) { | |
amount = 1; | |
} | |
doUncountedCooling(); | |
currentTemperature += amount; | |
}, | |
isOverheated: () => { | |
doUncountedCooling(); | |
return currentTemperature > opts.maxTemp; | |
}, | |
getTemperature: () => { | |
doUncountedCooling(); | |
return currentTemperature; | |
}, | |
}; | |
}; | |
module.exports = CooldownMonitor; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment