kopia lustrzana https://github.com/jameshball/osci-render
Fix various lua bugs to prevent crashes
rodzic
19c115e47a
commit
60e7e2082d
|
@ -187,11 +187,17 @@ void OscirenderAudioProcessorEditor::updateCodeEditor() {
|
||||||
codeEditors[i]->setVisible(false);
|
codeEditors[i]->setVisible(false);
|
||||||
}
|
}
|
||||||
codeEditors[index]->setVisible(true);
|
codeEditors[index]->setVisible(true);
|
||||||
|
// used so that codeDocumentTextInserted and codeDocumentTextDeleted know whether the parserLock
|
||||||
|
// is held by the message thread or not. We hold the lock in this function, but not when the
|
||||||
|
// code document is updated by the user editing text. Since both functions are called by the
|
||||||
|
// message thread, this is safe.
|
||||||
|
updatingDocumentsWithParserLock = true;
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
codeEditors[index]->loadContent(audioProcessor.perspectiveEffect->getCode());
|
codeEditors[index]->loadContent(audioProcessor.perspectiveEffect->getCode());
|
||||||
} else {
|
} else {
|
||||||
codeEditors[index]->loadContent(juce::MemoryInputStream(*audioProcessor.getFileBlock(originalIndex), false).readEntireStreamAsString());
|
codeEditors[index]->loadContent(juce::MemoryInputStream(*audioProcessor.getFileBlock(originalIndex), false).readEntireStreamAsString());
|
||||||
}
|
}
|
||||||
|
updatingDocumentsWithParserLock = false;
|
||||||
}
|
}
|
||||||
triggerAsyncUpdate();
|
triggerAsyncUpdate();
|
||||||
}
|
}
|
||||||
|
@ -227,12 +233,22 @@ void OscirenderAudioProcessorEditor::editPerspectiveFunction(bool enable) {
|
||||||
|
|
||||||
// parsersLock AND effectsLock must be locked before calling this function
|
// parsersLock AND effectsLock must be locked before calling this function
|
||||||
void OscirenderAudioProcessorEditor::codeDocumentTextInserted(const juce::String& newText, int insertIndex) {
|
void OscirenderAudioProcessorEditor::codeDocumentTextInserted(const juce::String& newText, int insertIndex) {
|
||||||
|
if (updatingDocumentsWithParserLock) {
|
||||||
updateCodeDocument();
|
updateCodeDocument();
|
||||||
|
} else {
|
||||||
|
juce::SpinLock::ScopedLockType parserLock(audioProcessor.parsersLock);
|
||||||
|
updateCodeDocument();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parsersLock AND effectsLock must be locked before calling this function
|
// parsersLock AND effectsLock must be locked before calling this function
|
||||||
void OscirenderAudioProcessorEditor::codeDocumentTextDeleted(int startIndex, int endIndex) {
|
void OscirenderAudioProcessorEditor::codeDocumentTextDeleted(int startIndex, int endIndex) {
|
||||||
|
if (updatingDocumentsWithParserLock) {
|
||||||
updateCodeDocument();
|
updateCodeDocument();
|
||||||
|
} else {
|
||||||
|
juce::SpinLock::ScopedLockType parserLock(audioProcessor.parsersLock);
|
||||||
|
updateCodeDocument();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parsersLock AND effectsLock must be locked before calling this function
|
// parsersLock AND effectsLock must be locked before calling this function
|
||||||
|
|
|
@ -55,6 +55,8 @@ private:
|
||||||
MainMenuBarModel menuBarModel{*this};
|
MainMenuBarModel menuBarModel{*this};
|
||||||
juce::MenuBarComponent menuBar;
|
juce::MenuBarComponent menuBar;
|
||||||
|
|
||||||
|
std::atomic<bool> updatingDocumentsWithParserLock = false;
|
||||||
|
|
||||||
void codeDocumentTextInserted(const juce::String& newText, int insertIndex) override;
|
void codeDocumentTextInserted(const juce::String& newText, int insertIndex) override;
|
||||||
void codeDocumentTextDeleted(int startIndex, int endIndex) override;
|
void codeDocumentTextDeleted(int startIndex, int endIndex) override;
|
||||||
void updateCodeDocument();
|
void updateCodeDocument();
|
||||||
|
|
|
@ -381,10 +381,10 @@ void OscirenderAudioProcessor::changeCurrentFile(int index) {
|
||||||
if (index < 0 || index >= fileBlocks.size()) {
|
if (index < 0 || index >= fileBlocks.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
changeSound(sounds[index]);
|
|
||||||
currentFile = index;
|
currentFile = index;
|
||||||
updateLuaValues();
|
updateLuaValues();
|
||||||
updateObjValues();
|
updateObjValues();
|
||||||
|
changeSound(sounds[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OscirenderAudioProcessor::changeSound(ShapeSound::Ptr sound) {
|
void OscirenderAudioProcessor::changeSound(ShapeSound::Ptr sound) {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
LuaParser::LuaParser(juce::String script) {
|
LuaParser::LuaParser(juce::String script) {
|
||||||
// initialization
|
// initialization
|
||||||
L = luaL_newstate();
|
L = luaL_newstate();
|
||||||
|
lua_atpanic(L, panic);
|
||||||
luaL_openlibs(L);
|
luaL_openlibs(L);
|
||||||
|
|
||||||
this->script = script;
|
this->script = script;
|
||||||
|
@ -54,6 +55,7 @@ std::vector<float> LuaParser::run() {
|
||||||
|
|
||||||
lua_geti(L, LUA_REGISTRYINDEX, functionRef);
|
lua_geti(L, LUA_REGISTRYINDEX, functionRef);
|
||||||
|
|
||||||
|
if (lua_isfunction(L, -1)) {
|
||||||
const int ret = lua_pcall(L, 0, LUA_MULTRET, 0);
|
const int ret = lua_pcall(L, 0, LUA_MULTRET, 0);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
const char* error = lua_tostring(L, -1);
|
const char* error = lua_tostring(L, -1);
|
||||||
|
@ -70,8 +72,13 @@ std::vector<float> LuaParser::run() {
|
||||||
values.push_back(value);
|
values.push_back(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
DBG("functionRef is not a function");
|
||||||
|
functionRef = -1;
|
||||||
|
}
|
||||||
|
|
||||||
lua_pop(L, 1);
|
// clear stack
|
||||||
|
lua_settop(L, 0);
|
||||||
|
|
||||||
step++;
|
step++;
|
||||||
|
|
||||||
|
@ -86,3 +93,11 @@ void LuaParser::setVariable(juce::String variableName, double value) {
|
||||||
variables.push_back(value);
|
variables.push_back(value);
|
||||||
updateVariables = true;
|
updateVariables = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LuaParser::panic(lua_State *L) {
|
||||||
|
const char *msg = lua_tostring(L, -1);
|
||||||
|
if (msg == NULL) msg = "error object is not a string";
|
||||||
|
DBG("PANIC: unprotected error in call to Lua API (%s)\n" << msg);
|
||||||
|
return 0; /* return to Lua to abort */
|
||||||
|
}
|
|
@ -14,6 +14,8 @@ public:
|
||||||
private:
|
private:
|
||||||
void parse();
|
void parse();
|
||||||
|
|
||||||
|
static int panic(lua_State* L);
|
||||||
|
|
||||||
int functionRef = -1;
|
int functionRef = -1;
|
||||||
long step = 1;
|
long step = 1;
|
||||||
lua_State* L;
|
lua_State* L;
|
||||||
|
|
Ładowanie…
Reference in New Issue