Skip to content

Commit 25c11a6

Browse files
committed
Experiment with automatic async function wrapping;
1 parent fb2ba8a commit 25c11a6

File tree

6 files changed

+55
-9
lines changed

6 files changed

+55
-9
lines changed

src/api/api.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,33 @@ void luax_registerloader(lua_State* L, lua_CFunction loader, int index) {
314314
lua_pop(L, 1);
315315
}
316316

317+
static int luax_wrapasync(lua_State* L) {
318+
if (luax_gettask(L)) {
319+
int n = lua_gettop(L);
320+
lua_pushvalue(L, lua_upvalueindex(1));
321+
lua_insert(L, 1);
322+
return luax_callthread(L, n);
323+
} else {
324+
lua_CFunction function = lua_tocfunction(L, lua_upvalueindex(1));
325+
return function(L);
326+
}
327+
}
328+
329+
void _luax_registerasync(lua_State* L, const char* name, const char** methods) {
330+
luaL_getmetatable(L, name);
331+
332+
if (lua_istable(L, -1)) {
333+
while (*methods) {
334+
const char* method = *methods++;
335+
lua_getfield(L, -1, method);
336+
lua_pushcclosure(L, luax_wrapasync, 1);
337+
lua_setfield(L, -2, method);
338+
}
339+
}
340+
341+
lua_pop(L, 1);
342+
}
343+
317344
int luax_resume(lua_State* T, int n) {
318345
#if LUA_VERSION_NUM >= 504
319346
int results;

src/api/api.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ typedef struct {
104104
#endif
105105

106106
#define luax_registertype(L, T) _luax_registertype(L, T_ ## T, #T, lovr ## T ## Destroy, lovr ## T)
107+
#define luax_registerasync(L, T) _luax_registerasync(L, #T, lovr ## T ## Async)
107108
#define luax_totype(L, i, T) (T*) _luax_totype(L, i, T_ ## T)
108109
#define luax_checktype(L, i, T) (T*) _luax_checktype(L, i, T_ ## T)
109110
#define luax_pushtype(L, T, o) _luax_pushtype(L, T_ ## T, o)
@@ -124,6 +125,7 @@ int luax_typeerror(lua_State* L, int index, const char* expected);
124125
void _luax_pushtype(lua_State* L, int type, void* object);
125126
int _luax_checkenum(lua_State* L, int index, const StringEntry* map, const char* fallback, const char* label);
126127
void luax_registerloader(lua_State* L, int (*loader)(lua_State* L), int index);
128+
void _luax_registerasync(lua_State* L, const char* type, const char** methods);
127129
int luax_resume(lua_State* T, int n);
128130
int luax_loadbufferx(lua_State* L, const char* buffer, size_t size, const char* name, const char* mode);
129131
void luax_vthrow(void* L, const char* format, va_list args);
@@ -205,5 +207,10 @@ struct Shape* luax_newterrainshape(lua_State* L, int index);
205207

206208
#ifndef LOVR_DISABLE_TASK
207209
#include "task/task.h"
210+
Task* luax_gettask(lua_State* L);
208211
int luax_runasync(lua_State* L, fn_task* fn, fn_continuation* continuation, void* context);
209212
#endif
213+
214+
#ifndef LOVR_DISABLE_THREAD
215+
int luax_callthread(lua_State* L, int n);
216+
#endif

src/api/l_physics.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,8 @@ extern const luaL_Reg lovrDistanceJoint[];
343343
extern const luaL_Reg lovrHingeJoint[];
344344
extern const luaL_Reg lovrSliderJoint[];
345345

346+
extern const char* lovrWorldAsync[];
347+
346348
static void luax_unref(void* object, uintptr_t userdata) {
347349
if (!userdata) return;
348350
lua_State* L = (lua_State*) userdata;
@@ -370,6 +372,7 @@ int luaopen_lovr_physics(lua_State* L) {
370372
luax_registertype(L, DistanceJoint);
371373
luax_registertype(L, HingeJoint);
372374
luax_registertype(L, SliderJoint);
375+
luax_registerasync(L, World);
373376
lovrPhysicsInit(luax_unref);
374377
luax_atexit(L, lovrPhysicsDestroy);
375378
return 1;

src/api/l_physics_world.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,3 +708,8 @@ const luaL_Reg lovrWorld[] = {
708708

709709
{ NULL, NULL }
710710
};
711+
712+
const char* lovrWorldAsync[] = {
713+
"raycast",
714+
NULL
715+
};

src/api/l_task.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <stdlib.h>
66
#include <string.h>
77

8-
static Task* luax_gettask(lua_State* L) {
8+
Task* luax_gettask(lua_State* L) {
99
lua_getfield(L, LUA_REGISTRYINDEX, "_lovrtasks");
1010
if (lua_isnil(L, -1)) return lua_pop(L, 1), NULL;
1111
lua_pushthread(L);

src/api/l_thread.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ static int writer(lua_State* L, const void* data, size_t size, void* userdata) {
210210
return 0;
211211
}
212212

213-
static int l_lovrThreadRun(lua_State* L) {
213+
int luax_callthread(lua_State* L, int n) {
214214
RunContext* context = contextPool;
215215

216216
if (context) {
@@ -225,16 +225,18 @@ static int l_lovrThreadRun(lua_State* L) {
225225
arr_init(&context->code);
226226
}
227227

228-
if (lua_iscfunction(L, 1)) {
229-
context->function = lua_tocfunction(L, 1);
228+
int function = lua_gettop(L) - n;
229+
230+
if (lua_iscfunction(L, function)) {
231+
context->function = lua_tocfunction(L, function);
230232
} else {
231-
luaL_checktype(L, 1, LUA_TFUNCTION);
233+
luaL_checktype(L, function, LUA_TFUNCTION);
232234
lua_getfield(L, LUA_REGISTRYINDEX, "_lovrbytecode");
233-
lua_pushvalue(L, 1);
235+
lua_pushvalue(L, function);
234236
lua_rawget(L, -2);
235237

236238
if (lua_isnil(L, -1)) {
237-
lua_pushvalue(L, 1);
239+
lua_pushvalue(L, function);
238240
luax_check(L, !lua_dump(L, writer, context), "Failed to dump function to bytecode");
239241
lua_pushlstring(L, context->code.data, context->code.length);
240242
lua_rawset(L, -4);
@@ -247,8 +249,6 @@ static int l_lovrThreadRun(lua_State* L) {
247249
}
248250
}
249251

250-
int n = lua_gettop(L) - 1;
251-
252252
if (n > 0) {
253253
context->argumentCount = n;
254254
context->arguments = lovrMalloc(n * sizeof(Variant));
@@ -260,6 +260,10 @@ static int l_lovrThreadRun(lua_State* L) {
260260
return luax_runasync(L, luax_runlua, luax_pushresults, context);
261261
}
262262

263+
static int l_lovrThreadRun(lua_State* L) {
264+
return luax_callthread(L, lua_gettop(L) - 1);
265+
}
266+
263267
static const luaL_Reg lovrThreadModule[] = {
264268
{ "newThread", l_lovrThreadNewThread },
265269
{ "newChannel", l_lovrThreadNewChannel },

0 commit comments

Comments
 (0)