mirror of https://github.com/bjornbytes/lovr.git
Make custom events work;
This commit is contained in:
parent
156c0cde5d
commit
9e494cae46
|
@ -1,5 +1,6 @@
|
||||||
#include "luax.h"
|
#include "luax.h"
|
||||||
#include "data/blob.h"
|
#include "data/blob.h"
|
||||||
|
#include "event/event.h"
|
||||||
#include "graphics/mesh.h"
|
#include "graphics/mesh.h"
|
||||||
#include "math/math.h"
|
#include "math/math.h"
|
||||||
#include "math/randomGenerator.h"
|
#include "math/randomGenerator.h"
|
||||||
|
@ -111,3 +112,5 @@ void luax_setvertex(lua_State* L, int index, VertexPointer* vertex, VertexFormat
|
||||||
int luax_readtransform(lua_State* L, int index, mat4 transform, int scaleComponents);
|
int luax_readtransform(lua_State* L, int index, mat4 transform, int scaleComponents);
|
||||||
Blob* luax_readblob(lua_State* L, int index, const char* debug);
|
Blob* luax_readblob(lua_State* L, int index, const char* debug);
|
||||||
Seed luax_checkrandomseed(lua_State* L, int index);
|
Seed luax_checkrandomseed(lua_State* L, int index);
|
||||||
|
void luax_checkvariant(lua_State* L, int index, Variant* variant);
|
||||||
|
int luax_pushvariant(lua_State* L, Variant* variant);
|
||||||
|
|
105
src/api/event.c
105
src/api/event.c
|
@ -14,6 +14,53 @@ const char* EventTypes[] = {
|
||||||
|
|
||||||
static _Thread_local int pollRef;
|
static _Thread_local int pollRef;
|
||||||
|
|
||||||
|
void luax_checkvariant(lua_State* L, int index, Variant* variant) {
|
||||||
|
int type = lua_type(L, index);
|
||||||
|
switch (type) {
|
||||||
|
case LUA_TNIL:
|
||||||
|
variant->type = TYPE_NIL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LUA_TBOOLEAN:
|
||||||
|
variant->type = TYPE_BOOLEAN;
|
||||||
|
variant->value.boolean = lua_toboolean(L, index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LUA_TNUMBER:
|
||||||
|
variant->type = TYPE_NUMBER;
|
||||||
|
variant->value.number = lua_tonumber(L, index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LUA_TSTRING:
|
||||||
|
variant->type = TYPE_STRING;
|
||||||
|
size_t length;
|
||||||
|
const char* string = lua_tolstring(L, index, &length);
|
||||||
|
variant->value.string = malloc(length + 1);
|
||||||
|
strcpy(variant->value.string, string);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LUA_TUSERDATA:
|
||||||
|
variant->type = TYPE_OBJECT;
|
||||||
|
variant->value.ref = lua_touserdata(L, index);
|
||||||
|
lovrRetain(variant->value.ref);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
lovrThrow("Bad type for Channel:push: %s", lua_typename(L, type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int luax_pushvariant(lua_State* L, Variant* variant) {
|
||||||
|
switch (variant->type) {
|
||||||
|
case TYPE_NIL: lua_pushnil(L); return 1;
|
||||||
|
case TYPE_BOOLEAN: lua_pushboolean(L, variant->value.boolean); return 1;
|
||||||
|
case TYPE_NUMBER: lua_pushnumber(L, variant->value.number); return 1;
|
||||||
|
case TYPE_STRING: lua_pushstring(L, variant->value.string); free(variant->value.string); return 1;
|
||||||
|
case TYPE_OBJECT: luax_pushobject(L, variant->value.ref); lovrRelease(variant->value.ref); return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int nextEvent(lua_State* L) {
|
static int nextEvent(lua_State* L) {
|
||||||
Event event;
|
Event event;
|
||||||
|
|
||||||
|
@ -21,7 +68,11 @@ static int nextEvent(lua_State* L) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushstring(L, EventTypes[event.type]);
|
if (event.type == EVENT_CUSTOM) {
|
||||||
|
lua_pushstring(L, event.data.custom.name);
|
||||||
|
} else {
|
||||||
|
lua_pushstring(L, EventTypes[event.type]);
|
||||||
|
}
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case EVENT_QUIT:
|
case EVENT_QUIT:
|
||||||
|
@ -57,6 +108,12 @@ static int nextEvent(lua_State* L) {
|
||||||
lua_pushstring(L, ControllerButtons[event.data.controller.button]);
|
lua_pushstring(L, ControllerButtons[event.data.controller.button]);
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
|
case EVENT_CUSTOM:
|
||||||
|
for (int i = 0; i < event.data.custom.count; i++) {
|
||||||
|
luax_pushvariant(L, &event.data.custom.data[i]);
|
||||||
|
}
|
||||||
|
return event.data.custom.count + 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -90,47 +147,15 @@ int l_lovrEventPump(lua_State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int l_lovrEventPush(lua_State* L) {
|
int l_lovrEventPush(lua_State* L) {
|
||||||
EventType type = luaL_checkoption(L, 1, NULL, EventTypes);
|
CustomEvent eventData;
|
||||||
EventData data;
|
const char* name = luaL_checkstring(L, 1);
|
||||||
|
strncpy(eventData.name, name, MAX_EVENT_NAME_LENGTH - 1);
|
||||||
switch (type) {
|
eventData.count = MIN(lua_gettop(L) - 1, 4);
|
||||||
case EVENT_QUIT:
|
for (int i = 0; i < eventData.count; i++) {
|
||||||
if (lua_type(L, 2) == LUA_TSTRING) {
|
luax_checkvariant(L, 2 + i, &eventData.data[i]);
|
||||||
data.quit.restart = lua_toboolean(L, 2);
|
|
||||||
} else {
|
|
||||||
data.quit.exitCode = luaL_optint(L, 2, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EVENT_FOCUS:
|
|
||||||
case EVENT_MOUNT:
|
|
||||||
data.boolean.value = lua_toboolean(L, 2);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
|
||||||
case EVENT_THREAD_ERROR:
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
case EVENT_THREAD_ERROR:
|
|
||||||
data.thread.thread = luax_checktype(L, 2, Thread);
|
|
||||||
data.thread.error = luaL_checkstring(L, 3);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case EVENT_CONTROLLER_ADDED:
|
|
||||||
case EVENT_CONTROLLER_REMOVED:
|
|
||||||
data.controller.controller = luax_checktype(L, 2, Controller);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EVENT_CONTROLLER_PRESSED:
|
|
||||||
case EVENT_CONTROLLER_RELEASED:
|
|
||||||
data.controller.controller = luax_checktype(L, 2, Controller);
|
|
||||||
data.controller.button = luaL_checkoption(L, 3, NULL, ControllerButtons);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Event event = { .type = type, .data = data };
|
lovrEventPush((Event) { .type = EVENT_CUSTOM, .data.custom = eventData });
|
||||||
lovrEventPush(event);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,53 +1,6 @@
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
#include "thread/channel.h"
|
#include "thread/channel.h"
|
||||||
|
|
||||||
static void luax_checkvariant(lua_State* L, int index, Variant* variant) {
|
|
||||||
int type = lua_type(L, index);
|
|
||||||
switch (type) {
|
|
||||||
case LUA_TNIL:
|
|
||||||
variant->type = TYPE_NIL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TBOOLEAN:
|
|
||||||
variant->type = TYPE_BOOLEAN;
|
|
||||||
variant->value.boolean = lua_toboolean(L, index);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TNUMBER:
|
|
||||||
variant->type = TYPE_NUMBER;
|
|
||||||
variant->value.number = lua_tonumber(L, index);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TSTRING:
|
|
||||||
variant->type = TYPE_STRING;
|
|
||||||
size_t length;
|
|
||||||
const char* string = lua_tolstring(L, index, &length);
|
|
||||||
variant->value.string = malloc(length + 1);
|
|
||||||
strcpy(variant->value.string, string);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TUSERDATA:
|
|
||||||
variant->type = TYPE_OBJECT;
|
|
||||||
variant->value.ref = lua_touserdata(L, index);
|
|
||||||
lovrRetain(variant->value.ref);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
lovrThrow("Bad type for Channel:push: %s", lua_typename(L, type));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int luax_pushvariant(lua_State* L, Variant* variant) {
|
|
||||||
switch (variant->type) {
|
|
||||||
case TYPE_NIL: lua_pushnil(L); return 1;
|
|
||||||
case TYPE_BOOLEAN: lua_pushboolean(L, variant->value.boolean); return 1;
|
|
||||||
case TYPE_NUMBER: lua_pushnumber(L, variant->value.number); return 1;
|
|
||||||
case TYPE_STRING: lua_pushstring(L, variant->value.string); free(variant->value.string); return 1;
|
|
||||||
case TYPE_OBJECT: luax_pushobject(L, variant->value.ref); lovrRelease(variant->value.ref); return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void luax_checktimeout(lua_State* L, int index, double* timeout) {
|
static void luax_checktimeout(lua_State* L, int index, double* timeout) {
|
||||||
switch (lua_type(L, index)) {
|
switch (lua_type(L, index)) {
|
||||||
case LUA_TNONE:
|
case LUA_TNONE:
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define MAX_EVENT_NAME_LENGTH 32
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EVENT_QUIT,
|
EVENT_QUIT,
|
||||||
EVENT_FOCUS,
|
EVENT_FOCUS,
|
||||||
|
@ -15,9 +17,32 @@ typedef enum {
|
||||||
EVENT_CONTROLLER_ADDED,
|
EVENT_CONTROLLER_ADDED,
|
||||||
EVENT_CONTROLLER_REMOVED,
|
EVENT_CONTROLLER_REMOVED,
|
||||||
EVENT_CONTROLLER_PRESSED,
|
EVENT_CONTROLLER_PRESSED,
|
||||||
EVENT_CONTROLLER_RELEASED
|
EVENT_CONTROLLER_RELEASED,
|
||||||
|
EVENT_CUSTOM
|
||||||
} EventType;
|
} EventType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TYPE_NIL,
|
||||||
|
TYPE_BOOLEAN,
|
||||||
|
TYPE_NUMBER,
|
||||||
|
TYPE_STRING,
|
||||||
|
TYPE_OBJECT
|
||||||
|
} VariantType;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
bool boolean;
|
||||||
|
double number;
|
||||||
|
char* string;
|
||||||
|
Ref* ref;
|
||||||
|
} VariantValue;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
VariantType type;
|
||||||
|
VariantValue value;
|
||||||
|
} Variant;
|
||||||
|
|
||||||
|
typedef vec_t(Variant) vec_variant_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool restart;
|
bool restart;
|
||||||
int exitCode;
|
int exitCode;
|
||||||
|
@ -39,6 +64,12 @@ typedef struct {
|
||||||
ControllerButton button;
|
ControllerButton button;
|
||||||
} ControllerEvent;
|
} ControllerEvent;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[MAX_EVENT_NAME_LENGTH];
|
||||||
|
Variant data[4];
|
||||||
|
int count;
|
||||||
|
} CustomEvent;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
QuitEvent quit;
|
QuitEvent quit;
|
||||||
BoolEvent boolean;
|
BoolEvent boolean;
|
||||||
|
@ -46,6 +77,7 @@ typedef union {
|
||||||
ThreadEvent thread;
|
ThreadEvent thread;
|
||||||
#endif
|
#endif
|
||||||
ControllerEvent controller;
|
ControllerEvent controller;
|
||||||
|
CustomEvent custom;
|
||||||
} EventData;
|
} EventData;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "event/event.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "lib/tinycthread/tinycthread.h"
|
#include "lib/tinycthread/tinycthread.h"
|
||||||
#include "lib/vec/vec.h"
|
#include "lib/vec/vec.h"
|
||||||
|
@ -6,36 +7,14 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef enum {
|
struct Channel {
|
||||||
TYPE_NIL,
|
|
||||||
TYPE_BOOLEAN,
|
|
||||||
TYPE_NUMBER,
|
|
||||||
TYPE_STRING,
|
|
||||||
TYPE_OBJECT
|
|
||||||
} VariantType;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
bool boolean;
|
|
||||||
double number;
|
|
||||||
char* string;
|
|
||||||
Ref* ref;
|
|
||||||
} VariantValue;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
VariantType type;
|
|
||||||
VariantValue value;
|
|
||||||
} Variant;
|
|
||||||
|
|
||||||
typedef vec_t(Variant) vec_variant_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Ref ref;
|
Ref ref;
|
||||||
mtx_t lock;
|
mtx_t lock;
|
||||||
cnd_t cond;
|
cnd_t cond;
|
||||||
vec_variant_t messages;
|
vec_variant_t messages;
|
||||||
uint64_t sent;
|
uint64_t sent;
|
||||||
uint64_t received;
|
uint64_t received;
|
||||||
} Channel;
|
};
|
||||||
|
|
||||||
Channel* lovrChannelCreate();
|
Channel* lovrChannelCreate();
|
||||||
void lovrChannelDestroy(void* ref);
|
void lovrChannelDestroy(void* ref);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "thread/thread.h"
|
#include "thread/thread.h"
|
||||||
|
#include "thread/channel.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
static ThreadState state;
|
static ThreadState state;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#include "thread/channel.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "lib/tinycthread/tinycthread.h"
|
#include "lib/tinycthread/tinycthread.h"
|
||||||
#include "lib/map/map.h"
|
#include "lib/map/map.h"
|
||||||
|
@ -6,6 +5,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct Channel Channel;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool initialized;
|
bool initialized;
|
||||||
map_void_t channels;
|
map_void_t channels;
|
||||||
|
@ -23,7 +24,7 @@ typedef struct {
|
||||||
|
|
||||||
void lovrThreadInit();
|
void lovrThreadInit();
|
||||||
void lovrThreadDeinit();
|
void lovrThreadDeinit();
|
||||||
Channel* lovrThreadGetChannel(const char* name);
|
struct Channel* lovrThreadGetChannel(const char* name);
|
||||||
|
|
||||||
Thread* lovrThreadCreate(int (*runner)(void*), const char* body);
|
Thread* lovrThreadCreate(int (*runner)(void*), const char* body);
|
||||||
void lovrThreadDestroy(void* ref);
|
void lovrThreadDestroy(void* ref);
|
||||||
|
|
Loading…
Reference in New Issue