Last active
June 2, 2021 08:29
-
-
Save ElectricImpSampleCode/c9d61d17c969510dd2f64b036413b579 to your computer and use it in GitHub Desktop.
imp API Cookbook recipe: repeating timers
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
class Timer { | |
static version = "1.0.0"; | |
/* | |
* Private Properties | |
*/ | |
_repeat = true; | |
_period = 0; | |
_timer = null; | |
_cb = null; | |
/* | |
* @constructor | |
* | |
* @param {Integer|Float} period - The period before the timer fires | |
* @param {Bool} repeat - Should the timer repeat. Default: true | |
* @param {Function} callback - The function to be called when the timer fires | |
* | |
*/ | |
constructor(period, repeat = true, callback = null) { | |
if (!(typeof period == "integer" || typeof period == "float")) | |
throw "Timer period must be an integer or float"; | |
if (typeof repeat != "bool") | |
throw "Timer repeat must be true or false"; | |
if (typeof callback != "function" || callback == null) | |
throw "Timer callback must be a function"; | |
_period = period; | |
_repeat = repeat; | |
_cb = callback; | |
_timer = imp.wakeup(_period, _firee.bindenv(this)); | |
} | |
/* | |
* Call the timer's target immediately. | |
* | |
* This does not affect the timer, which will fire after the set period | |
* | |
*/ | |
function fire() { | |
if (_cb != null) imp.wakeup(0, _cb); | |
if (!_repeat) invalidate(); | |
} | |
/* | |
* Invalidate the timer immediately. | |
* | |
* If the timer has not yet fired when this is called, it will not do so | |
* | |
*/ | |
function invalidate() { | |
if (_timer != null) { | |
imp.cancelwakeup(_timer); | |
_timer, _cb = null; | |
} | |
} | |
/* | |
* Indicates whether the timer is valid. | |
* | |
* A valid timer is one that has been set and, if it is non-repeating, has | |
* not yet fired. Repeating timers remain valid. | |
* | |
* @returns {Bool} whether the timer is valid (true) or not (false) | |
* | |
*/ | |
function isValid() { | |
return (_timer != null); | |
} | |
/* | |
* Internal timer fire handler | |
* | |
* @private | |
* | |
*/ | |
function _firee() { | |
// The timer has fired: trigger the callback | |
fire(); | |
// Re-schedule or invalidate the timer | |
if (_repeat) { | |
_timer = imp.wakeup(_period, _firee.bindenv(this)); | |
} else { | |
_timer, _cb = null; | |
} | |
} | |
} |
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
// Early-run code | |
server.setsendtimeoutpolicy(RETURN_ON_ERROR, WAIT_TIL_SENT, 10); | |
/* | |
* Include the Timer class here | |
*/ | |
// Set an LED on pin M (imp003 and up) | |
hardware.pinM.configure(DIGITAL_OUT, 0); | |
// Record LED state | |
state <- true; | |
// Instantiate a repeating (true) timer that will fire in 10 seconds, | |
// and then every subsequent 10 seconds, to call the inline function, | |
// which flips the LED state | |
timer <- Timer(10, true, function() { | |
hardware.pinM.write(state ? 1 : 0); | |
state = !state | |
}); | |
// Cause the timer to fire prematurely after 15 seconds | |
imp.wakeup(15, function() { | |
if (timer.isValid()) timer.fire(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment