Make custom events work;

This commit is contained in:
bjorn 2018-07-26 14:02:54 -07:00
parent 156c0cde5d
commit 9e494cae46
7 changed files with 108 additions and 114 deletions

View File

@ -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);

View File

@ -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;
} }

View File

@ -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:

View File

@ -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 {

View File

@ -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);

View File

@ -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;

View File

@ -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);