mirror of https://github.com/bjornbytes/lovr.git
api: try new file naming convention; Tupfile: cleanup;
I assume full responsibility for any catastrophes this causes.
This commit is contained in:
parent
72328640b6
commit
c9b1f257bf
|
@ -345,8 +345,8 @@ if(LOVR_ENABLE_AUDIO)
|
||||||
src/modules/audio/source.c
|
src/modules/audio/source.c
|
||||||
src/modules/audio/microphone.c
|
src/modules/audio/microphone.c
|
||||||
src/api/l_audio.c
|
src/api/l_audio.c
|
||||||
src/api/l_source.c
|
src/api/l_audio_source.c
|
||||||
src/api/l_microphone.c
|
src/api/l_audio_microphone.c
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -362,12 +362,12 @@ if(LOVR_ENABLE_DATA)
|
||||||
src/modules/data/soundData.c
|
src/modules/data/soundData.c
|
||||||
src/modules/data/textureData.c
|
src/modules/data/textureData.c
|
||||||
src/api/l_data.c
|
src/api/l_data.c
|
||||||
src/api/l_audioStream.c
|
src/api/l_data_audioStream.c
|
||||||
src/api/l_blob.c
|
src/api/l_data_blob.c
|
||||||
src/api/l_modelData.c
|
src/api/l_data_modelData.c
|
||||||
src/api/l_rasterizer.c
|
src/api/l_data_rasterizer.c
|
||||||
src/api/l_soundData.c
|
src/api/l_data_soundData.c
|
||||||
src/api/l_textureData.c
|
src/api/l_data_textureData.c
|
||||||
src/lib/stb/stb_image.c
|
src/lib/stb/stb_image.c
|
||||||
src/lib/stb/stb_image_write.c
|
src/lib/stb/stb_image_write.c
|
||||||
src/lib/stb/stb_truetype.c
|
src/lib/stb/stb_truetype.c
|
||||||
|
@ -407,14 +407,14 @@ if(LOVR_ENABLE_GRAPHICS)
|
||||||
src/modules/graphics/shader.c
|
src/modules/graphics/shader.c
|
||||||
src/modules/graphics/texture.c
|
src/modules/graphics/texture.c
|
||||||
src/api/l_graphics.c
|
src/api/l_graphics.c
|
||||||
src/api/l_canvas.c
|
src/api/l_graphics_canvas.c
|
||||||
src/api/l_font.c
|
src/api/l_graphics_font.c
|
||||||
src/api/l_material.c
|
src/api/l_graphics_material.c
|
||||||
src/api/l_mesh.c
|
src/api/l_graphics_mesh.c
|
||||||
src/api/l_model.c
|
src/api/l_graphics_model.c
|
||||||
src/api/l_shader.c
|
src/api/l_graphics_shader.c
|
||||||
src/api/l_shaderBlock.c
|
src/api/l_graphics_shaderBlock.c
|
||||||
src/api/l_texture.c
|
src/api/l_graphics_texture.c
|
||||||
src/resources/shaders.c
|
src/resources/shaders.c
|
||||||
src/lib/glad/glad.c
|
src/lib/glad/glad.c
|
||||||
)
|
)
|
||||||
|
@ -468,9 +468,9 @@ if(LOVR_ENABLE_MATH)
|
||||||
src/modules/math/pool.c
|
src/modules/math/pool.c
|
||||||
src/modules/math/randomGenerator.c
|
src/modules/math/randomGenerator.c
|
||||||
src/api/l_math.c
|
src/api/l_math.c
|
||||||
src/api/l_curve.c
|
src/api/l_math_curve.c
|
||||||
src/api/l_randomGenerator.c
|
src/api/l_math_randomGenerator.c
|
||||||
src/api/l_vectors.c
|
src/api/l_math_vectors.c
|
||||||
src/lib/noise1234/noise1234.c
|
src/lib/noise1234/noise1234.c
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
@ -480,10 +480,10 @@ if(LOVR_ENABLE_PHYSICS)
|
||||||
target_sources(lovr PRIVATE
|
target_sources(lovr PRIVATE
|
||||||
src/modules/physics/physics.c
|
src/modules/physics/physics.c
|
||||||
src/api/l_physics.c
|
src/api/l_physics.c
|
||||||
src/api/l_collider.c
|
src/api/l_physics_collider.c
|
||||||
src/api/l_joints.c
|
src/api/l_physics_joints.c
|
||||||
src/api/l_shapes.c
|
src/api/l_physics_shapes.c
|
||||||
src/api/l_world.c
|
src/api/l_physics_world.c
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -492,9 +492,9 @@ if(LOVR_ENABLE_THREAD)
|
||||||
target_sources(lovr PRIVATE
|
target_sources(lovr PRIVATE
|
||||||
src/modules/thread/channel.c
|
src/modules/thread/channel.c
|
||||||
src/modules/thread/thread.c
|
src/modules/thread/thread.c
|
||||||
src/api/l_thread_module.c
|
|
||||||
src/api/l_channel.c
|
|
||||||
src/api/l_thread.c
|
src/api/l_thread.c
|
||||||
|
src/api/l_thread_channel.c
|
||||||
|
src/api/l_thread_thread.c
|
||||||
src/lib/tinycthread/tinycthread.c
|
src/lib/tinycthread/tinycthread.c
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
127
Tupfile
127
Tupfile
|
@ -1,5 +1,6 @@
|
||||||
include_rules
|
include_rules
|
||||||
|
|
||||||
|
# core
|
||||||
SRC += src/main.c
|
SRC += src/main.c
|
||||||
SRC += src/core/arr.c
|
SRC += src/core/arr.c
|
||||||
SRC += src/core/fs.c
|
SRC += src/core/fs.c
|
||||||
|
@ -10,94 +11,62 @@ SRC += src/core/ref.c
|
||||||
SRC += src/core/utf.c
|
SRC += src/core/utf.c
|
||||||
SRC += src/core/util.c
|
SRC += src/core/util.c
|
||||||
SRC += src/core/zip.c
|
SRC += src/core/zip.c
|
||||||
|
|
||||||
|
# modules
|
||||||
|
SRC_@(AUDIO) += src/modules/audio/*.c
|
||||||
|
SRC_@(DATA) += src/modules/data/*.c
|
||||||
|
SRC_@(EVENT) += src/modules/event/*.c
|
||||||
|
SRC_@(FILESYSTEM) += src/modules/filesystem/*.c
|
||||||
|
SRC_@(GRAPHICS) += src/modules/graphics/*.c
|
||||||
|
SRC_@(HEADSET) += src/modules/headset/headset.c
|
||||||
|
SRC_@(HEADSET)@(SIMULATOR) += src/modules/headset/desktop.c
|
||||||
|
SRC_@(HEADSET)@(OPENVR) += src/modules/headset/openvr.c
|
||||||
|
SRC_@(HEADSET)@(OPENXR) += src/modules/headset/openxr.c
|
||||||
|
SRC_@(HEADSET)@(OCULUS) += src/modules/headset/oculus.c
|
||||||
|
SRC_@(HEADSET)@(VRAPI) += src/modules/headset/oculus_mobile.c
|
||||||
|
SRC_@(HEADSET)@(WEBVR) += src/modules/headset/webvr.c
|
||||||
|
SRC_@(HEADSET)@(LEAP) += src/modules/headset/leap.c
|
||||||
|
SRC_@(MATH) += src/modules/math/*.c
|
||||||
|
SRC_@(PHYSICS) += src/modules/physics/*.c
|
||||||
|
SRC_@(THREAD) += src/modules/thread/*.c
|
||||||
|
SRC_@(TIMER) += src/modules/timer/*.c
|
||||||
|
|
||||||
|
# lib
|
||||||
|
SRC += src/lib/stb/*.c
|
||||||
|
SRC_@(DATA) += src/lib/jsmn/jsmn.c
|
||||||
|
SRC_@(GRAPHICS) += src/lib/glad/glad.c
|
||||||
|
SRC_@(MATH) += src/lib/noise1234/noise1234.c
|
||||||
|
SRC_@(THREAD) += src/lib/tinycthread/tinycthread.c
|
||||||
|
|
||||||
|
# api
|
||||||
SRC += src/api/api.c
|
SRC += src/api/api.c
|
||||||
SRC += src/api/l_lovr.c
|
SRC += src/api/l_lovr.c
|
||||||
SRC += src/lib/stb/*.c
|
SRC_@(AUDIO) += src/api/l_audio*.c
|
||||||
|
SRC_@(DATA) += src/api/l_data*.c
|
||||||
SRC_@(AUDIO) += src/modules/audio/*.c
|
SRC_@(EVENT) += src/api/l_event*.c
|
||||||
SRC_@(AUDIO) += src/api/l_audio.c
|
SRC_@(FILESYSTEM) += src/api/l_filesystem*.c
|
||||||
SRC_@(AUDIO) += src/api/l_microphone.c
|
SRC_@(GRAPHICS) += src/api/l_graphics*.c
|
||||||
SRC_@(AUDIO) += src/api/l_source.c
|
SRC_@(HEADSET) += src/api/l_headset*.c
|
||||||
|
SRC_@(MATH) += src/api/l_math*.c
|
||||||
SRC_@(DATA) += src/modules/data/*.c
|
SRC_@(PHYSICS) += src/api/l_physics*.c
|
||||||
SRC_@(DATA) += src/lib/jsmn/jsmn.c
|
SRC_@(THREAD) += src/api/l_thread*.c
|
||||||
SRC_@(DATA) += src/api/l_data.c
|
SRC_@(TIMER) += src/api/l_timer*.c
|
||||||
SRC_@(DATA) += src/api/l_audioStream.c
|
|
||||||
SRC_@(DATA) += src/api/l_blob.c
|
|
||||||
SRC_@(DATA) += src/api/l_modelData.c
|
|
||||||
SRC_@(DATA) += src/api/l_rasterizer.c
|
|
||||||
SRC_@(DATA) += src/api/l_soundData.c
|
|
||||||
SRC_@(DATA) += src/api/l_textureData.c
|
|
||||||
|
|
||||||
SRC_@(EVENT) += src/modules/event/*.c
|
|
||||||
SRC_@(EVENT) += src/api/l_event.c
|
|
||||||
|
|
||||||
SRC_@(FILESYSTEM) += src/modules/filesystem/*.c
|
|
||||||
SRC_@(FILESYSTEM) += src/api/l_filesystem.c
|
|
||||||
|
|
||||||
SRC_@(GRAPHICS) += src/modules/graphics/*.c
|
|
||||||
SRC_@(GRAPHICS) += src/resources/shaders.c
|
|
||||||
SRC_@(GRAPHICS) += src/lib/glad/glad.c
|
|
||||||
SRC_@(GRAPHICS) += src/api/l_graphics.c
|
|
||||||
SRC_@(GRAPHICS) += src/api/l_canvas.c
|
|
||||||
SRC_@(GRAPHICS) += src/api/l_font.c
|
|
||||||
SRC_@(GRAPHICS) += src/api/l_material.c
|
|
||||||
SRC_@(GRAPHICS) += src/api/l_mesh.c
|
|
||||||
SRC_@(GRAPHICS) += src/api/l_model.c
|
|
||||||
SRC_@(GRAPHICS) += src/api/l_shader.c
|
|
||||||
SRC_@(GRAPHICS) += src/api/l_shaderBlock.c
|
|
||||||
SRC_@(GRAPHICS) += src/api/l_texture.c
|
|
||||||
|
|
||||||
SRC_@(HEADSET) += src/modules/headset/headset.c
|
|
||||||
SRC_@(HEADSET) += src/api/l_headset.c
|
|
||||||
ifeq (@(HEADSET),y)
|
|
||||||
SRC_@(SIMULATOR) += src/modules/headset/desktop.c
|
|
||||||
SRC_@(OPENVR) += src/modules/headset/openvr.c
|
|
||||||
SRC_@(OPENXR) += src/modules/headset/openxr.c
|
|
||||||
SRC_@(OCULUS) += src/modules/headset/oculus.c
|
|
||||||
SRC_@(VRAPI) += src/modules/headset/oculus_mobile.c
|
|
||||||
SRC_@(WEBVR) += src/modules/headset/webvr.c
|
|
||||||
SRC_@(LEAP) += src/modules/headset/leap.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
SRC_@(MATH) += src/modules/math/*.c
|
|
||||||
SRC_@(MATH) += src/lib/noise1234/noise1234.c
|
|
||||||
SRC_@(MATH) += src/api/l_math.c
|
|
||||||
SRC_@(MATH) += src/api/l_curve.c
|
|
||||||
SRC_@(MATH) += src/api/l_randomGenerator.c
|
|
||||||
SRC_@(MATH) += src/api/l_vectors.c
|
|
||||||
|
|
||||||
SRC_@(PHYSICS) += src/modules/physics/*.c
|
|
||||||
SRC_@(PHYSICS) += src/api/l_physics.c
|
|
||||||
SRC_@(PHYSICS) += src/api/l_collider.c
|
|
||||||
SRC_@(PHYSICS) += src/api/l_joints.c
|
|
||||||
SRC_@(PHYSICS) += src/api/l_shapes.c
|
|
||||||
SRC_@(PHYSICS) += src/api/l_world.c
|
|
||||||
|
|
||||||
SRC_@(THREAD) += src/modules/thread/*.c
|
|
||||||
SRC_@(THREAD) += src/lib/tinycthread/tinycthread.c
|
|
||||||
SRC_@(THREAD) += src/api/l_thread_module.c
|
|
||||||
SRC_@(THREAD) += src/api/l_thread.c
|
|
||||||
SRC_@(THREAD) += src/api/l_channel.c
|
|
||||||
|
|
||||||
SRC_@(TIMER) += src/modules/timer/*.c
|
|
||||||
SRC_@(TIMER) += src/api/l_timer.c
|
|
||||||
|
|
||||||
SRC_@(JSON) += src/lib/lua-cjson/*.c
|
SRC_@(JSON) += src/lib/lua-cjson/*.c
|
||||||
SRC_@(ENET) += src/lib/lua-enet/*.c
|
SRC_@(ENET) += src/lib/lua-enet/*.c
|
||||||
|
|
||||||
|
# resources
|
||||||
RES += src/resources/boot.lua
|
RES += src/resources/boot.lua
|
||||||
RES += src/resources/VarelaRound.ttf
|
RES += src/resources/VarelaRound.ttf
|
||||||
RES_@(OPENVR) += src/resources/*.json
|
RES_@(OPENVR) += src/resources/*.json
|
||||||
|
SRC_@(GRAPHICS) += src/resources/shaders.c
|
||||||
|
|
||||||
# Convert resources to binary headers using xxd
|
## build:
|
||||||
: foreach $(RES) $(RES_y) |> !xxd |> %f.h
|
# 1 [XD] resources -> bin headers
|
||||||
|
# 2 [CC] compile .c -> .o
|
||||||
|
# 3 [LD] link .o -> exe
|
||||||
|
# 4 [CP] copy external libs -> libs folder
|
||||||
|
|
||||||
# Compile C source files to object files
|
: foreach $(RES) $(RES_y) |> !xd |> %f.h
|
||||||
: foreach $(SRC) $(SRC_y) | src/resources/*.h |> !cc |> .obj/%B.o
|
: foreach $(SRC) $(SRC_y) $(SRC_yy) | src/resources/*.h |> !cc |> .obj/%B.o
|
||||||
|
|
||||||
# Link object files into executable
|
|
||||||
: .obj/*.o |> !ld |> lovr
|
: .obj/*.o |> !ld |> lovr
|
||||||
|
|
||||||
# Copy external shared libraries to libs folder
|
|
||||||
: foreach $(LIBS) |> !cp |> libs/%b
|
: foreach $(LIBS) |> !cp |> libs/%b
|
||||||
|
|
|
@ -113,5 +113,5 @@ LDFLAGS += @(EXTRA_LDFLAGS)
|
||||||
## Macros
|
## Macros
|
||||||
!cc = |> ^ CC %b^ @(CC) $(CFLAGS_y) $(CFLAGS) -c %f -o %o |>
|
!cc = |> ^ CC %b^ @(CC) $(CFLAGS_y) $(CFLAGS) -c %f -o %o |>
|
||||||
!ld = |> ^ LD %o^ @(CC) -o %o %f $(LDFLAGS_y) $(LDFLAGS) |>
|
!ld = |> ^ LD %o^ @(CC) -o %o %f $(LDFLAGS_y) $(LDFLAGS) |>
|
||||||
!xxd = |> ^ XD %f^ xxd -i %f > %o |>
|
!xd = |> ^ XD %f^ xxd -i %f > %o |>
|
||||||
!cp = |> ^ CP %b^ cp %f %o |>
|
!cp = |> ^ CP %b^ cp %f %o |>
|
||||||
|
|
|
@ -1,44 +1,108 @@
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
|
#include "event/event.h"
|
||||||
#include "thread/thread.h"
|
#include "thread/thread.h"
|
||||||
|
#include "thread/channel.h"
|
||||||
|
#include "core/ref.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static int l_lovrThreadStart(lua_State* L) {
|
static int threadRunner(void* data) {
|
||||||
Thread* thread = luax_checktype(L, 1, Thread);
|
Thread* thread = (Thread*) data;
|
||||||
Variant arguments[MAX_THREAD_ARGUMENTS];
|
|
||||||
size_t argumentCount = MIN(MAX_THREAD_ARGUMENTS, lua_gettop(L) - 1);
|
lovrRetain(thread);
|
||||||
for (size_t i = 0; i < argumentCount; i++) {
|
mtx_lock(&thread->lock);
|
||||||
luax_checkvariant(L, 2 + i, &arguments[i]);
|
thread->running = true;
|
||||||
|
mtx_unlock(&thread->lock);
|
||||||
|
|
||||||
|
lua_State* L = luaL_newstate();
|
||||||
|
luaL_openlibs(L);
|
||||||
|
lovrSetErrorCallback((errorFn*) luax_vthrow, L);
|
||||||
|
|
||||||
|
lua_getglobal(L, "package");
|
||||||
|
lua_getfield(L, -1, "preload");
|
||||||
|
luaL_register(L, NULL, lovrModules);
|
||||||
|
lua_pop(L, 2);
|
||||||
|
|
||||||
|
if (!luaL_loadbuffer(L, thread->body->data, thread->body->size, "thread")) {
|
||||||
|
for (size_t i = 0; i < thread->argumentCount; i++) {
|
||||||
|
luax_pushvariant(L, &thread->arguments[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lua_pcall(L, thread->argumentCount, 0, 0)) {
|
||||||
|
mtx_lock(&thread->lock);
|
||||||
|
thread->running = false;
|
||||||
|
mtx_unlock(&thread->lock);
|
||||||
|
lovrRelease(Thread, thread);
|
||||||
|
lua_close(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lovrThreadStart(thread, arguments, argumentCount);
|
|
||||||
return 0;
|
// Error handling
|
||||||
|
size_t length;
|
||||||
|
const char* error = lua_tolstring(L, -1, &length);
|
||||||
|
mtx_lock(&thread->lock);
|
||||||
|
thread->error = malloc(length + 1);
|
||||||
|
if (thread->error) {
|
||||||
|
memcpy(thread->error, error, length + 1);
|
||||||
|
lovrEventPush((Event) {
|
||||||
|
.type = EVENT_THREAD_ERROR,
|
||||||
|
.data.thread = { thread, thread->error }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
thread->running = false;
|
||||||
|
mtx_unlock(&thread->lock);
|
||||||
|
lovrRelease(Thread, thread);
|
||||||
|
lua_close(L);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_lovrThreadWait(lua_State* L) {
|
static int l_lovrThreadNewThread(lua_State* L) {
|
||||||
Thread* thread = luax_checktype(L, 1, Thread);
|
Blob* blob = luax_totype(L, 1, Blob);
|
||||||
lovrThreadWait(thread);
|
if (!blob) {
|
||||||
return 0;
|
size_t length;
|
||||||
}
|
const char* str = lua_tolstring(L, 1, &length);
|
||||||
|
if (memchr(str, '\n', MIN(1024, length))) {
|
||||||
static int l_lovrThreadGetError(lua_State* L) {
|
void* data = malloc(length + 1);
|
||||||
Thread* thread = luax_checktype(L, 1, Thread);
|
lovrAssert(data, "Out of memory");
|
||||||
const char* error = lovrThreadGetError(thread);
|
memcpy(data, str, length + 1);
|
||||||
if (error) {
|
blob = lovrBlobCreate(data, length, "thread code");
|
||||||
lua_pushstring(L, error);
|
} else {
|
||||||
|
void* code = luax_readfile(str, &length);
|
||||||
|
lovrAssert(code, "Could not read thread code from file '%s'", str);
|
||||||
|
blob = lovrBlobCreate(code, length, str);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
lovrRetain(blob);
|
||||||
}
|
}
|
||||||
|
Thread* thread = lovrThreadCreate(threadRunner, blob);
|
||||||
|
luax_pushtype(L, Thread, thread);
|
||||||
|
lovrRelease(Thread, thread);
|
||||||
|
lovrRelease(Blob, blob);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_lovrThreadIsRunning(lua_State* L) {
|
static int l_lovrThreadGetChannel(lua_State* L) {
|
||||||
Thread* thread = luax_checktype(L, 1, Thread);
|
const char* name = luaL_checkstring(L, 1);
|
||||||
lua_pushboolean(L, thread->running);
|
Channel* channel = lovrThreadGetChannel(name);
|
||||||
|
luax_pushtype(L, Channel, channel);
|
||||||
|
lovrRelease(Channel, channel);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const luaL_Reg lovrThread[] = {
|
static const luaL_Reg lovrThreadModule[] = {
|
||||||
{ "start", l_lovrThreadStart },
|
{ "newThread", l_lovrThreadNewThread },
|
||||||
{ "wait", l_lovrThreadWait },
|
{ "getChannel", l_lovrThreadGetChannel },
|
||||||
{ "getError", l_lovrThreadGetError },
|
|
||||||
{ "isRunning", l_lovrThreadIsRunning },
|
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int luaopen_lovr_thread(lua_State* L) {
|
||||||
|
lua_newtable(L);
|
||||||
|
luaL_register(L, NULL, lovrThreadModule);
|
||||||
|
luax_registertype(L, Thread);
|
||||||
|
luax_registertype(L, Channel);
|
||||||
|
if (lovrThreadModuleInit()) {
|
||||||
|
luax_atexit(L, lovrThreadModuleDestroy);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
#include "api.h"
|
|
||||||
#include "event/event.h"
|
|
||||||
#include "thread/thread.h"
|
|
||||||
#include "thread/channel.h"
|
|
||||||
#include "core/ref.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static int threadRunner(void* data) {
|
|
||||||
Thread* thread = (Thread*) data;
|
|
||||||
|
|
||||||
lovrRetain(thread);
|
|
||||||
mtx_lock(&thread->lock);
|
|
||||||
thread->running = true;
|
|
||||||
mtx_unlock(&thread->lock);
|
|
||||||
|
|
||||||
lua_State* L = luaL_newstate();
|
|
||||||
luaL_openlibs(L);
|
|
||||||
lovrSetErrorCallback((errorFn*) luax_vthrow, L);
|
|
||||||
|
|
||||||
lua_getglobal(L, "package");
|
|
||||||
lua_getfield(L, -1, "preload");
|
|
||||||
luaL_register(L, NULL, lovrModules);
|
|
||||||
lua_pop(L, 2);
|
|
||||||
|
|
||||||
if (!luaL_loadbuffer(L, thread->body->data, thread->body->size, "thread")) {
|
|
||||||
for (size_t i = 0; i < thread->argumentCount; i++) {
|
|
||||||
luax_pushvariant(L, &thread->arguments[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!lua_pcall(L, thread->argumentCount, 0, 0)) {
|
|
||||||
mtx_lock(&thread->lock);
|
|
||||||
thread->running = false;
|
|
||||||
mtx_unlock(&thread->lock);
|
|
||||||
lovrRelease(Thread, thread);
|
|
||||||
lua_close(L);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error handling
|
|
||||||
size_t length;
|
|
||||||
const char* error = lua_tolstring(L, -1, &length);
|
|
||||||
mtx_lock(&thread->lock);
|
|
||||||
thread->error = malloc(length + 1);
|
|
||||||
if (thread->error) {
|
|
||||||
memcpy(thread->error, error, length + 1);
|
|
||||||
lovrEventPush((Event) {
|
|
||||||
.type = EVENT_THREAD_ERROR,
|
|
||||||
.data.thread = { thread, thread->error }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
thread->running = false;
|
|
||||||
mtx_unlock(&thread->lock);
|
|
||||||
lovrRelease(Thread, thread);
|
|
||||||
lua_close(L);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int l_lovrThreadNewThread(lua_State* L) {
|
|
||||||
Blob* blob = luax_totype(L, 1, Blob);
|
|
||||||
if (!blob) {
|
|
||||||
size_t length;
|
|
||||||
const char* str = lua_tolstring(L, 1, &length);
|
|
||||||
if (memchr(str, '\n', MIN(1024, length))) {
|
|
||||||
void* data = malloc(length + 1);
|
|
||||||
lovrAssert(data, "Out of memory");
|
|
||||||
memcpy(data, str, length + 1);
|
|
||||||
blob = lovrBlobCreate(data, length, "thread code");
|
|
||||||
} else {
|
|
||||||
void* code = luax_readfile(str, &length);
|
|
||||||
lovrAssert(code, "Could not read thread code from file '%s'", str);
|
|
||||||
blob = lovrBlobCreate(code, length, str);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lovrRetain(blob);
|
|
||||||
}
|
|
||||||
Thread* thread = lovrThreadCreate(threadRunner, blob);
|
|
||||||
luax_pushtype(L, Thread, thread);
|
|
||||||
lovrRelease(Thread, thread);
|
|
||||||
lovrRelease(Blob, blob);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int l_lovrThreadGetChannel(lua_State* L) {
|
|
||||||
const char* name = luaL_checkstring(L, 1);
|
|
||||||
Channel* channel = lovrThreadGetChannel(name);
|
|
||||||
luax_pushtype(L, Channel, channel);
|
|
||||||
lovrRelease(Channel, channel);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const luaL_Reg lovrThreadModule[] = {
|
|
||||||
{ "newThread", l_lovrThreadNewThread },
|
|
||||||
{ "getChannel", l_lovrThreadGetChannel },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
int luaopen_lovr_thread(lua_State* L) {
|
|
||||||
lua_newtable(L);
|
|
||||||
luaL_register(L, NULL, lovrThreadModule);
|
|
||||||
luax_registertype(L, Thread);
|
|
||||||
luax_registertype(L, Channel);
|
|
||||||
if (lovrThreadModuleInit()) {
|
|
||||||
luax_atexit(L, lovrThreadModuleDestroy);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include "api.h"
|
||||||
|
#include "thread/thread.h"
|
||||||
|
|
||||||
|
static int l_lovrThreadStart(lua_State* L) {
|
||||||
|
Thread* thread = luax_checktype(L, 1, Thread);
|
||||||
|
Variant arguments[MAX_THREAD_ARGUMENTS];
|
||||||
|
size_t argumentCount = MIN(MAX_THREAD_ARGUMENTS, lua_gettop(L) - 1);
|
||||||
|
for (size_t i = 0; i < argumentCount; i++) {
|
||||||
|
luax_checkvariant(L, 2 + i, &arguments[i]);
|
||||||
|
}
|
||||||
|
lovrThreadStart(thread, arguments, argumentCount);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_lovrThreadWait(lua_State* L) {
|
||||||
|
Thread* thread = luax_checktype(L, 1, Thread);
|
||||||
|
lovrThreadWait(thread);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_lovrThreadGetError(lua_State* L) {
|
||||||
|
Thread* thread = luax_checktype(L, 1, Thread);
|
||||||
|
const char* error = lovrThreadGetError(thread);
|
||||||
|
if (error) {
|
||||||
|
lua_pushstring(L, error);
|
||||||
|
} else {
|
||||||
|
lua_pushnil(L);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_lovrThreadIsRunning(lua_State* L) {
|
||||||
|
Thread* thread = luax_checktype(L, 1, Thread);
|
||||||
|
lua_pushboolean(L, thread->running);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const luaL_Reg lovrThread[] = {
|
||||||
|
{ "start", l_lovrThreadStart },
|
||||||
|
{ "wait", l_lovrThreadWait },
|
||||||
|
{ "getError", l_lovrThreadGetError },
|
||||||
|
{ "isRunning", l_lovrThreadIsRunning },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
Loading…
Reference in New Issue