-
Notifications
You must be signed in to change notification settings - Fork 14
Module wrap with setInterval
The default unpacking routine extracts the code to a string, then runs it with eval()
.
This module addresses demos using setInterval()
to trigger their main animation loop. It refactors the code to have the unpacked string executed with that same setInterval()
, so that eval()
is not necessary.
Any initialization code originally executed before the main loop is pushed to a conditional statement inside the loop so it is run on the first occurrence.
It requires a variable representing time, which is initialized to 0 at the beginning, then modified within the loop. The initialization block is only executed if the time is zero.
// Initialization code (executed only once)
var time = 0;
...
// end initialization code
setInterval( function() {
// main loop
...
time += timeStep;
}, delay);
becomes
if (!time) {
// Initialization code (executed only once)
...
// end initialization code
}
// main loop
...
time += timeStep;
which is then packed, and the result is evaluated with setInterval("packed code", delay)
Warning : this module may cause a performance hit, since the unpacked code is evaluated at each loop, instead of once as with eval()
.
The initialization block and loop contents are identified and split. Code present after the loop is considered part of the initialization block and appended to it. If no loop is found, or the delay is not a number, the module exits leaving the input data unchanged.
Any variables declared as parameters of the function()
executed at each tick are ignored; however any variable assignment is kept and prepended to the initialization block.
If a time variable is provided, its declaration is stripped from the initialization code, according to the exact syntax used :
time=0;
is removed altogether.
time=a=b=0;
and a=b=time=0
both become a=b=0
.
a[time=0]
becomes a[0]
.
If no time variable is provided, the module chooses an unused name through the method allocateNewVariable()
, reusing a principle from the module Rename Variables.
Any character used in a built-in keyword or function name, yet with no one-letter variable by this name, is picked first[
If there is none, any allowed character not already used as a variable is selected. Barring this, the first available two-letter combination is kept.
To account for the fact that the time variable is not incremented by the original code, the conditional statement is modified to read if(!time++)
instead of if(!time)
so it does not execute on subsequent loops.
The initialization block - if any, see #72 - is then wrapped into the conditional statement, and the main loop is appended afterwards.
Adaptation of the unpacking routine is stored into the PackerData. This features the use of setInterval(code, delay)
instead of eval(code)
and the initial assignment of the time variable.
Other modules run afterwards - such as the one hashing context methods - can add instructions at the beginning of the code. Since these instructions should be executed only once, they need to be inserted at the beginning of the conditional statement instead. The appropriate offset is stored in the PackerData to be reused by these modules.
From RegPack v5.0 on, the module recognizes ES6 syntaxes for function declaration :
-
Arrow functions :
()=>{ /* main loop */ }
ort=>{ /* main loop */ }
(see #44) -
Default parameters :
function(x,y=0,z=1){ /* main loop */}
(see #56) - Both combined :
(x,y=0,z=1)=>{ /* main loop */}
Support for these is active even though the parameter useES6
is set to false
.
Parameter name | Type | Default | Effect |
---|---|---|---|
wrapInSetInterval |
boolean | false |
enable or disable the module |
timeVariableName |
String | "" |
name of the variable representing time |
If the variable name is empty, the module will create a new variable instead.
The module is implemented by the method Shapeshifter.refactorToSetInterval()
.
It uses a PackerData
as both input and output. If the refactoring is successful, the data is modified to match. Otherwise it is left unaltered.