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 "data/blob.h"
#include "event/event.h"
#include "graphics/mesh.h"
#include "math/math.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);
Blob* luax_readblob(lua_State* L, int index, const char* debug);
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;
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) {
Event event;
@ -21,7 +68,11 @@ static int nextEvent(lua_State* L) {
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) {
case EVENT_QUIT:
@ -57,6 +108,12 @@ static int nextEvent(lua_State* L) {
lua_pushstring(L, ControllerButtons[event.data.controller.button]);
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:
return 1;
}
@ -90,47 +147,15 @@ int l_lovrEventPump(lua_State* L) {
}
int l_lovrEventPush(lua_State* L) {
EventType type = luaL_checkoption(L, 1, NULL, EventTypes);
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);
}
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;
CustomEvent eventData;
const char* name = luaL_checkstring(L, 1);
strncpy(eventData.name, name, MAX_EVENT_NAME_LENGTH - 1);
eventData.count = MIN(lua_gettop(L) - 1, 4);
for (int i = 0; i < eventData.count; i++) {
luax_checkvariant(L, 2 + i, &eventData.data[i]);
}
Event event = { .type = type, .data = data };
lovrEventPush(event);
lovrEventPush((Event) { .type = EVENT_CUSTOM, .data.custom = eventData });
return 0;
}

View File

@ -1,53 +1,6 @@
#include "api.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) {
switch (lua_type(L, index)) {
case LUA_TNONE:

View File

@ -7,6 +7,8 @@
#pragma once
#define MAX_EVENT_NAME_LENGTH 32
typedef enum {
EVENT_QUIT,
EVENT_FOCUS,
@ -15,9 +17,32 @@ typedef enum {
EVENT_CONTROLLER_ADDED,
EVENT_CONTROLLER_REMOVED,
EVENT_CONTROLLER_PRESSED,
EVENT_CONTROLLER_RELEASED
EVENT_CONTROLLER_RELEASED,
EVENT_CUSTOM
} 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 {
bool restart;
int exitCode;
@ -39,6 +64,12 @@ typedef struct {
ControllerButton button;
} ControllerEvent;
typedef struct {
char name[MAX_EVENT_NAME_LENGTH];
Variant data[4];
int count;
} CustomEvent;
typedef union {
QuitEvent quit;
BoolEvent boolean;
@ -46,6 +77,7 @@ typedef union {
ThreadEvent thread;
#endif
ControllerEvent controller;
CustomEvent custom;
} EventData;
typedef struct {

View File

@ -1,3 +1,4 @@
#include "event/event.h"
#include "util.h"
#include "lib/tinycthread/tinycthread.h"
#include "lib/vec/vec.h"
@ -6,36 +7,14 @@
#pragma once
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 {
struct Channel {
Ref ref;
mtx_t lock;
cnd_t cond;
vec_variant_t messages;
uint64_t sent;
uint64_t received;
} Channel;
};
Channel* lovrChannelCreate();
void lovrChannelDestroy(void* ref);

View File

@ -1,4 +1,5 @@
#include "thread/thread.h"
#include "thread/channel.h"
#include <stdlib.h>
static ThreadState state;

View File

@ -1,4 +1,3 @@
#include "thread/channel.h"
#include "util.h"
#include "lib/tinycthread/tinycthread.h"
#include "lib/map/map.h"
@ -6,6 +5,8 @@
#pragma once
typedef struct Channel Channel;
typedef struct {
bool initialized;
map_void_t channels;
@ -23,7 +24,7 @@ typedef struct {
void lovrThreadInit();
void lovrThreadDeinit();
Channel* lovrThreadGetChannel(const char* name);
struct Channel* lovrThreadGetChannel(const char* name);
Thread* lovrThreadCreate(int (*runner)(void*), const char* body);
void lovrThreadDestroy(void* ref);