aboutsummaryrefslogtreecommitdiffhomepage
path: root/backends/lua.c
diff options
context:
space:
mode:
Diffstat (limited to 'backends/lua.c')
-rw-r--r--backends/lua.c74
1 files changed, 48 insertions, 26 deletions
diff --git a/backends/lua.c b/backends/lua.c
index 968193e..7424f65 100644
--- a/backends/lua.c
+++ b/backends/lua.c
@@ -155,8 +155,19 @@ static void lua_thread_resume(size_t current_thread){
lua_settable(thread[current_thread].thread, LUA_REGISTRYINDEX);
}
-static int lua_callback_thread(lua_State* interpreter){
+static instance* lua_fetch_instance(lua_State* interpreter){
instance* inst = NULL;
+
+ //get instance pointer from registry
+ lua_pushstring(interpreter, LUA_REGISTRY_KEY);
+ lua_gettable(interpreter, LUA_REGISTRYINDEX);
+ inst = (instance*) lua_touserdata(interpreter, -1);
+ lua_pop(interpreter, 1);
+ return inst;
+}
+
+static int lua_callback_thread(lua_State* interpreter){
+ instance* inst = lua_fetch_instance(interpreter);
size_t u = threads;
if(lua_gettop(interpreter) != 1){
LOGPF("Thread function called with %d arguments, expected function", lua_gettop(interpreter));
@@ -165,11 +176,6 @@ static int lua_callback_thread(lua_State* interpreter){
luaL_checktype(interpreter, 1, LUA_TFUNCTION);
- //get instance pointer from registry
- lua_pushstring(interpreter, LUA_REGISTRY_KEY);
- lua_gettable(interpreter, LUA_REGISTRYINDEX);
- inst = (instance*) lua_touserdata(interpreter, -1);
-
//make space for a new thread
thread = realloc(thread, (threads + 1) * sizeof(lua_thread));
if(!thread){
@@ -223,20 +229,14 @@ static int lua_callback_output(lua_State* interpreter){
size_t n = 0;
channel_value val;
const char* channel_name = NULL;
- instance* inst = NULL;
- lua_instance_data* data = NULL;
+ instance* inst = lua_fetch_instance(interpreter);
+ lua_instance_data* data = (lua_instance_data*) inst->impl;
if(lua_gettop(interpreter) != 2){
LOGPF("Output function called with %d arguments, expected 2 (string, number)", lua_gettop(interpreter));
return 0;
}
- //get instance pointer from registry
- lua_pushstring(interpreter, LUA_REGISTRY_KEY);
- lua_gettable(interpreter, LUA_REGISTRYINDEX);
- inst = (instance*) lua_touserdata(interpreter, -1);
- data = (lua_instance_data*) inst->impl;
-
//fetch function parameters
channel_name = lua_tostring(interpreter, 1);
val.normalised = clamp(luaL_checknumber(interpreter, 2), 1.0, 0.0);
@@ -264,6 +264,28 @@ static int lua_callback_output(lua_State* interpreter){
return 0;
}
+static int lua_callback_cleanup_handler(lua_State* interpreter){
+ instance* inst = lua_fetch_instance(interpreter);
+ lua_instance_data* data = (lua_instance_data*) inst->impl;
+ int current_handler = data->cleanup_handler;
+
+ if(lua_gettop(interpreter) != 1){
+ LOGPF("Cleanup handler function called with %d arguments, expected 1 (function)", lua_gettop(interpreter));
+ return 0;
+ }
+
+ luaL_checktype(interpreter, 1, LUA_TFUNCTION);
+
+ data->cleanup_handler = luaL_ref(interpreter, LUA_REGISTRYINDEX);
+ if(current_handler == LUA_NOREF){
+ lua_pushnil(interpreter);
+ return 1;
+ }
+ lua_rawgeti(interpreter, LUA_REGISTRYINDEX, current_handler);
+ luaL_unref(interpreter, LUA_REGISTRYINDEX, current_handler);
+ return 1;
+}
+
static int lua_callback_interval(lua_State* interpreter){
size_t n = 0;
uint64_t interval = 0;
@@ -274,10 +296,6 @@ static int lua_callback_interval(lua_State* interpreter){
return 0;
}
- //get instance pointer from registry
- lua_pushstring(interpreter, LUA_REGISTRY_KEY);
- lua_gettable(interpreter, LUA_REGISTRYINDEX);
-
//fetch and round the interval
interval = luaL_checkinteger(interpreter, 2);
if(interval % 10 < 5){
@@ -341,21 +359,15 @@ static int lua_callback_interval(lua_State* interpreter){
static int lua_callback_value(lua_State* interpreter, uint8_t input){
size_t n = 0;
- instance* inst = NULL;
- lua_instance_data* data = NULL;
const char* channel_name = NULL;
+ instance* inst = lua_fetch_instance(interpreter);
+ lua_instance_data* data = (lua_instance_data*) inst->impl;
if(lua_gettop(interpreter) != 1){
LOGPF("get_value function called with %d arguments, expected 1 (string)", lua_gettop(interpreter));
return 0;
}
- //get instance pointer from registry
- lua_pushstring(interpreter, LUA_REGISTRY_KEY);
- lua_gettable(interpreter, LUA_REGISTRYINDEX);
- inst = (instance*) lua_touserdata(interpreter, -1);
- data = (lua_instance_data*) inst->impl;
-
//fetch argument
channel_name = lua_tostring(interpreter, 1);
@@ -425,6 +437,7 @@ static int lua_instance(instance* inst){
//load the interpreter
data->interpreter = luaL_newstate();
+ data->cleanup_handler = LUA_NOREF;
if(!data->interpreter){
LOG("Failed to initialize interpreter");
free(data);
@@ -441,6 +454,7 @@ static int lua_instance(instance* inst){
lua_register(data->interpreter, "timestamp", lua_callback_timestamp);
lua_register(data->interpreter, "thread", lua_callback_thread);
lua_register(data->interpreter, "sleep", lua_callback_sleep);
+ lua_register(data->interpreter, "cleanup_handler", lua_callback_cleanup_handler);
//store instance pointer to the lua state
lua_pushstring(data->interpreter, LUA_REGISTRY_KEY);
@@ -578,6 +592,7 @@ static int lua_resolve_symbol(lua_State* interpreter, char* symbol){
|| !strcmp(symbol, "output_value")
|| !strcmp(symbol, "input_channel")
|| !strcmp(symbol, "timestamp")
+ || !strcmp(symbol, "cleanup_handler")
|| !strcmp(symbol, "interval")){
return LUA_NOREF;
}
@@ -639,6 +654,13 @@ static int lua_shutdown(size_t n, instance** inst){
for(u = 0; u < n; u++){
data = (lua_instance_data*) inst[u]->impl;
+
+ //call cleanup function if one is registered
+ if(data->cleanup_handler != LUA_NOREF){
+ lua_rawgeti(data->interpreter, LUA_REGISTRYINDEX, data->cleanup_handler);
+ lua_pcall(data->interpreter, 0, 0, 0);
+ }
+
//stop the interpreter
lua_close(data->interpreter);
//cleanup channel data