awtk/lua/custom.c

180 lines
4.3 KiB
C
Raw Normal View History

2018-03-10 08:06:02 +08:00
#include "base/enums.h"
#include "ui_loader/ui_builder_default.h"
2018-03-04 13:09:23 +08:00
typedef struct _userdata_info_t {
const char* info;
void* data;
2018-03-09 21:54:46 +08:00
} userdata_info_t;
2018-03-04 08:32:52 +08:00
static lua_State* s_current_L = NULL;
2018-03-09 21:54:46 +08:00
extern void luaL_openlib(lua_State* L, const char* libname, const luaL_Reg* l, int nup);
2018-03-04 08:32:52 +08:00
2018-03-04 13:09:23 +08:00
static int lftk_newuserdata(lua_State* L, void* data, const char* info, const char* metatable) {
2018-03-10 08:06:02 +08:00
char str[48];
2018-03-04 13:09:23 +08:00
userdata_info_t* udata = NULL;
return_value_if_fail(data != NULL, 0);
udata = (userdata_info_t*)lua_newuserdata(L, sizeof(userdata_info_t));
return_value_if_fail(data != NULL, 0);
udata->data = data;
udata->info = info;
2018-03-10 08:06:02 +08:00
if (strstr(info, "/widget_t") != NULL && strcmp(metatable, "lftk.widget_t") == 0) {
widget_t* widget = (widget_t*)data;
const key_type_value_t* kv = widget_name_find_by_value(widget->type);
if (kv != NULL) {
snprintf(str, sizeof(str), "lftk.%s_t", kv->name);
metatable = str;
}
}
2018-03-09 21:54:46 +08:00
if (metatable != NULL) {
2018-03-04 13:09:23 +08:00
luaL_getmetatable(L, metatable);
lua_setmetatable(L, -2);
}
return 1;
}
2018-03-04 08:32:52 +08:00
static const luaL_Reg* find_member(const luaL_Reg* funcs, const char* name) {
const luaL_Reg* iter = funcs;
2018-03-09 21:54:46 +08:00
while (iter->name) {
if (*iter->name == *name && strcmp(iter->name, name) == 0) {
2018-03-04 08:32:52 +08:00
return iter;
2018-03-09 21:54:46 +08:00
}
2018-03-04 08:32:52 +08:00
iter++;
}
return NULL;
}
static void* lftk_checkudata(lua_State* L, int idx, const char* name) {
2018-03-04 13:09:23 +08:00
userdata_info_t* udata = (userdata_info_t*)lua_touserdata(L, idx);
2018-03-09 21:54:46 +08:00
if (udata) {
2018-03-10 08:06:02 +08:00
// assert(strstr(udata->info, name) != NULL);
2018-03-04 13:09:23 +08:00
return udata->data;
} else {
return NULL;
}
2018-03-04 08:32:52 +08:00
}
static ret_t call_on_event(void* ctx, event_t* e) {
lua_State* L = (lua_State*)s_current_L;
int func_id = (char*)ctx - (char*)NULL;
lua_settop(L, 0);
lua_rawgeti(L, LUA_REGISTRYINDEX, func_id);
2018-03-04 13:09:23 +08:00
lftk_newuserdata(L, e, "event_t", NULL);
2018-03-04 08:32:52 +08:00
2018-03-09 21:54:46 +08:00
lua_pcall(L, 1, 1, 0);
2018-03-04 08:32:52 +08:00
2018-03-06 21:56:52 +08:00
return 1;
2018-03-04 08:32:52 +08:00
}
static int wrap_widget_on(lua_State* L) {
ret_t ret = 0;
2018-03-04 13:09:23 +08:00
widget_t* widget = (widget_t*)lftk_checkudata(L, 1, "widget_t");
2018-03-04 08:32:52 +08:00
event_type_t type = (event_type_t)luaL_checkinteger(L, 2);
2018-03-09 21:54:46 +08:00
if (lua_isfunction(L, 3)) {
2018-03-04 08:32:52 +08:00
int func_id = 0;
2018-03-09 21:54:46 +08:00
lua_pushvalue(L, 3);
2018-03-04 08:32:52 +08:00
func_id = luaL_ref(L, LUA_REGISTRYINDEX);
ret = (ret_t)widget_on(widget, type, call_on_event, (char*)NULL + func_id);
2018-03-09 21:54:46 +08:00
lua_pushnumber(L, (lua_Number)ret);
2018-03-04 13:09:23 +08:00
2018-03-04 08:32:52 +08:00
return 1;
} else {
return 0;
}
}
static int wrap_widget_off(lua_State* L) {
ret_t ret = 0;
2018-03-04 13:09:23 +08:00
widget_t* widget = (widget_t*)lftk_checkudata(L, 1, "widget_t");
2018-03-04 08:32:52 +08:00
uint32_t id = (uint32_t)luaL_checkinteger(L, 2);
emitter_item_t* item = emitter_find(widget->emitter, id);
2018-03-04 13:09:23 +08:00
2018-03-09 21:54:46 +08:00
if (item) {
2018-03-04 08:32:52 +08:00
uint32_t func_id = (char*)(item->ctx) - (char*)NULL;
luaL_unref(L, LUA_REGISTRYINDEX, func_id);
ret = (ret_t)widget_off(widget, id);
}
2018-03-09 21:54:46 +08:00
lua_pushnumber(L, (lua_Number)(ret));
2018-03-04 08:32:52 +08:00
return 1;
}
static int to_wstr(lua_State* L) {
2018-03-09 21:54:46 +08:00
const char* str = (const char*)luaL_checkstring(L, 1);
2018-03-04 08:32:52 +08:00
uint32_t size = (strlen(str) + 1) * sizeof(wchar_t);
wchar_t* p = (wchar_t*)lua_newuserdata(L, size);
utf8_to_utf16(str, p, size);
2018-03-09 21:54:46 +08:00
lua_pushlightuserdata(L, p);
2018-03-04 08:32:52 +08:00
return 1;
}
static int to_str(lua_State* L) {
2018-03-09 21:54:46 +08:00
const wchar_t* str = (const wchar_t*)lua_touserdata(L, 1);
2018-03-04 08:32:52 +08:00
uint32_t size = (wcslen(str) + 1) * 3;
char* p = (char*)lua_newuserdata(L, size);
utf8_from_utf16(str, p, size);
2018-03-09 21:54:46 +08:00
lua_pushstring(L, p);
2018-03-04 08:32:52 +08:00
return 1;
}
2018-03-06 21:56:52 +08:00
static ret_t call_on_timer(const timer_info_t* timer) {
ret_t ret = RET_REMOVE;
lua_State* L = (lua_State*)s_current_L;
int func_id = (char*)(timer->ctx) - (char*)NULL;
lua_settop(L, 0);
lua_rawgeti(L, LUA_REGISTRYINDEX, func_id);
lua_pcall(L, 0, 1, 0);
2018-03-09 21:54:46 +08:00
2018-03-06 21:56:52 +08:00
ret = (ret_t)lua_tonumber(L, -1);
return ret;
}
static int wrap_timer_add(lua_State* L) {
uint32_t id = 0;
2018-03-09 21:54:46 +08:00
if (lua_isfunction(L, 1)) {
2018-03-06 21:56:52 +08:00
int func_id = 0;
uint32_t duration_ms = (uint32_t)luaL_checkinteger(L, 2);
2018-03-09 21:54:46 +08:00
lua_pushvalue(L, 1);
2018-03-06 21:56:52 +08:00
func_id = luaL_ref(L, LUA_REGISTRYINDEX);
2018-03-09 21:54:46 +08:00
2018-03-06 21:56:52 +08:00
id = timer_add(call_on_timer, (char*)NULL + func_id, duration_ms);
2018-03-09 21:54:46 +08:00
lua_pushnumber(L, (lua_Number)id);
2018-03-06 21:56:52 +08:00
return 1;
} else {
return 0;
}
}
static int wrap_timer_remove(lua_State* L) {
ret_t ret = 0;
uint32_t id = (uint32_t)luaL_checkinteger(L, 1);
const timer_info_t* timer = timer_find(id);
2018-03-09 21:54:46 +08:00
if (timer) {
2018-03-06 21:56:52 +08:00
uint32_t func_id = (char*)(timer->ctx) - (char*)NULL;
luaL_unref(L, LUA_REGISTRYINDEX, func_id);
ret = (ret_t)timer_remove(id);
}
2018-03-09 21:54:46 +08:00
lua_pushnumber(L, (lua_Number)(ret));
2018-03-06 21:56:52 +08:00
return 1;
}