lovr/src/api/event.c

186 lines
4.7 KiB
C
Raw Normal View History

2017-12-10 20:40:37 +00:00
#include "api.h"
2016-11-19 09:28:01 +00:00
#include "event/event.h"
2016-11-29 06:59:27 +00:00
2018-07-05 03:11:52 +00:00
const char* EventTypes[] = {
[EVENT_QUIT] = "quit",
[EVENT_FOCUS] = "focus",
[EVENT_MOUNT] = "mount",
[EVENT_THREAD_ERROR] = "threaderror",
[EVENT_CONTROLLER_ADDED] = "controlleradded",
[EVENT_CONTROLLER_REMOVED] = "controllerremoved",
[EVENT_CONTROLLER_PRESSED] = "controllerpressed",
[EVENT_CONTROLLER_RELEASED] = "controllerreleased",
};
2017-03-11 11:08:07 +00:00
2018-04-02 05:43:54 +00:00
static _Thread_local int pollRef;
2016-11-29 06:59:27 +00:00
static int nextEvent(lua_State* L) {
Event event;
2016-11-29 06:59:27 +00:00
if (!lovrEventPoll(&event)) {
2016-11-29 06:59:27 +00:00
return 0;
}
2018-07-05 03:11:52 +00:00
lua_pushstring(L, EventTypes[event.type]);
switch (event.type) {
case EVENT_QUIT:
if (event.data.quit.restart) {
lua_pushstring(L, "restart");
} else {
lua_pushnumber(L, event.data.quit.exitCode);
}
2016-11-29 06:59:27 +00:00
return 2;
case EVENT_FOCUS:
lua_pushboolean(L, event.data.focus.focused);
return 2;
case EVENT_MOUNT:
lua_pushboolean(L, event.data.mount.mounted);
return 2;
#ifndef EMSCRIPTEN
case EVENT_THREAD_ERROR:
2018-07-25 03:10:30 +00:00
luax_pushobject(L, event.data.threaderror.thread);
2018-02-17 17:49:24 +00:00
lua_pushstring(L, event.data.threaderror.error);
2018-03-12 17:37:45 +00:00
free((void*) event.data.threaderror.error);
2018-02-17 17:49:24 +00:00
return 3;
#endif
2018-02-17 17:49:24 +00:00
case EVENT_CONTROLLER_ADDED:
2018-07-25 03:10:30 +00:00
luax_pushobject(L, event.data.controlleradded.controller);
2018-02-26 08:59:03 +00:00
lovrRelease(event.data.controlleradded.controller);
2016-12-01 07:03:58 +00:00
return 2;
case EVENT_CONTROLLER_REMOVED:
2018-07-25 03:10:30 +00:00
luax_pushobject(L, event.data.controllerremoved.controller);
2018-02-26 08:59:03 +00:00
lovrRelease(event.data.controlleradded.controller);
2016-12-01 07:03:58 +00:00
return 2;
case EVENT_CONTROLLER_PRESSED:
2018-07-25 03:10:30 +00:00
luax_pushobject(L, event.data.controllerpressed.controller);
2018-07-05 03:11:52 +00:00
lua_pushstring(L, ControllerButtons[event.data.controllerpressed.button]);
return 3;
case EVENT_CONTROLLER_RELEASED:
2018-07-25 03:10:30 +00:00
luax_pushobject(L, event.data.controllerreleased.controller);
2018-07-05 03:11:52 +00:00
lua_pushstring(L, ControllerButtons[event.data.controllerpressed.button]);
return 3;
2016-11-29 06:59:27 +00:00
default:
return 1;
2016-11-29 06:59:27 +00:00
}
}
2016-08-10 06:28:17 +00:00
int l_lovrEventInit(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrEvent);
// Store nextEvent in the registry to avoid creating a closure every time we poll for events.
lua_pushcfunction(L, nextEvent);
pollRef = luaL_ref(L, LUA_REGISTRYINDEX);
2016-11-29 06:59:27 +00:00
lovrEventInit();
2016-08-10 06:28:17 +00:00
return 1;
}
2016-11-29 06:59:27 +00:00
int l_lovrEventClear(lua_State* L) {
lovrEventClear();
return 0;
}
2016-08-10 06:28:17 +00:00
int l_lovrEventPoll(lua_State* L) {
lua_rawgeti(L, LUA_REGISTRYINDEX, pollRef);
2016-11-29 06:59:27 +00:00
return 1;
}
int l_lovrEventPump(lua_State* L) {
lovrEventPump();
return 0;
}
int l_lovrEventPush(lua_State* L) {
2018-07-05 03:11:52 +00:00
EventType type = luaL_checkoption(L, 1, NULL, EventTypes);
2016-11-29 06:59:27 +00:00
EventData data;
switch (type) {
case EVENT_QUIT:
if (lua_type(L, 2) == LUA_TSTRING) {
data.quit.restart = lua_toboolean(L, 2);
} else {
data.quit.exitCode = luaL_optint(L, 2, 0);
}
2016-11-29 06:59:27 +00:00
break;
2016-12-01 07:03:58 +00:00
case EVENT_FOCUS:
data.focus.focused = lua_toboolean(L, 2);
break;
case EVENT_MOUNT:
data.mount.mounted = lua_toboolean(L, 2);
break;
#ifdef EMSCRIPTEN
case EVENT_THREAD_ERROR:
break;
#else
2018-02-17 17:49:24 +00:00
case EVENT_THREAD_ERROR:
data.threaderror.thread = luax_checktype(L, 2, Thread);
data.threaderror.error = luaL_checkstring(L, 3);
break;
#endif
2018-02-17 17:49:24 +00:00
2016-12-01 07:03:58 +00:00
case EVENT_CONTROLLER_ADDED:
data.controlleradded.controller = luax_checktype(L, 2, Controller);
break;
case EVENT_CONTROLLER_REMOVED:
data.controllerremoved.controller = luax_checktype(L, 2, Controller);
break;
case EVENT_CONTROLLER_PRESSED:
data.controllerpressed.controller = luax_checktype(L, 2, Controller);
2018-07-05 03:11:52 +00:00
data.controllerpressed.button = luaL_checkoption(L, 3, NULL, ControllerButtons);
break;
case EVENT_CONTROLLER_RELEASED:
data.controllerreleased.controller = luax_checktype(L, 2, Controller);
2018-07-05 03:11:52 +00:00
data.controllerreleased.button = luaL_checkoption(L, 3, NULL, ControllerButtons);
break;
2016-11-29 06:59:27 +00:00
}
Event event = { .type = type, .data = data };
lovrEventPush(event);
2016-08-10 06:28:17 +00:00
return 0;
}
int l_lovrEventQuit(lua_State* L) {
EventData data;
int argType = lua_type(L, 1);
if (argType == LUA_TSTRING && 0 == strcmp("restart", lua_tostring(L, 1))) {
data.quit.restart = true;
data.quit.exitCode = 0;
} else if (argType == LUA_TNUMBER || lua_isnoneornil(L, 1)) {
data.quit.restart = false;
data.quit.exitCode = luaL_optint(L, 1, 0);
} else {
return luaL_argerror (L, 1, "number, nil or the exact string 'restart' expected");
}
EventType type = EVENT_QUIT;
Event event = { .type = type, .data = data };
lovrEventPush(event);
2018-01-27 03:01:20 +00:00
return 0;
2016-08-10 06:28:17 +00:00
}
2017-03-11 11:08:07 +00:00
const luaL_Reg lovrEvent[] = {
{ "clear", l_lovrEventClear },
{ "poll", l_lovrEventPoll },
{ "pump", l_lovrEventPump },
{ "push", l_lovrEventPush },
{ "quit", l_lovrEventQuit },
{ NULL, NULL }
};