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 "lovr.h"
|
||||
#include "glfw.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void lovrEventPoll() {
|
||||
glfwPollEvents();
|
||||
static EventState state;
|
||||
|
||||
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) {
|
||||
lovrDestroy(exitCode);
|
||||
void lovrEventInit() {
|
||||
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();
|
||||
void lovrEventQuit(int exitCode);
|
||||
#include <vendor/vec/vec.h>
|
||||
|
||||
#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 <stdlib.h>
|
||||
|
||||
void initGlfw(GLFWerrorfun onError, GLFWwindowclosefun onClose, void* userPointer) {
|
||||
static void onError(int code, const char* description) {
|
||||
error(description);
|
||||
}
|
||||
|
||||
void initGlfw() {
|
||||
glfwSetErrorCallback(onError);
|
||||
|
||||
if (!glfwInit()) {
|
||||
|
@ -14,7 +18,6 @@ void initGlfw(GLFWerrorfun onError, GLFWwindowclosefun onClose, void* userPointe
|
|||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
//glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
|
||||
window = glfwCreateWindow(800, 600, "Window", NULL, NULL);
|
||||
|
||||
|
@ -23,8 +26,6 @@ void initGlfw(GLFWerrorfun onError, GLFWwindowclosefun onClose, void* userPointe
|
|||
error("Could not create window");
|
||||
}
|
||||
|
||||
glfwSetWindowCloseCallback(window, onClose);
|
||||
glfwSetWindowUserPointer(window, userPointer);
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
|
||||
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/headset.h"
|
||||
#include "lovr/timer.h"
|
||||
#include "glfw.h"
|
||||
#include "util.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
|
||||
initGlfw(lovrOnGlfwError, lovrOnClose, L);
|
||||
if (lua_isfunction(L, -1)) {
|
||||
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
|
||||
lua_newtable(L);
|
||||
|
@ -71,10 +85,24 @@ void lovrInit(lua_State* L, int argc, char** argv) {
|
|||
|
||||
"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() "
|
||||
" if lovr.load then lovr.load() end "
|
||||
" 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() "
|
||||
" if lovr.update then lovr.update(dt) end "
|
||||
" lovr.graphics.clear() "
|
||||
|
@ -93,7 +121,7 @@ void lovrInit(lua_State* L, int argc, char** argv) {
|
|||
|
||||
"function lovr.errhand(message, layer) "
|
||||
" 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 "
|
||||
|
||||
"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);
|
||||
}
|
||||
|
||||
lua_atpanic(L, lovrOnLuaError);
|
||||
lua_atpanic(L, handleLuaError);
|
||||
}
|
||||
|
||||
void lovrDestroy(int exitCode) {
|
||||
|
@ -119,44 +147,9 @@ void lovrRun(lua_State* L) {
|
|||
// lovr.run()
|
||||
lua_getglobal(L, "lovr");
|
||||
lua_getfield(L, -1, "run");
|
||||
lua_call(L, 0, 0);
|
||||
}
|
||||
|
||||
int lovrOnLuaError(lua_State* L) {
|
||||
const char* message = luaL_checkstring(L, -1);
|
||||
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);
|
||||
}
|
||||
}
|
||||
lua_call(L, 0, 1);
|
||||
|
||||
// Exit with return value from lovr.run
|
||||
int exitCode = luaL_optint(L, -1, 0);
|
||||
lovrDestroy(exitCode);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "glfw.h"
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
|
@ -7,5 +6,3 @@ void lovrInit(lua_State* L, int argc, char** argv);
|
|||
void lovrDestroy(int exitCode);
|
||||
void lovrRun(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 "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[] = {
|
||||
{ "clear", l_lovrEventClear },
|
||||
{ "poll", l_lovrEventPoll },
|
||||
{ "pump", l_lovrEventPump },
|
||||
{ "push", l_lovrEventPush },
|
||||
{ "quit", l_lovrEventQuit },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
@ -10,16 +32,46 @@ const luaL_Reg lovrEvent[] = {
|
|||
int l_lovrEventInit(lua_State* L) {
|
||||
lua_newtable(L);
|
||||
luaL_register(L, NULL, lovrEvent);
|
||||
map_init(&EventTypes);
|
||||
map_set(&EventTypes, "quit", EVENT_QUIT);
|
||||
lovrEventInit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int l_lovrEventClear(lua_State* L) {
|
||||
lovrEventClear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int l_lovrEventQuit(lua_State* L) {
|
||||
int exitCode = luaL_optint(L, 1, 0);
|
||||
lovrEventQuit(exitCode);
|
||||
return 0;
|
||||
lua_settop(L, 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 <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
|
||||
map_int_t EventTypes;
|
||||
|
||||
extern const luaL_Reg lovrEvent[];
|
||||
int l_lovrEventInit(lua_State* L);
|
||||
int l_lovrEventClear(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);
|
||||
|
|
Loading…
Reference in New Issue