mirror of https://github.com/bjornbytes/lovr.git
Overhaul lovr.event;
This commit is contained in:
parent
40eeeabcff
commit
e3c1dcfa54
|
@ -1,11 +1,53 @@
|
||||||
#include "event/event.h"
|
#include "event/event.h"
|
||||||
#include "lovr.h"
|
|
||||||
#include "glfw.h"
|
#include "glfw.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
void lovrEventPoll() {
|
static EventState state;
|
||||||
glfwPollEvents();
|
|
||||||
|
static void onClose(GLFWwindow* _window) {
|
||||||
|
if (_window == window) {
|
||||||
|
EventType type = EVENT_QUIT;
|
||||||
|
EventData data = { .quit = { 0 } };
|
||||||
|
Event event = { .type = type, .data = data };
|
||||||
|
lovrEventPush(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrEventQuit(int exitCode) {
|
void lovrEventInit() {
|
||||||
lovrDestroy(exitCode);
|
vec_init(&state.pumps);
|
||||||
|
vec_init(&state.events);
|
||||||
|
lovrEventAddPump(glfwPollEvents);
|
||||||
|
glfwSetWindowCloseCallback(window, onClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lovrEventDestroy() {
|
||||||
|
vec_deinit(&state.pumps);
|
||||||
|
vec_deinit(&state.events);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lovrEventAddPump(EventPump pump) {
|
||||||
|
vec_push(&state.pumps, pump);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lovrEventPump() {
|
||||||
|
int i; EventPump pump;
|
||||||
|
vec_foreach(&state.pumps, pump, i) {
|
||||||
|
pump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lovrEventPush(Event event) {
|
||||||
|
vec_insert(&state.events, 0, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
Event* lovrEventPoll() {
|
||||||
|
if (state.events.length == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &vec_pop(&state.events);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lovrEventClear() {
|
||||||
|
vec_clear(&state.events);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,41 @@
|
||||||
void lovrEventPoll();
|
#include <vendor/vec/vec.h>
|
||||||
void lovrEventQuit(int exitCode);
|
|
||||||
|
#ifndef LOVR_EVENT_TYPES
|
||||||
|
#define LOVR_EVENT_TYPES
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
EVENT_QUIT
|
||||||
|
} EventType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int exitCode;
|
||||||
|
} QuitEvent;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
QuitEvent quit;
|
||||||
|
} EventData;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EventType type;
|
||||||
|
EventData data;
|
||||||
|
} Event;
|
||||||
|
|
||||||
|
typedef void (*EventPump)(void);
|
||||||
|
|
||||||
|
typedef vec_t(EventPump) vec_pump_t;
|
||||||
|
typedef vec_t(Event) vec_event_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
vec_pump_t pumps;
|
||||||
|
vec_event_t events;
|
||||||
|
} EventState;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void lovrEventInit();
|
||||||
|
void lovrEventDestroy();
|
||||||
|
void lovrEventAddPump(void (*pump)(void));
|
||||||
|
void lovrEventPump();
|
||||||
|
void lovrEventPush(Event event);
|
||||||
|
Event* lovrEventPoll();
|
||||||
|
void lovrEventClear();
|
||||||
|
|
|
@ -3,7 +3,11 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void initGlfw(GLFWerrorfun onError, GLFWwindowclosefun onClose, void* userPointer) {
|
static void onError(int code, const char* description) {
|
||||||
|
error(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initGlfw() {
|
||||||
glfwSetErrorCallback(onError);
|
glfwSetErrorCallback(onError);
|
||||||
|
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
|
@ -14,7 +18,6 @@ void initGlfw(GLFWerrorfun onError, GLFWwindowclosefun onClose, void* userPointe
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
//glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
|
||||||
|
|
||||||
window = glfwCreateWindow(800, 600, "Window", NULL, NULL);
|
window = glfwCreateWindow(800, 600, "Window", NULL, NULL);
|
||||||
|
|
||||||
|
@ -23,8 +26,6 @@ void initGlfw(GLFWerrorfun onError, GLFWwindowclosefun onClose, void* userPointe
|
||||||
error("Could not create window");
|
error("Could not create window");
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwSetWindowCloseCallback(window, onClose);
|
|
||||||
glfwSetWindowUserPointer(window, userPointer);
|
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -8,4 +8,4 @@
|
||||||
|
|
||||||
GLFWwindow* window;
|
GLFWwindow* window;
|
||||||
|
|
||||||
void initGlfw(GLFWerrorfun onError, GLFWwindowclosefun onClose, void* userPointer);
|
void initGlfw();
|
||||||
|
|
85
src/lovr.c
85
src/lovr.c
|
@ -4,13 +4,27 @@
|
||||||
#include "lovr/graphics.h"
|
#include "lovr/graphics.h"
|
||||||
#include "lovr/headset.h"
|
#include "lovr/headset.h"
|
||||||
#include "lovr/timer.h"
|
#include "lovr/timer.h"
|
||||||
|
#include "glfw.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void lovrInit(lua_State* L, int argc, char** argv) {
|
static int handleLuaError(lua_State* L) {
|
||||||
|
const char* message = luaL_checkstring(L, -1);
|
||||||
|
lua_getglobal(L, "lovr");
|
||||||
|
lua_getfield(L, -1, "errhand");
|
||||||
|
|
||||||
// Set up GLFW
|
if (lua_isfunction(L, -1)) {
|
||||||
initGlfw(lovrOnGlfwError, lovrOnClose, L);
|
lua_pushstring(L, message);
|
||||||
|
lua_call(L, 1, 0);
|
||||||
|
} else {
|
||||||
|
error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lovrInit(lua_State* L, int argc, char** argv) {
|
||||||
|
initGlfw();
|
||||||
|
|
||||||
// arg global
|
// arg global
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
|
@ -71,10 +85,24 @@ void lovrInit(lua_State* L, int argc, char** argv) {
|
||||||
|
|
||||||
"lovr.filesystem.setIdentity(conf.identity or 'default') "
|
"lovr.filesystem.setIdentity(conf.identity or 'default') "
|
||||||
|
|
||||||
|
"lovr.handlers = setmetatable({ "
|
||||||
|
" quit = function() end "
|
||||||
|
"}, { "
|
||||||
|
" __index = function(self, event) "
|
||||||
|
" error('Unknown event: ', event) "
|
||||||
|
" end "
|
||||||
|
"}) "
|
||||||
|
|
||||||
"function lovr.run() "
|
"function lovr.run() "
|
||||||
" if lovr.load then lovr.load() end "
|
" if lovr.load then lovr.load() end "
|
||||||
" while true do "
|
" while true do "
|
||||||
" lovr.event.poll() "
|
" lovr.event.pump() "
|
||||||
|
" for name, a, b, c, d in lovr.event.poll() do "
|
||||||
|
" if name == 'quit' and (not lovr.quit or not lovr.quit()) then "
|
||||||
|
" return a "
|
||||||
|
" end "
|
||||||
|
" lovr.handlers[name](a, b, c, d) "
|
||||||
|
" end "
|
||||||
" local dt = lovr.timer.step() "
|
" local dt = lovr.timer.step() "
|
||||||
" if lovr.update then lovr.update(dt) end "
|
" if lovr.update then lovr.update(dt) end "
|
||||||
" lovr.graphics.clear() "
|
" lovr.graphics.clear() "
|
||||||
|
@ -93,7 +121,7 @@ void lovrInit(lua_State* L, int argc, char** argv) {
|
||||||
|
|
||||||
"function lovr.errhand(message, layer) "
|
"function lovr.errhand(message, layer) "
|
||||||
" local stackTrace = debug.traceback('Error: ' .. tostring(message), 1 + (layer or 1)) "
|
" local stackTrace = debug.traceback('Error: ' .. tostring(message), 1 + (layer or 1)) "
|
||||||
" print((stackTrace:gsub('\\n[^\\n]+$', ''))) "
|
" print((stackTrace:gsub('\\n[^\\n]+$', ''):gsub('stack traceback', 'Stack'))) "
|
||||||
"end "
|
"end "
|
||||||
|
|
||||||
"if lovr.filesystem.isFile('main.lua') then "
|
"if lovr.filesystem.isFile('main.lua') then "
|
||||||
|
@ -106,7 +134,7 @@ void lovrInit(lua_State* L, int argc, char** argv) {
|
||||||
error("Unable to bootstrap LOVR: %s", message);
|
error("Unable to bootstrap LOVR: %s", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_atpanic(L, lovrOnLuaError);
|
lua_atpanic(L, handleLuaError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrDestroy(int exitCode) {
|
void lovrDestroy(int exitCode) {
|
||||||
|
@ -119,44 +147,9 @@ void lovrRun(lua_State* L) {
|
||||||
// lovr.run()
|
// lovr.run()
|
||||||
lua_getglobal(L, "lovr");
|
lua_getglobal(L, "lovr");
|
||||||
lua_getfield(L, -1, "run");
|
lua_getfield(L, -1, "run");
|
||||||
lua_call(L, 0, 0);
|
lua_call(L, 0, 1);
|
||||||
}
|
|
||||||
|
// Exit with return value from lovr.run
|
||||||
int lovrOnLuaError(lua_State* L) {
|
int exitCode = luaL_optint(L, -1, 0);
|
||||||
const char* message = luaL_checkstring(L, -1);
|
lovrDestroy(exitCode);
|
||||||
lua_getglobal(L, "lovr");
|
|
||||||
lua_getfield(L, -1, "errhand");
|
|
||||||
|
|
||||||
if (lua_isfunction(L, -1)) {
|
|
||||||
lua_pushstring(L, message);
|
|
||||||
lua_call(L, 1, 0);
|
|
||||||
} else {
|
|
||||||
error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lovrOnGlfwError(int code, const char* description) {
|
|
||||||
error(description);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lovrOnClose(GLFWwindow* _window) {
|
|
||||||
if (_window == window) {
|
|
||||||
|
|
||||||
lua_State* L = (lua_State*) glfwGetWindowUserPointer(window);
|
|
||||||
|
|
||||||
// lovr.quit()
|
|
||||||
lua_getglobal(L, "lovr");
|
|
||||||
lua_getfield(L, -1, "quit");
|
|
||||||
|
|
||||||
if (!lua_isnil(L, -1)) {
|
|
||||||
lua_call(L, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glfwWindowShouldClose(window)) {
|
|
||||||
glfwDestroyWindow(window);
|
|
||||||
lovrDestroy(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#include "glfw.h"
|
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
|
@ -7,5 +6,3 @@ void lovrInit(lua_State* L, int argc, char** argv);
|
||||||
void lovrDestroy(int exitCode);
|
void lovrDestroy(int exitCode);
|
||||||
void lovrRun(lua_State* L);
|
void lovrRun(lua_State* L);
|
||||||
int lovrOnLuaError(lua_State* L);
|
int lovrOnLuaError(lua_State* L);
|
||||||
void lovrOnGlfwError(int code, const char* description);
|
|
||||||
void lovrOnClose(GLFWwindow* window);
|
|
||||||
|
|
|
@ -1,8 +1,30 @@
|
||||||
#include "lovr/event.h"
|
#include "lovr/event.h"
|
||||||
#include "event/event.h"
|
#include "event/event.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
static int nextEvent(lua_State* L) {
|
||||||
|
Event* event = lovrEventPoll();
|
||||||
|
|
||||||
|
if (!event) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event->type) {
|
||||||
|
case EVENT_QUIT:
|
||||||
|
lua_pushstring(L, "quit");
|
||||||
|
lua_pushnumber(L, event->data.quit.exitCode);
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const luaL_Reg lovrEvent[] = {
|
const luaL_Reg lovrEvent[] = {
|
||||||
|
{ "clear", l_lovrEventClear },
|
||||||
{ "poll", l_lovrEventPoll },
|
{ "poll", l_lovrEventPoll },
|
||||||
|
{ "pump", l_lovrEventPump },
|
||||||
|
{ "push", l_lovrEventPush },
|
||||||
{ "quit", l_lovrEventQuit },
|
{ "quit", l_lovrEventQuit },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
@ -10,16 +32,46 @@ const luaL_Reg lovrEvent[] = {
|
||||||
int l_lovrEventInit(lua_State* L) {
|
int l_lovrEventInit(lua_State* L) {
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
luaL_register(L, NULL, lovrEvent);
|
luaL_register(L, NULL, lovrEvent);
|
||||||
|
map_init(&EventTypes);
|
||||||
|
map_set(&EventTypes, "quit", EVENT_QUIT);
|
||||||
|
lovrEventInit();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int l_lovrEventClear(lua_State* L) {
|
||||||
|
lovrEventClear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int l_lovrEventPoll(lua_State* L) {
|
int l_lovrEventPoll(lua_State* L) {
|
||||||
lovrEventPoll();
|
lua_pushcclosure(L, nextEvent, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int l_lovrEventPump(lua_State* L) {
|
||||||
|
lovrEventPump();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int l_lovrEventPush(lua_State* L) {
|
||||||
|
EventType type = *(EventType*) luax_checkenum(L, 1, &EventTypes, "event type");
|
||||||
|
EventData data;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case EVENT_QUIT:
|
||||||
|
data.quit.exitCode = luaL_optint(L, 2, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Event event = { .type = type, .data = data };
|
||||||
|
lovrEventPush(event);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int l_lovrEventQuit(lua_State* L) {
|
int l_lovrEventQuit(lua_State* L) {
|
||||||
int exitCode = luaL_optint(L, 1, 0);
|
int exitCode = luaL_optint(L, 1, 0);
|
||||||
lovrEventQuit(exitCode);
|
lua_settop(L, 0);
|
||||||
return 0;
|
lua_pushliteral(L, "quit");
|
||||||
|
lua_pushinteger(L, exitCode);
|
||||||
|
return l_lovrEventPush(L);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
|
#include "vendor/map/map.h"
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
|
|
||||||
|
map_int_t EventTypes;
|
||||||
|
|
||||||
extern const luaL_Reg lovrEvent[];
|
extern const luaL_Reg lovrEvent[];
|
||||||
int l_lovrEventInit(lua_State* L);
|
int l_lovrEventInit(lua_State* L);
|
||||||
|
int l_lovrEventClear(lua_State* L);
|
||||||
int l_lovrEventPoll(lua_State* L);
|
int l_lovrEventPoll(lua_State* L);
|
||||||
|
int l_lovrEventPump(lua_State* L);
|
||||||
|
int l_lovrEventPush(lua_State* L);
|
||||||
int l_lovrEventQuit(lua_State* L);
|
int l_lovrEventQuit(lua_State* L);
|
||||||
|
|
Loading…
Reference in New Issue