Skip to content

Commit

Permalink
Fixes #157 - Add Lua API for Keyboard Events
Browse files Browse the repository at this point in the history
  • Loading branch information
st3fan committed Sep 20, 2017
1 parent 97d415a commit 1cd98d8
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 7 deletions.
141 changes: 134 additions & 7 deletions src/two.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,18 +352,105 @@ void ewm_two_destroy(struct ewm_two_t *two) {

// Lua support

int ewm_two_luaopen(lua_State *state) {
luaL_Reg ewm_two_functions[] = {
// TODO What module level functions do we need here?
{NULL, NULL}
};
luaL_newlib(state, ewm_two_functions);
static int two_lua_index(lua_State *state) {
//void *two_data = luaL_checkudata(state, 1, "two_meta_table");
//struct ewm_two_t *two = *((struct ewm_two_t**) two_data);

if (!lua_isstring(state, 2)) {
printf("TODO lua_cpu_index: arg 2 is not a string\n");
return 0;
}

const char *name = lua_tostring(state, 2);

if (strcmp(name, "version") == 0) {
lua_pushnumber(state, 1);
return 1;
}

// Delegate to the methods metatable
luaL_getmetatable(state, "two_methods_meta_table");
lua_pushvalue(state, 2);
lua_rawget(state, -2);

return 1;
}

static int two_lua_newindex(lua_State *state) {
//void *two_data = luaL_checkudata(state, 1, "two_meta_table");
//struct ewm_two_t *two = *((struct ewm_two_t**) two_data);

// TODO What can we modify in two?

return 0;
}

static int two_lua_onKeyDown(lua_State *state) {
if (lua_gettop(state) != 2) {
printf("Not enough arguments\n");
return 0;
}

void *two_data = luaL_checkudata(state, 1, "two_meta_table");
struct ewm_two_t *two = *((struct ewm_two_t**) two_data);

if (lua_type(state, 2) != LUA_TFUNCTION) {
printf("Second arg fail\n");
return 0;
}

lua_pushvalue(state, 2);
two->lua_key_down_fn = luaL_ref(state, LUA_REGISTRYINDEX);

return 0;
}

static int two_lua_onKeyUp(lua_State *state) {
if (lua_gettop(state) != 2) {
printf("Not enough arguments\n");
return 0;
}

void *two_data = luaL_checkudata(state, 1, "two_meta_table");
struct ewm_two_t *two = *((struct ewm_two_t**) two_data);

if (lua_type(state, 2) != LUA_TFUNCTION) {
printf("Second arg fail\n");
return 0;
}

lua_pushvalue(state, 2);
two->lua_key_up_fn = luaL_ref(state, LUA_REGISTRYINDEX);

return 0;
}

int ewm_two_init_lua(struct ewm_two_t *two, struct ewm_lua_t *lua) {
two->lua = lua;
luaL_requiref(two->lua->state, "two", ewm_two_luaopen, 0);

luaL_Reg functions[] = {
{"__index", two_lua_index},
{"__newindex", two_lua_newindex},
{NULL, NULL}
};
ewm_lua_register_component(lua, "two", functions);

luaL_Reg two_methods[] = {
{"onKeyDown", two_lua_onKeyDown},
{"onKeyUp", two_lua_onKeyUp},
{NULL, NULL}
};
ewm_lua_register_component(lua, "two_methods", two_methods);

// Register a global cpu instance

void *two_data = lua_newuserdata(lua->state, sizeof(struct ewm_two_t*));
*((struct ewm_two_t**) two_data) = two;

luaL_getmetatable(lua->state, "two_meta_table");
lua_setmetatable(lua->state, -2);
lua_setglobal(lua->state, "two");

return 0;
}

Expand Down Expand Up @@ -405,6 +492,26 @@ static bool ewm_two_poll_event(struct ewm_two_t *two, SDL_Window *window) { // T
break;

case SDL_KEYDOWN:
if (two->lua_key_down_fn != LUA_NOREF) {
lua_rawgeti(two->lua->state, LUA_REGISTRYINDEX, two->lua_key_down_fn);
ewm_lua_push_two(two->lua, two);
lua_pushinteger(two->lua->state, event.key.keysym.mod);
lua_pushinteger(two->lua->state, event.key.keysym.sym);
if (lua_pcall(two->lua->state, 3, 1, 0) != LUA_OK) {
printf("two: script error: %s\n", lua_tostring(two->lua->state, -1));
return true;
}

if (lua_isboolean(two->lua->state, -1) == 0) {
printf("two: script error: expected boolean result\n");
return true;
}

if (lua_toboolean(two->lua->state, -1)) {
return true;
}
}

if (event.key.keysym.mod & KMOD_CTRL) {
if (event.key.keysym.sym >= SDLK_a && event.key.keysym.sym <= SDLK_z) {
two->key = (event.key.keysym.sym - SDLK_a + 1) | 0x80;
Expand Down Expand Up @@ -459,6 +566,26 @@ static bool ewm_two_poll_event(struct ewm_two_t *two, SDL_Window *window) { // T
break;

case SDL_KEYUP:
if (two->lua_key_up_fn != LUA_NOREF) {
lua_rawgeti(two->lua->state, LUA_REGISTRYINDEX, two->lua_key_up_fn);
ewm_lua_push_two(two->lua, two);
lua_pushinteger(two->lua->state, event.key.keysym.mod);
lua_pushinteger(two->lua->state, event.key.keysym.sym);
if (lua_pcall(two->lua->state, 3, 1, 0) != LUA_OK) {
printf("two: script error: %s\n", lua_tostring(two->lua->state, -1));
return true;
}

if (lua_isboolean(two->lua->state, -1) == 0) {
printf("two: script error: expected boolean result\n");
return true;
}

if (lua_toboolean(two->lua->state, -1)) {
return true;
}
}

if (event.key.keysym.mod & KMOD_ALT) {
switch (event.key.keysym.sym) {
case SDLK_1:
Expand Down
3 changes: 3 additions & 0 deletions src/two.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ struct ewm_two_t {
bool status_bar_visible;

bool debug;

int lua_key_down_fn;
int lua_key_up_fn;
};

struct ewm_two_t *ewm_two_create(int type, SDL_Renderer *renderer, SDL_Joystick *joystick);
Expand Down

0 comments on commit 1cd98d8

Please sign in to comment.