Scripter Javascript Tutorial
javascriptmusiclogicscripterbookexcerpttutorial90 Using Functions For Long or Complicated Code
In the following example, the code is very easy to read, but lines 19–20 are challenging to read. Sometimes that’s just the way code works out, and that it’s painful to read compared to the rest of the code is actually a good thing because it means the rest of the code is well-developed.
var NeedsTimingInfo = true;
var activeNotes = [];
var lastBlockStart;
function HandleMIDI( event ) {
if ( event instanceof NoteOn ) {
.push( event );
activeNoteselse if ( event instanceof NoteOff ) {
} // remove the note from activeNotes
}
}
function ProcessMIDI() {
var timingInfo = GetTimingInfo();
if ( timingInfo.playing ) {
var currBlockStart = Math.floor(timingInfo.blockStartBeat);
if ( currBlockStart != lastBlockStart \&\&
<= 1 || currBlockStart \% timingInfo.meterNumerator == 0 ) ) {
( currBlockStart Trace(lastBlockStart + " - " + currBlockStart)
} }
For large or complicated test or code blocks, a function can be used to manage readability:
function ProcessMIDI() {
// get the current position of the cursor and project play state
var timingInfo = GetTimingInfo();
if ( timingInfo.playing ) {
var currBlockStart = Math.floor( timingInfo.blockStartBeat );
if ( inNewBar( timingInfo ) ) {
Trace( lastBlockStart + " - " + currBlockStart )
}
}
function inNewBar( timingInfo ) {
if ( currBlockStart != lastBlockStart \&\&
<= 1 ||
( currBlockStart % timingInfo.meterNumerator == 0 )
currBlockStart \
) {return true;
}return false;
}
The structure of the big Bar test has not changed, and it won’t
change unless Apple decides to change the TimingInfo
object’s structure or how timing information is specified. So, the
calculation is put into its own function which makes the actual use of
it as simple as a single function call and not multiple comparisons. Any
context needed to work on that part of the code is already provided by
the name of the function and the fact that timingInfo
is
passed into it.