|
|
@@ -1,28 +1,6 @@ |
|
|
|
#include "ScriptEngine.hpp" |
|
|
|
#include <luajit-2.0/lua.hpp> |
|
|
|
|
|
|
|
static const luaL_Reg lj_lib_load[] = { |
|
|
|
{ "", luaopen_base }, |
|
|
|
{ LUA_LOADLIBNAME, luaopen_package }, |
|
|
|
{ LUA_TABLIBNAME, luaopen_table }, |
|
|
|
{ LUA_STRLIBNAME, luaopen_string }, |
|
|
|
{ LUA_MATHLIBNAME, luaopen_math }, |
|
|
|
{ LUA_BITLIBNAME, luaopen_bit }, |
|
|
|
{ LUA_JITLIBNAME, luaopen_jit }, |
|
|
|
{ LUA_FFILIBNAME, luaopen_ffi }, |
|
|
|
{ NULL, NULL } |
|
|
|
}; |
|
|
|
|
|
|
|
LUALIB_API void custom_openlibs(lua_State *L) |
|
|
|
{ |
|
|
|
const luaL_Reg *lib; |
|
|
|
for (lib = lj_lib_load; lib->func; lib++) { |
|
|
|
lua_pushcfunction(L, lib->func); |
|
|
|
lua_pushstring(L, lib->name); |
|
|
|
lua_call(L, 1, 0); |
|
|
|
} |
|
|
|
lua_pop(L, 1); |
|
|
|
} |
|
|
|
|
|
|
|
struct LuaJITEngine : ScriptEngine { |
|
|
|
lua_State* L = NULL; |
|
|
@@ -33,15 +11,15 @@ struct LuaJITEngine : ScriptEngine { |
|
|
|
float sampleRate; |
|
|
|
float sampleTime; |
|
|
|
int bufferSize; |
|
|
|
float* inputs[NUM_ROWS+1]; |
|
|
|
float* outputs[NUM_ROWS+1]; |
|
|
|
float* inputs[NUM_ROWS + 1]; |
|
|
|
float* outputs[NUM_ROWS + 1]; |
|
|
|
float* knobs; |
|
|
|
bool* switches; |
|
|
|
float* lights[NUM_ROWS+1]; |
|
|
|
float* switchLights[NUM_ROWS+1]; |
|
|
|
float* lights[NUM_ROWS + 1]; |
|
|
|
float* switchLights[NUM_ROWS + 1]; |
|
|
|
}; |
|
|
|
|
|
|
|
LuaProcessBlock block; |
|
|
|
LuaProcessBlock luaBlock; |
|
|
|
|
|
|
|
~LuaJITEngine() { |
|
|
|
if (L) |
|
|
@@ -53,22 +31,21 @@ struct LuaJITEngine : ScriptEngine { |
|
|
|
} |
|
|
|
|
|
|
|
int run(const std::string& path, const std::string& script) override { |
|
|
|
ProcessBlock* original_block = getProcessBlock(); |
|
|
|
|
|
|
|
block.sampleRate = original_block->sampleRate; |
|
|
|
block.sampleTime = original_block->sampleTime; |
|
|
|
block.bufferSize = original_block->bufferSize; |
|
|
|
ProcessBlock* block = getProcessBlock(); |
|
|
|
|
|
|
|
// 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]); |
|
|
|
#pragma GCC diagnostic push |
|
|
|
#pragma GCC diagnostic ignored "-Warray-bounds" |
|
|
|
luaBlock.knobs = &block->knobs[-1]; |
|
|
|
luaBlock.switches = &block->switches[-1]; |
|
|
|
|
|
|
|
for (int i = 0; i < NUM_ROWS; i++) { |
|
|
|
luaBlock.inputs[i + 1] = &block->inputs[i][-1]; |
|
|
|
luaBlock.outputs[i + 1] = &block->outputs[i][-1]; |
|
|
|
luaBlock.lights[i + 1] = &block->lights[i][-1]; |
|
|
|
luaBlock.switchLights[i + 1] = &block->switchLights[i][-1]; |
|
|
|
} |
|
|
|
#pragma GCC diagnostic pop |
|
|
|
|
|
|
|
L = luaL_newstate(); |
|
|
|
if (!L) { |
|
|
@@ -77,7 +54,22 @@ struct LuaJITEngine : ScriptEngine { |
|
|
|
} |
|
|
|
|
|
|
|
// Import a subset of the standard library |
|
|
|
custom_openlibs(L); |
|
|
|
static const luaL_Reg lj_lib_load[] = { |
|
|
|
{"", luaopen_base}, |
|
|
|
{LUA_LOADLIBNAME, luaopen_package}, |
|
|
|
{LUA_TABLIBNAME, luaopen_table}, |
|
|
|
{LUA_STRLIBNAME, luaopen_string}, |
|
|
|
{LUA_MATHLIBNAME, luaopen_math}, |
|
|
|
{LUA_BITLIBNAME, luaopen_bit}, |
|
|
|
{LUA_JITLIBNAME, luaopen_jit}, |
|
|
|
{LUA_FFILIBNAME, luaopen_ffi}, |
|
|
|
{NULL, NULL} |
|
|
|
}; |
|
|
|
for (const luaL_Reg* lib = lj_lib_load; lib->func; lib++) { |
|
|
|
lua_pushcfunction(L, lib->func); |
|
|
|
lua_pushstring(L, lib->name); |
|
|
|
lua_call(L, 1, 0); |
|
|
|
} |
|
|
|
|
|
|
|
// Set user pointer |
|
|
|
lua_pushlightuserdata(L, this); |
|
|
@@ -102,11 +94,11 @@ struct LuaJITEngine : ScriptEngine { |
|
|
|
} |
|
|
|
lua_setglobal(L, "config"); |
|
|
|
|
|
|
|
// Loads the FFI auxiliary functions. |
|
|
|
// Load the FFI auxiliary functions. |
|
|
|
std::stringstream ffi_stream; |
|
|
|
ffi_stream |
|
|
|
<< "local ffi = require('ffi')" << std::endl |
|
|
|
// Describes the struct 'LuaProcessBlock' that way LuaJIT knows how to access the data |
|
|
|
// Describe the struct `LuaProcessBlock` so that LuaJIT knows how to access the data |
|
|
|
<< "ffi.cdef[[" << std::endl |
|
|
|
<< "struct LuaProcessBlock {" << std::endl |
|
|
|
<< "float sampleRate;" << std::endl |
|
|
@@ -118,9 +110,9 @@ struct LuaJITEngine : ScriptEngine { |
|
|
|
<< "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 LuaProcessBlock*', b) end"; |
|
|
|
<< "};]]" << std::endl |
|
|
|
// Declare the function `_castBlock` used to transform `luaBlock` pointer into a LuaJIT cdata |
|
|
|
<< "function _castBlock(b) return ffi.cast('struct LuaProcessBlock*', b) end"; |
|
|
|
std::string ffi_script = ffi_stream.str(); |
|
|
|
|
|
|
|
// Compile the ffi script |
|
|
@@ -183,21 +175,27 @@ struct LuaJITEngine : ScriptEngine { |
|
|
|
} |
|
|
|
|
|
|
|
// Create block object |
|
|
|
lua_getglobal(L, "castBlock"); |
|
|
|
lua_pushlightuserdata(L, (void *)&block); |
|
|
|
if (lua_pcall(L, 1, 1, 0) != 0) |
|
|
|
printf("error running function 'castBlock': %s", lua_tostring(L, -1)); |
|
|
|
lua_getglobal(L, "_castBlock"); |
|
|
|
lua_pushlightuserdata(L, (void*) &luaBlock); |
|
|
|
if (lua_pcall(L, 1, 1, 0)) { |
|
|
|
const char* s = lua_tostring(L, -1); |
|
|
|
WARN("LuaJIT: Error casting block: %s", s); |
|
|
|
display(s); |
|
|
|
lua_pop(L, 1); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int process() override { |
|
|
|
ProcessBlock* original_block = getProcessBlock(); |
|
|
|
ProcessBlock* 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; |
|
|
|
// Update the values of the block. |
|
|
|
// The pointer values do not change. |
|
|
|
luaBlock.sampleRate = block->sampleRate; |
|
|
|
luaBlock.sampleTime = block->sampleTime; |
|
|
|
luaBlock.bufferSize = block->bufferSize; |
|
|
|
|
|
|
|
// Duplicate process function |
|
|
|
lua_pushvalue(L, -2); |
|
|
|