|
|
@@ -98,6 +98,7 @@ struct Prototype : Module { |
|
|
|
ScriptEngine* scriptEngine = NULL; |
|
|
|
int frame = 0; |
|
|
|
int frameDivider; |
|
|
|
// This is dynamically allocated to have some protection against script bugs. |
|
|
|
ProcessBlock* block; |
|
|
|
int bufferIndex = 0; |
|
|
|
|
|
|
@@ -129,15 +130,28 @@ struct Prototype : Module { |
|
|
|
} |
|
|
|
|
|
|
|
void process(const ProcessArgs& args) override { |
|
|
|
// Load security-sandboxed script if the security warning message is accepted. |
|
|
|
if (securityScript != "" && securityAccepted) { |
|
|
|
setScript(securityScript); |
|
|
|
securityScript = ""; |
|
|
|
} |
|
|
|
|
|
|
|
// Frame divider for reducing sample rate |
|
|
|
if (++frame < frameDivider) |
|
|
|
return; |
|
|
|
frame = 0; |
|
|
|
|
|
|
|
// Load security-sandboxed script if the security warning message is accepted. |
|
|
|
if (securityScript != "" && securityAccepted) { |
|
|
|
setScript(securityScript); |
|
|
|
securityScript = ""; |
|
|
|
// Clear outputs if no script is running |
|
|
|
if (!scriptEngine) { |
|
|
|
for (int i = 0; i < NUM_ROWS; i++) |
|
|
|
for (int c = 0; c < 3; c++) |
|
|
|
lights[LIGHT_LIGHTS + i * 3 + c].setBrightness(0.f); |
|
|
|
for (int i = 0; i < NUM_ROWS; i++) |
|
|
|
for (int c = 0; c < 3; c++) |
|
|
|
lights[SWITCH_LIGHTS + i * 3 + c].setBrightness(0.f); |
|
|
|
for (int i = 0; i < NUM_ROWS; i++) |
|
|
|
outputs[OUT_OUTPUTS + i].setVoltage(0.f); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// Inputs |
|
|
@@ -146,6 +160,7 @@ struct Prototype : Module { |
|
|
|
|
|
|
|
// Process block |
|
|
|
if (++bufferIndex >= block->bufferSize) { |
|
|
|
std::lock_guard<std::mutex> lock(scriptMutex); |
|
|
|
bufferIndex = 0; |
|
|
|
|
|
|
|
// Block settings |
|
|
@@ -158,12 +173,11 @@ struct Prototype : Module { |
|
|
|
for (int i = 0; i < NUM_ROWS; i++) |
|
|
|
block->switches[i] = params[SWITCH_PARAMS + i].getValue() > 0.f; |
|
|
|
float oldKnobs[NUM_ROWS]; |
|
|
|
std::memcpy(oldKnobs, block->knobs, sizeof(block->knobs)); |
|
|
|
std::memcpy(oldKnobs, block->knobs, sizeof(oldKnobs)); |
|
|
|
|
|
|
|
// Run ScriptEngine's process function |
|
|
|
{ |
|
|
|
// Process buffer |
|
|
|
std::lock_guard<std::mutex> lock(scriptMutex); |
|
|
|
if (scriptEngine) { |
|
|
|
if (scriptEngine->process()) { |
|
|
|
WARN("Script %s process() failed. Stopped script.", path.c_str()); |
|
|
@@ -175,6 +189,7 @@ struct Prototype : Module { |
|
|
|
} |
|
|
|
|
|
|
|
// Params |
|
|
|
// Only set params if values were changed by the script. This avoids issues when the user is manipulating them from the UI thread. |
|
|
|
for (int i = 0; i < NUM_ROWS; i++) { |
|
|
|
if (block->knobs[i] != oldKnobs[i]) |
|
|
|
params[KNOB_PARAMS + i].setValue(block->knobs[i]); |
|
|
@@ -247,17 +262,9 @@ struct Prototype : Module { |
|
|
|
// Reset process state |
|
|
|
frameDivider = 32; |
|
|
|
frame = 0; |
|
|
|
*block = ProcessBlock(); |
|
|
|
bufferIndex = 0; |
|
|
|
// Reset outputs and lights because they might hold old values |
|
|
|
for (int i = 0; i < NUM_ROWS; i++) |
|
|
|
outputs[OUT_OUTPUTS + i].setVoltage(0.f); |
|
|
|
for (int i = 0; i < NUM_ROWS; i++) |
|
|
|
for (int c = 0; c < 3; c++) |
|
|
|
lights[LIGHT_LIGHTS + i * 3 + c].setBrightness(0.f); |
|
|
|
for (int i = 0; i < NUM_ROWS; i++) |
|
|
|
for (int c = 0; c < 3; c++) |
|
|
|
lights[SWITCH_LIGHTS + i * 3 + c].setBrightness(0.f); |
|
|
|
// Reset block |
|
|
|
*block = ProcessBlock(); |
|
|
|
|
|
|
|
if (script == "") |
|
|
|
return; |
|
|
@@ -322,9 +329,8 @@ struct Prototype : Module { |
|
|
|
std::string script = std::string(json_string_value(scriptJ), json_string_length(scriptJ)); |
|
|
|
if (script != "") { |
|
|
|
// Request security warning message |
|
|
|
if (!securityAccepted) { |
|
|
|
securityRequested = true; |
|
|
|
} |
|
|
|
securityAccepted = false; |
|
|
|
securityRequested = true; |
|
|
|
securityScript = script; |
|
|
|
} |
|
|
|
} |
|
|
@@ -365,10 +371,13 @@ struct Prototype : Module { |
|
|
|
if (newExt == "") |
|
|
|
newPath += "." + ext; |
|
|
|
|
|
|
|
std::ofstream f(newPath); |
|
|
|
f << script; |
|
|
|
// Set path directly |
|
|
|
path = newPath; |
|
|
|
// Write and close file |
|
|
|
{ |
|
|
|
std::ofstream f(newPath); |
|
|
|
f << script; |
|
|
|
} |
|
|
|
// Load path so that it reloads and is watched. |
|
|
|
setPath(newPath); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|