Script Processor: "not a function" error is intermittent/non-deterministic (4.1.0)
-
I am using HISE 4.1.0, Windows standalone. Please see below my case:
getGlobalVariable turned out to need array syntax (getGlobalVariable[i]), not function-call syntax (getGlobalVariable(i)) — that part makes sense once found.
The real issue: the compiler is intermittent. The exact same, unmodified line sometimes compiles fine and sometimes throws "This expression is not a function!" — I've seen this happen even to setGlobalVariable(...) calls (which are correctly function-style). Recompiling with no code change sometimes clears the error, sometimes doesn't. It's happened in a fresh, minimal project too (not just a long-edited one), so it doesn't seem to be project corruption.
Minimal repro that has failed intermittently for me:
function onNoteOn()
{
setGlobalVariable(2, 1);
setGlobalVariable(1, 0);
}in a Script Processor inside a Sampler's MIDI chain.
Is this a known issue with this build? Anything I should check (JUCE/compiler version, a setting, etc.) before assuming it's just flaky?
-
@musicayciencia First thing you should do is build HISE form the source.
Ignore the Releases section on GitHub - 4.1.0 is far too old to spend any time debugging it.
Follow the "How to Compile HISE" details further down the repo page.
-
@musicayciencia
setGlobalVariable()isn't a HISE function, or is it a function you created? Either way, you should avoid global variables if you can. -
@dannytaurus good to know about building from source for the long run. I'll keep that in mind if I keep pushing HISE's limits. Thanks
-
@David-Healey you nailed it, as setGlobalVariable/getGlobalVariable was indeed the wrong approach on my end. Switched to the Globals object as you suggested and the instability is gone. Compiles reliably now!
Marking this solved. Cheers!
-
@musicayciencia said in Script Processor: "not a function" error is intermittent/non-deterministic (4.1.0):
Switched to the Globals object as you suggested
I suggest you don't use globals at all
-
@David-Healey thanks. My mistake. Follow-up question then: without Globals, what's the correct way to share a persistent value (e.g. a MidiList, or just an int) between onInit(), onNoteOn() and onNoteOff() within the same Script Processor? I need to track "which notes are currently held" across those three callbacks. Is reg the right tool for this, or something else?
-
@musicayciencia For a MIDIList use a const, for an int use a reg. You should watch my scripting 101 video on YouTube.
-
@David-Healey will definitely check out your scripting 101 video and follow your channel. Clearly I've got some fundamentals to shore up. Thanks.
-
@musicayciencia globals are used when you need to share data between script processors - although David correctly suggests that this should be the last tool you pick for that as there are way better ways for cross-module communication by now. The callback of a single script processor share all the variables declared in the onInit callback.
Now about the non-deterministic issue: if you compile that script it won't cause an error, as the JS compiler cannot know whether the variable
setGlobalVariableis a function that can be called - it might get assigned to something callable at some point so it stays put and doesn't complain. However when you play a note, then it's time to call this variable and that's where HISE realises that you can't execute the (empty) variable.var callableAtSecondTime = undefined; function onNoteOn() { callableAtSecondTime(); } function onNoteOff() { callableAtSecondTime = function() { Console.print("Now I work"); }; }This script will throw an error when you press the first note, but the first note off will then assign a function to the variable so subsequent notes will not raise the error but call the function. That example looks weird, but it's one of the more powerful features of JS (and HiseScript) to be able to reassign function slots to different functions like this so you can implement dynamic logic more easily.