| @@ -27,11 +27,22 @@ LUALIB_API void custom_openlibs(lua_State *L) | |||
| struct LuaJITEngine : ScriptEngine { | |||
| lua_State* L = NULL; | |||
| struct SafeArray { | |||
| void* p; | |||
| size_t len; | |||
| // This is a mirror of ProcessBlock that we are going to use | |||
| // to provide 1-based indices within the Lua VM | |||
| struct LuaProcessBlock { | |||
| float sampleRate; | |||
| float sampleTime; | |||
| int bufferSize; | |||
| float* inputs[NUM_ROWS+1]; | |||
| float* outputs[NUM_ROWS+1]; | |||
| float* knobs; | |||
| bool* switches; | |||
| float* lights[NUM_ROWS+1]; | |||
| float* switchLights[NUM_ROWS+1]; | |||
| }; | |||
| LuaProcessBlock block; | |||
| ~LuaJITEngine() { | |||
| if (L) | |||
| lua_close(L); | |||
| @@ -42,7 +53,22 @@ struct LuaJITEngine : ScriptEngine { | |||
| } | |||
| int run(const std::string& path, const std::string& script) override { | |||
| ProcessBlock* block = getProcessBlock(); | |||
| ProcessBlock* original_block = getProcessBlock(); | |||
| block.sampleRate = original_block->sampleRate; | |||
| block.sampleTime = original_block->sampleTime; | |||
| block.bufferSize = original_block->bufferSize; | |||
| // Initialize all the pointers with an offset of -1 | |||
| block.knobs = (float*)&(original_block->knobs[-1]); | |||
| block.switches = (bool*)&(original_block->switches[-1]); | |||
| for(int i = 1; i < NUM_ROWS + 1; i++) { | |||
| block.inputs[i] = (float*)&(original_block->inputs[i-1][-1]); | |||
| block.outputs[i] = (float*)&(original_block->outputs[i-1][-1]); | |||
| block.lights[i] = (float*)&(original_block->lights[i-1][-1]); | |||
| block.switchLights[i] = (float*)&(original_block->switchLights[i-1][-1]); | |||
| } | |||
| L = luaL_newstate(); | |||
| if (!L) { | |||
| @@ -80,20 +106,21 @@ struct LuaJITEngine : ScriptEngine { | |||
| std::stringstream ffi_stream; | |||
| ffi_stream | |||
| << "local ffi = require('ffi')" << std::endl | |||
| // Describes the struct 'ProcessBlock' that way LuaJIT knows how to access the data | |||
| // Describes the struct 'LuaProcessBlock' that way LuaJIT knows how to access the data | |||
| << "ffi.cdef[[" << std::endl | |||
| << "struct ProcessBlock {" << std::endl | |||
| << "struct LuaProcessBlock {" << std::endl | |||
| << "float sampleRate;" << std::endl | |||
| << "float sampleTime;" << std::endl | |||
| << "int bufferSize;" << std::endl | |||
| << "float inputs[" << NUM_ROWS << "][" << MAX_BUFFER_SIZE << "];" << std::endl | |||
| << "float outputs[" << NUM_ROWS << "][" << MAX_BUFFER_SIZE << "];" << std::endl | |||
| << "float knobs[" << NUM_ROWS << "];" << std::endl | |||
| << "bool switches[" << NUM_ROWS << "];" << std::endl | |||
| << "float lights[" << NUM_ROWS << "][3];" << std::endl | |||
| << "float switchLights[" << NUM_ROWS << "][3];};]]" << std::endl | |||
| << "float *inputs[" << NUM_ROWS + 1 << "];" << std::endl | |||
| << "float *outputs[" << NUM_ROWS + 1 << "];" << std::endl | |||
| << "float *knobs;" << std::endl | |||
| << "bool *switches;" << std::endl | |||
| << "float *lights[" << NUM_ROWS + 1 << "];" << std::endl | |||
| << "float *switchLights[" << NUM_ROWS + 1 << "];" << std::endl | |||
| <<"};]]" << std::endl | |||
| // Declares the function 'castBlock' used to transform the 'block' pointer into a LuaJIT cdata | |||
| << "function castBlock(b) return ffi.cast('struct ProcessBlock*', b) end"; | |||
| << "function castBlock(b) return ffi.cast('struct LuaProcessBlock*', b) end"; | |||
| std::string ffi_script = ffi_stream.str(); | |||
| // Compile the ffi script | |||
| @@ -157,7 +184,7 @@ struct LuaJITEngine : ScriptEngine { | |||
| // Create block object | |||
| lua_getglobal(L, "castBlock"); | |||
| lua_pushlightuserdata(L, (void *)block); | |||
| lua_pushlightuserdata(L, (void *)&block); | |||
| if (lua_pcall(L, 1, 1, 0) != 0) | |||
| printf("error running function 'castBlock': %s", lua_tostring(L, -1)); | |||
| @@ -165,6 +192,13 @@ struct LuaJITEngine : ScriptEngine { | |||
| } | |||
| int process() override { | |||
| ProcessBlock* original_block = getProcessBlock(); | |||
| // Update the values of the block (the pointers should not change) | |||
| block.sampleRate = original_block->sampleRate; | |||
| block.sampleTime = original_block->sampleTime; | |||
| block.bufferSize = original_block->bufferSize; | |||
| // Duplicate process function | |||
| lua_pushvalue(L, -2); | |||
| // Duplicate block | |||