diff options
Diffstat (limited to 'src/lua/modules')
33 files changed, 2801 insertions, 0 deletions
diff --git a/src/lua/modules/audio/luaopen_Source.cpp b/src/lua/modules/audio/luaopen_Source.cpp new file mode 100644 index 0000000..4c98ead --- /dev/null +++ b/src/lua/modules/audio/luaopen_Source.cpp @@ -0,0 +1,115 @@ +#include "libjin/jin.h" +#include "lua/modules/luax.h" +#include "lua/common/common.h" + +namespace jin +{ +namespace lua +{ + + using namespace jin::audio; + + typedef Ref<Source>& SourceRef; + + static inline SourceRef checkSource(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_AUDIO_SOURCE); + return proxy->getRef<Source>(); + } + + static int l_play(lua_State* L) + { + SourceRef ref = checkSource(L); + ref->play(); + return 0; + } + + static int l_stop(lua_State* L) + { + SourceRef ref = checkSource(L); + ref->stop(); + return 0; + } + + static int l_pause(lua_State* L) + { + SourceRef ref = checkSource(L); + ref->pause(); + return 0; + } + + static int l_rewind(lua_State* L) + { + SourceRef ref = checkSource(L); + ref->rewind(); + return 0; + } + + static int l_resume(lua_State* L) + { + SourceRef ref = checkSource(L); + ref->resume(); + return 0; + } + + static int l_isStop(lua_State* L) + { + SourceRef ref = checkSource(L); + bool isStop = ref->isStopped(); + luax_pushboolean(L, isStop); + return 1; + } + + static int l_isPaused(lua_State* L) + { + SourceRef ref = checkSource(L); + bool isPaused = ref->isPaused(); + luax_pushboolean(L, isPaused); + return 1; + } + + static int l_setVolume(lua_State* L) + { + SourceRef ref = checkSource(L); + float volume = luax_checknumber(L, 2); + ref->setVolume(volume); + return 0; + } + + static int l_setLoop(lua_State* L) + { + SourceRef ref = checkSource(L); + bool loop = luax_checkbool(L, 2); + ref->setLoop(loop); + return 0; + } + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_AUDIO_SOURCE); + proxy->release(); + return 0; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "play", l_play }, + { "stop", l_stop }, + { "pause", l_pause }, + { "resume", l_resume }, + { "rewind", l_rewind }, + { "isStop", l_isStop }, + { "isPaused", l_isPaused }, + { "setVolume", l_setVolume }, + { "setLoop", l_setLoop }, + { 0, 0 } + }; + + int luaopen_Source(lua_State* L) + { + luax_newtype(L, JIN_AUDIO_SOURCE, f); + return 0; + } + +} // lua +} // jin
\ No newline at end of file diff --git a/src/lua/modules/audio/luaopen_audio.cpp b/src/lua/modules/audio/luaopen_audio.cpp new file mode 100644 index 0000000..1c44374 --- /dev/null +++ b/src/lua/modules/audio/luaopen_audio.cpp @@ -0,0 +1,109 @@ +#include "lua/modules/luax.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace jin +{ +namespace lua +{ + + using namespace jin::audio; + using namespace jin::filesystem; + + typedef SDLAudio Audio; + typedef SDLSource Source; + + static int l_init(lua_State* L) + { + Audio::Setting setting; + setting.samplerate = 44100; + setting.samples = 44100; + if (!Audio::get()->init(&setting)) + { + luax_error(L, "could not init audio"); + luax_pushboolean(L, false); + return 1; + } + luax_pushboolean(L, true); + return 1; + } + + static int l_play(lua_State* L) + { + Audio::get()->play(); + return 0; + } + + static int l_stop(lua_State* L) + { + Audio::get()->stop(); + return 0; + } + + static int l_pause(lua_State* L) + { + Audio::get()->pause(); + return 0; + } + + static int l_resume(lua_State* L) + { + Audio::get()->resume(); + return 0; + } + + static int l_setVolume(lua_State* L) + { + float volume = luax_checknumber(L, 1); + Audio::get()->setVolume(volume); + return 0; + } + + static int l_newSource(lua_State* L) + { + Filesystem* fs = Filesystem::get(); + const char* f = luax_checkstring(L, 1); + if (!fs->exists(f)) + { + printf("Error: no such image %s\n", f); + exit(1); + } + Buffer b; + fs->read(f, &b); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_AUDIO_SOURCE, sizeof(Proxy)); + Source* src = Source::createSource(b.data, b.size); + proxy->bind(new Ref<Source>(src, JIN_AUDIO_SOURCE)); + return 1; + } + + static int l_destroy(lua_State* L) + { + Audio* audio = Audio::get(); + audio->quit(); + return 0; + } + + static const luaL_Reg f[] = { + { "init", l_init }, + { "play", l_play }, + { "stop", l_stop }, + { "pause", l_pause }, + { "resume", l_resume }, + { "setVolume", l_setVolume }, + { "newSource", l_newSource }, + { "destroy", l_destroy }, + { 0, 0 } + }; + + extern int luaopen_Source(lua_State* L); + + int luaopen_audio(lua_State* L) + { + luaopen_Source(L); + + luax_newlib(L, f); + + return 1; + } +} +}
\ No newline at end of file diff --git a/src/lua/modules/bit/luaopen_bit.cpp b/src/lua/modules/bit/luaopen_bit.cpp new file mode 100644 index 0000000..5b18125 --- /dev/null +++ b/src/lua/modules/bit/luaopen_bit.cpp @@ -0,0 +1,84 @@ +#include "lua/modules/luax.h" +#include "libjin/jin.h" +#include <cstdlib> + +namespace jin +{ +namespace lua +{ + + static int l_and(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushinteger(L, a & b); + return 1; + } + + static int l_or(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushinteger(L, a | b); + return 1; + } + + static int l_xor(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushinteger(L, a ^ b); + return 1; + } + + static int l_not(lua_State* L) + { + int n = luax_checkinteger(L, 1); + luax_pushinteger(L, ~n); + return 1; + } + + static int l_lshift(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushinteger(L, a << b); + return 1; + } + + static int l_rshift(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushinteger(L, a >> b); + return 1; + } + + static int l_include(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushboolean(L, (a & b) == b); + return 1; + } + + static const luaL_Reg f[] = { + { "bAnd", l_and }, + { "bOr" , l_or }, + { "bXor", l_xor }, + { "bNot", l_not }, + { "bLs", l_lshift }, + { "bRs", l_rshift }, + { "bInc", l_include }, + { 0, 0 } + }; + + int luaopen_bit(lua_State* L) + { + luax_newlib(L, f); + + return 1; + } + +} +}
\ No newline at end of file diff --git a/src/lua/modules/core/luaopen_core.cpp b/src/lua/modules/core/luaopen_core.cpp new file mode 100644 index 0000000..0243554 --- /dev/null +++ b/src/lua/modules/core/luaopen_core.cpp @@ -0,0 +1,44 @@ +#include "lua/modules/luax.h" +#include "libjin/jin.h" + +namespace jin +{ +namespace lua +{ + using namespace jin::core; + + static int l_running(lua_State* L) + { + static Game* game = Game::get(); + bool running = game->running(); + luax_pushboolean(L, running); + return 1; + } + + static int l_stop(lua_State* L) + { + Game::get()->stop(); + return 0; + } + + static int l_quit(lua_State* L) + { + Game::get()->quit(); + return 0; + } + + static const luaL_Reg f[] = { + {"running", l_running }, + {"stop", l_stop }, + {"quit", l_quit }, + {0, 0 } + }; + + int luaopen_core(lua_State* L) + { + luax_newlib(L, f); + + return 1; + } +} +}
\ No newline at end of file diff --git a/src/lua/modules/embed/boot.lua.h b/src/lua/modules/embed/boot.lua.h new file mode 100644 index 0000000..32d3e1d --- /dev/null +++ b/src/lua/modules/embed/boot.lua.h @@ -0,0 +1,170 @@ +/* boot.lua */ +static const char* boot_lua = R"( +jin._argv[2] = jin._argv[2] or '.' +jin.filesystem.init() +jin.filesystem.mount(jin._argv[2]) + +local conf = {} +if jin.filesystem.exist("config.lua") then + conf = require "config" +end +conf.width = conf.width or 576 +conf.height = conf.height or 448 +conf.fps = conf.fps or 60 +conf.vsync = conf.vsync or false +conf.title = conf.title or ("jin v" .. jin.version()) +conf.resizable = conf.resizable or false +conf.fullscreen = conf.fullscreen or false + +-- initialize subsystems +jin.graphics.init(conf) +jin.audio.init() + +local function call(func, ...) + if func then + return func(...) + end +end + +jin.core.setHandler = function(handler) + if handler == nil then + return + end + jin.core.onLoad = handler.onLoad + jin.core.onEvent = handler.onEvent + jin.core.onUpdate = handler.onUpdate + jin.core.onDraw = handler.onDraw +end + +function jin.core.run() + call(jin.core.onLoad) + local previous = jin.time.second() + local SEC_PER_UPDATE = 1 / conf.fps + local dt = SEC_PER_UPDATE + local running = true + while(jin.core.running()) do + for _, e in pairs(jin.event.poll()) do + if e.type == "keydown" then + jin.keyboard.set(e.key, true) + elseif e.type == "keyup" then + jin.keyboard.set(e.key, false) + end + call(jin.core.onEvent, e) + running = jin.core.running() + if not running then break end + end + if not running then break end + + call(jin.core.onUpdate, dt) + + jin.graphics.unbind() + jin.graphics.clear() + jin.graphics.color() + jin.graphics.study() + call(jin.core.onDraw) + jin.graphics.present() + + local current = jin.time.second() + dt = current - previous + local wait = SEC_PER_UPDATE - dt + previous = previous + SEC_PER_UPDATE + if wait > 0 then + dt = SEC_PER_UPDATE + jin.time.sleep(wait) + else + previous = current + end + end +end + +local function onError(msg) + local tab = ' ' + print("Error:\n" .. msg) + function jin.core.onEvent(e) + if e.type == 'quit' then + jin.core.stop() + end + end + local ww, wh = jin.graphics.size() + function jin.core.onDraw() + jin.graphics.write("Error: ", 10, 10, 30, 3, 30) + jin.graphics.write(msg, 10, 50) + end +end + +------------------------------------------------------------------------------- +-- No game handler +------------------------------------------------------------------------------- + +jin.nogame = { + cs = 64, + sw = jin.graphics.getWidth(), + sh = jin.graphics.getHeight(), + cw = 0, + ch = 0, + ww = 6, + ww2 = 6*2, + speed = 4, + t = 0, + onLoad = function() + local nogame = jin.nogame + nogame.cw = nogame.sw / nogame.cs + nogame.ch = nogame.sh / nogame.cs + nogame.t = nogame.ww - 1 + end, + onEvent = function(e) + if e.type == 'quit' then + jin.core.stop() + end + end, + onUpdate = function(dt) + local nogame = jin.nogame + nogame.t = nogame.t + dt * nogame.speed + if nogame.t > nogame.ww2 then + nogame.t = nogame.t - nogame.ww2 + end + end, + circle = function(x, y, r) + local nogame = jin.nogame + if r % nogame.ww2 > nogame.ww then + return + end + r = math.sin((r/nogame.ww)*math.pi)*nogame.cs/2 + local fact = (x + y) / nogame.ch * nogame.cw + jin.graphics.color(155 + 100 * math.sin(fact), 155 + 100 * math.cos(fact), 155 + 100 * math.sin(fact * fact), 255) + jin.graphics.circle("fill", x*nogame.cs + nogame.cs/2, y*nogame.cs + nogame.cs/2, r) + end, + onDraw = function() + local nogame = jin.nogame + for y = 0, nogame.ch - 1 do + for x = 0, nogame.cw - 1 do + nogame.circle(x, y, nogame.t+x+y) + end + end + end +} + +------------------------------------------------------------------------------- +-- Boot jin +------------------------------------------------------------------------------- + +local function boot() + if jin.filesystem.exist("main.lua") then + -- require main game script + xpcall(function() require"main" end, onError) + jin.core.run() + else + -- no game + jin.core.setHandler(jin.nogame) + jin.core.run() + end + -- quit subsystems + jin.graphics.destroy() + jin.audio.destroy() + -- exit whole game + jin.core.quit() +end + +xpcall(boot, onError) + +)"; diff --git a/src/lua/modules/embed/embed.h b/src/lua/modules/embed/embed.h new file mode 100644 index 0000000..18ed1d8 --- /dev/null +++ b/src/lua/modules/embed/embed.h @@ -0,0 +1,49 @@ +#ifndef __JIN_LUA_EMBED_H +#define __JIN_LUA_EMBED_H +#include <cstring> + +namespace jin +{ +namespace embed +{ + + /** + * embed lua script to context. + */ +#define embed(L, script, name)\ + if(luax_loadbuffer(L, script, strlen(script), name) == 0)\ + lua_call(L, 0, 0); + + /** + * embed structure. + */ + struct jin_Embed + { + const char* file, *source; + }; + + static void boot(lua_State* L) + { + // embed scripts + #include "graphics.lua.h" // graphics + #include "keyboard.lua.h" // keyboard + #include "mouse.lua.h" // mouse + #include "boot.lua.h" // boot + + // embed scripts + const jin_Embed scripts[] = { + { "graphics.lua", graphics_lua }, + { "keyboard.lua", keyboard_lua }, + { "mouse.lua", mouse_lua }, + { "boot.lua", boot_lua }, + { 0, 0 } + }; + + // load all emebd lua scripts + for (int i = 0; scripts[i].file; ++i) + embed(L, scripts[i].source, scripts[i].file); + } +} +} + +#endif
\ No newline at end of file diff --git a/src/lua/modules/embed/graphics.lua.h b/src/lua/modules/embed/graphics.lua.h new file mode 100644 index 0000000..1414efc --- /dev/null +++ b/src/lua/modules/embed/graphics.lua.h @@ -0,0 +1,4 @@ +/* graphics.lua */ +static const char* graphics_lua = R"( +jin.graphics = jin.graphics or {} +)"; diff --git a/src/lua/modules/embed/keyboard.lua.h b/src/lua/modules/embed/keyboard.lua.h new file mode 100644 index 0000000..77bf3a9 --- /dev/null +++ b/src/lua/modules/embed/keyboard.lua.h @@ -0,0 +1,15 @@ + +static const char* keyboard_lua = R"( +jin.keyboard = jin.keyboard or {} + +local keys = {} + +function jin.keyboard.isDown(k) + return keys[k] +end + +function jin.keyboard.set(k, status) + keys[k] = status +end + +)"; diff --git a/src/lua/modules/embed/mouse.lua.h b/src/lua/modules/embed/mouse.lua.h new file mode 100644 index 0000000..3c222f3 --- /dev/null +++ b/src/lua/modules/embed/mouse.lua.h @@ -0,0 +1,14 @@ +static const char* mouse_lua = R"( +jin.mouse = jin.mouse or {} + +local button = {} + +function jin.mouse.isDown(btn) + return button[btn] +end + +function jin.mouse.set(btn, status) + button[btn] = status +end + +)";
\ No newline at end of file diff --git a/src/lua/modules/embed/net.lua.h b/src/lua/modules/embed/net.lua.h new file mode 100644 index 0000000..4d89dc7 --- /dev/null +++ b/src/lua/modules/embed/net.lua.h @@ -0,0 +1,4 @@ +/* net.lua */ +static const char* net_lua = R"( +jin.net = jin.net or {} +)";
\ No newline at end of file diff --git a/src/lua/modules/embed/path.lua.h b/src/lua/modules/embed/path.lua.h new file mode 100644 index 0000000..648adf8 --- /dev/null +++ b/src/lua/modules/embed/path.lua.h @@ -0,0 +1,14 @@ +/* path.lua */ +static const char* path_lua = R"( +jin.path = jin.path or {} + +-- game root directory +jin._root = nil + +-- return full path of a given path +function jin.path.full(path) + local root = jin._dir .. '/' .. jin._argv[2] + return root .. '/' .. path +end + +)";
\ No newline at end of file diff --git a/src/lua/modules/event/luaopen_event.cpp b/src/lua/modules/event/luaopen_event.cpp new file mode 100644 index 0000000..af9f8fc --- /dev/null +++ b/src/lua/modules/event/luaopen_event.cpp @@ -0,0 +1,106 @@ +/** +* Event module +*/ +#include "lua/modules/luax.h" +#include "libjin/jin.h" + +namespace jin +{ +namespace lua +{ + + using namespace jin::input; + + /** + * Load event poll, return a iterator(a table). + */ + static int l_event_poll(lua_State *L) + { + // table to store events + luax_newtable(L); + static Event e; + int i = 1; + poll: + while (pollEvent(&e)) + { + // each event is a table + luax_newtable(L); + switch (e.type) + { + case EventType::QUIT: + luax_setfield_string(L, "type", "quit"); + break; + + case EventType::KEY_DOWN: + luax_setfield_string(L, "type", "keydown"); + luax_setfield_string(L, "key", getKeyName(e.key.keysym.sym)); + break; + + case EventType::KEY_UP: + luax_setfield_string(L, "type", "keyup"); + luax_setfield_string(L, "key", getKeyName(e.key.keysym.sym)); + break; + + case EventType::MOUSE_MOTION: + luax_setfield_string(L, "type", "mousemotion"); + luax_setfield_number(L, "x", e.motion.x); + luax_setfield_number(L, "y", e.motion.y); + break; + + case EventType::MOUSE_BUTTON_DOWN: + luax_setfield_string(L, "type", "mousebuttondown"); + luax_setfield_string(L, "button", getButtonName(e.button.button)); + luax_setfield_number(L, "x", e.button.x); + luax_setfield_number(L, "y", e.button.y); + break; + + case EventType::MOUSE_BUTTON_UP: + luax_setfield_string(L, "type", "mousebuttonup"); + luax_setfield_string(L, "button", getButtonName(e.button.button)); + luax_setfield_number(L, "x", e.button.x); + luax_setfield_number(L, "y", e.button.y); + break; + + case EventType::MOUSE_WHEEL: + luax_setfield_string(L, "type", "wheel"); + if(e.wheel.x == -1) + luax_setfield_string(L, "x", "left"); + else if(e.wheel.x == 1) + luax_setfield_string(L, "x", "right"); + else + luax_setfield_string(L, "x", "none"); + if (e.wheel.y == -1) + luax_setfield_string(L, "y", "near"); + else if (e.wheel.y == 1) + luax_setfield_string(L, "y", "far"); + else + luax_setfield_string(L, "y", "none"); + break; + + default: + /* ignore other events */ + luax_pop(L, 1); // pop table out + goto poll; + break; + } + luax_rawseti(L, -2, i++); + } + return 1; + } + + static const luaL_Reg f[] = { + { "poll", l_event_poll }, + { 0, 0 } + }; + + /** + * load event module + */ + int luaopen_event(lua_State* L) + { + luax_newlib(L, f); + return 1; + } + +} // lua +} // jin
\ No newline at end of file diff --git a/src/lua/modules/filesystem/luaopen_filesystem.cpp b/src/lua/modules/filesystem/luaopen_filesystem.cpp new file mode 100644 index 0000000..55f4c06 --- /dev/null +++ b/src/lua/modules/filesystem/luaopen_filesystem.cpp @@ -0,0 +1,137 @@ +#include "lua/modules/luax.h" +#include "libjin/jin.h" +#include <string> + +using namespace jin::filesystem; + +namespace jin +{ +namespace lua +{ + + static struct + { + Filesystem* fs; + } context; + + static int l_init(lua_State* L) + { + context.fs = Filesystem::get(); + return 0; + } + + /** + * set current game root, like + * C:/jin/games/tank/ + */ + static int l_mount(lua_State* L) + { + const char* path = luax_checkstring(L, 1); + context.fs->mount(path); + return 0; + } + + /** + * + */ + static int l_isDir(lua_State *L) + { + const char* path = luax_checkstring(L, 1); + int r = context.fs->isDir(path); + luax_pushboolean(L, r); + return 1; + } + + /** + * + */ + static int l_exist(lua_State * L) + { + const char* path = luax_checkstring(L, 1); + int r = context.fs->exists(path); + luax_pushboolean(L, r); + return 1; + } + + static int l_isdir(lua_State* L) + { + const char* path = luax_checkstring(L, 1); + int r = context.fs->isDir(path); + luax_pushboolean(L, r); + return 1; + } + + // load but dont run it + static int loadf(lua_State* L) + { + const char* filename = lua_tostring(L, -1); + Buffer bf; + context.fs->read(filename, &bf); + luax_loadbuffer(L, (const char*)bf.data, bf.size, filename); + return 1; + } + + static int loader(lua_State* L) + { + const char * filename = lua_tostring(L, -1); + + std::string tmp(filename); + tmp += ".lua"; + + int size = tmp.size(); + + for (int i = 0; i<size - 4; ++i) + { + if (tmp[i] == '.') + { + tmp[i] = '/'; + } + } + + if (context.fs->exists(tmp.c_str())) + { + lua_pop(L, 1); + lua_pushstring(L, tmp.c_str()); + return loadf(L); + } + + tmp = filename; + size = tmp.size(); + for (int i = 0; i<size; ++i) + { + if (tmp[i] == '.') + tmp[i] = '/'; + } + + if (context.fs->isDir(tmp.c_str())) + { + tmp += "/init.lua"; + if (context.fs->exists(tmp.c_str())) + { + lua_pop(L, 1); + lua_pushstring(L, tmp.c_str()); + return loadf(L); + } + } + + lua_pushfstring(L, "\n\tno file \"%s\" in jin game directories.\n", (tmp + ".lua").c_str()); + return 1; + } + + static const luaL_Reg f[] = { + { "init", l_init }, + { "mount", l_mount }, + { "isdir", l_isDir }, + { "exist", l_exist }, + { 0, 0 } + }; + + int luaopen_filesystem(lua_State* L) + { + luax_newlib(L, f); + luax_register_searcher(L, loader, 1); + return 0; + } + +} +}
\ No newline at end of file diff --git a/src/lua/modules/graphics/luaopen_Canvas.cpp b/src/lua/modules/graphics/luaopen_Canvas.cpp new file mode 100644 index 0000000..d94e578 --- /dev/null +++ b/src/lua/modules/graphics/luaopen_Canvas.cpp @@ -0,0 +1,74 @@ +#include "lua/modules/luax.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace jin +{ +namespace lua +{ + + using namespace jin::graphics; + + typedef Ref<Canvas>& CanvasRef; + + static inline CanvasRef checkCanvas(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_CANVAS); + return proxy->getRef<Canvas>(); + } + + static int l_getWidth(lua_State* L) + { + CanvasRef ref = checkCanvas(L); + luax_pushnumber(L, ref->getWidth()); + return 1; + } + + static int l_getHeight(lua_State* L) + { + CanvasRef ref = checkCanvas(L); + luax_pushnumber(L, ref->getHeight()); + return 1; + } + + static int l_getSize(lua_State* L) + { + CanvasRef ref = checkCanvas(L); + luax_pushnumber(L, ref->getWidth()); + luax_pushnumber(L, ref->getHeight()); + return 2; + } + + static int l_setAnchor(lua_State* L) + { + CanvasRef ref = checkCanvas(L); + int x = luax_checknumber(L, 1); + int y = luax_checknumber(L, 2); + ref->setAnchor(x, y); + return 0; + } + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_CANVAS); + proxy->release(); + return 0; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "getWidth", l_getWidth }, + { "getHeight", l_getHeight }, + { "getSize", l_getSize }, + { "setAnchor", l_setAnchor }, + { 0, 0 } + }; + + int luaopen_Canvas(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_CANVAS, f); + return 0; + } + +}// lua +}// jin
\ No newline at end of file diff --git a/src/lua/modules/graphics/luaopen_Font.cpp b/src/lua/modules/graphics/luaopen_Font.cpp new file mode 100644 index 0000000..c5789ad --- /dev/null +++ b/src/lua/modules/graphics/luaopen_Font.cpp @@ -0,0 +1,48 @@ +#include "lua/modules/luax.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace jin +{ +namespace lua +{ + + using namespace jin::graphics; + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_FONT); + proxy->release(); + return 0; + } + + static int l_box(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_FONT, sizeof(Proxy)); + Ref<Font>& ref = proxy->getRef<Font>(); + const char* text = luax_checkstring(L, 2); + int fheight = luax_checknumber(L, 3); + int spacing = luax_checknumber(L, 4); + int lheight = luax_checknumber(L, 5); + int w, h; + ref->box(text, fheight, lheight, spacing, &w, &h); + luax_pushnumber(L, w); + luax_pushnumber(L, h); + return 2; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "box", l_box }, + { 0, 0 } + }; + + int luaopen_Font(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_FONT, f); + + return 0; + } + +} // lua +} // jin
\ No newline at end of file diff --git a/src/lua/modules/graphics/luaopen_Image.cpp b/src/lua/modules/graphics/luaopen_Image.cpp new file mode 100644 index 0000000..0f68873 --- /dev/null +++ b/src/lua/modules/graphics/luaopen_Image.cpp @@ -0,0 +1,88 @@ +#include "lua/modules/luax.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace jin +{ +namespace lua +{ + + using namespace jin::graphics; + + typedef Texture Image; + + static inline Ref<Image>& checkImage(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_IMAGE); + return proxy->getRef<Image>(); + } + + static int l_getWidth(lua_State* L) + { + Ref<Image>& ref = checkImage(L); + luax_pushnumber(L, ref->getWidth()); + return 1; + } + + static int l_getHeight(lua_State *L) + { + Ref<Image>& ref = checkImage(L); + luax_pushnumber(L, ref->getHeight()); + return 1; + } + + static int l_getPixel(lua_State* L) + { + Ref<Image>& ref = checkImage(L); + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + color c = ref->getPixel(x, y); + luax_pushnumber(L, c.rgba.r); + luax_pushnumber(L, c.rgba.g); + luax_pushnumber(L, c.rgba.b); + luax_pushnumber(L, c.rgba.a); + return 4; + } + + static int l_setAnchor(lua_State* L) + { + Ref<Image>& ref = checkImage(L); + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + ref->setAnchor(x, y); + return 0; + } + + static int l_getSize(lua_State* L) + { + Ref<Image>& ref = checkImage(L); + luax_pushnumber(L, ref->getWidth()); + luax_pushnumber(L, ref->getHeight()); + return 2; + } + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_IMAGE); + proxy->release(); + return 0; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "getWidth", l_getWidth }, + { "getHeight", l_getHeight }, + { "getSize", l_getSize }, + { "getPixel", l_getPixel }, + { "setAnchor", l_setAnchor }, + { 0, 0 } + }; + + int luaopen_Image(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_IMAGE, f); + return 0; + } + +}// graphics +}// jin
\ No newline at end of file diff --git a/src/lua/modules/graphics/luaopen_JSL.cpp b/src/lua/modules/graphics/luaopen_JSL.cpp new file mode 100644 index 0000000..c7a257a --- /dev/null +++ b/src/lua/modules/graphics/luaopen_JSL.cpp @@ -0,0 +1,145 @@ +#include "lua/modules/luax.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace jin +{ +namespace lua +{ + + using namespace jin::graphics; + + typedef Texture Image; + + static inline Ref<JSLProgram>& checkJSLProgram(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_SHADER); + return proxy->getRef<JSLProgram>(); + } + + static enum VARIABLE_TYPE + { + INVALID = 0, + + NUMBER, + IMAGE, + CANVAS, + VEC2, + VEC3, + VEC4, + COLOR, + }; + + static VARIABLE_TYPE strToType(const char* str) + { + std::string s = std::string(str); + if (s == "number") return NUMBER; + else if (s == "Image") return IMAGE; + else if (s == "Canvas") return CANVAS; + else if (s == "vec2") return VEC2; + else if (s == "vec3") return VEC3; + else if (s == "vec4") return VEC4; + else if (s == "Color") return COLOR; + else return INVALID; + } + + /** + * Use send function send variables to JSL program. + */ + static int l_send(lua_State* L) + { + Ref<JSLProgram>& ref = checkJSLProgram(L); + // number Image Texel + const char* typestr = luax_checkstring(L, 2); + // variable name + const char* variable = luax_checkstring(L, 3); + if (typestr != nullptr) + { + int type = strToType(typestr); + switch (type) + { + case NUMBER: + { + float number = luax_checknumber(L, 4); + ref->sendFloat(variable, number); + break; + } + case IMAGE: + { + Proxy* proxy = (Proxy*)luax_checktype(L, 4, JIN_GRAPHICS_IMAGE); + Ref<Image>& tex = proxy->getRef<Image>(); + ref->sendTexture(variable, tex.getObject()); + break; + } + case CANVAS: + { + Proxy* proxy = (Proxy*)luax_checktype(L, 4, JIN_GRAPHICS_CANVAS); + Ref<Canvas>& canvas = proxy->getRef<Canvas>(); + ref->sendCanvas(variable, canvas.getObject()); + break; + } + case VEC2: + { + float x = luax_checknumber(L, 4); + float y = luax_checknumber(L, 5); + ref->sendVec2(variable, x, y); + break; + } + case VEC3: + { + float x = luax_checknumber(L, 4); + float y = luax_checknumber(L, 5); + float z = luax_checknumber(L, 6); + ref->sendVec3(variable, x, y, z); + break; + } + case VEC4: + { + float x = luax_checknumber(L, 4); + float y = luax_checknumber(L, 5); + float z = luax_checknumber(L, 6); + float w = luax_checknumber(L, 7); + ref->sendVec4(variable, x, y, z, w); + break; + } + case COLOR: + { + color col; + col.rgba.r = luax_checkinteger(L, 4); + col.rgba.g = luax_checkinteger(L, 5); + col.rgba.b = luax_checkinteger(L, 6); + col.rgba.a = luax_checkinteger(L, 7); + ref->sendColor(variable, &col); + break; + } + default: + return 0; + } + } + return 1; + } + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_SHADER); + proxy->release(); + return 0; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "send", l_send }, + { 0, 0 } + }; + + /** + * JSL program + */ + int luaopen_JSL(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_SHADER, f); + return 0; + } + +} +}
\ No newline at end of file diff --git a/src/lua/modules/graphics/luaopen_graphics.cpp b/src/lua/modules/graphics/luaopen_graphics.cpp new file mode 100644 index 0000000..f0a7f5b --- /dev/null +++ b/src/lua/modules/graphics/luaopen_graphics.cpp @@ -0,0 +1,493 @@ +#include "lua/modules/luax.h" +#include "libjin/jin.h" +#include "lua/common/common.h" +#include "lua/modules/embed/graphics.lua.h" + +namespace jin +{ +namespace lua +{ + using namespace jin::graphics; + using jin::filesystem::Filesystem; + using jin::filesystem::Buffer; + + typedef Texture Image; + + static struct + { + color curRenderColor; + Font* curFont = nullptr; + Font* defaultFont = nullptr; + } context; + + static int l_init(lua_State* L) + { + Window* wnd = Window::get(); + Window::Setting setting; + setting.width = luax_getfield_integer(L, 1, "width"); + setting.height = luax_getfield_integer(L, 1, "height"); + setting.title = luax_getfield_string(L, 1, "title"); + setting.vsync = luax_getfield_bool(L, 1, "vsync"); + setting.fullscreen = luax_getfield_bool(L, 1, "fullscreen"); + setting.resizable= luax_getfield_bool(L, 1, "resizable"); + if (!wnd->init(&setting)) + { + luax_pushboolean(L, false); + return 1; + } + luax_pushboolean(L, true); + return 1; + } + + static int l_destroy(lua_State* L) + { + Window* wnd = Window::get(); + wnd->quit(); + return 0; + } + + static int l_getSize(lua_State* L) + { + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getW()); + luax_pushnumber(L, wnd->getH()); + return 2; + } + + static int l_getWidth(lua_State* L) + { + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getW()); + return 1; + } + + static int l_getHeight(lua_State* L) + { + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getH()); + return 1; + } + + static int l_newImage(lua_State* L) + { + Filesystem* fs = Filesystem::get(); + const char* f = luax_checkstring(L, 1); + if (!fs->exists(f)) + { + printf("Error: no such image %s\n", f); + exit(1); + } + Buffer b; + fs->read(f, &b); + + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_IMAGE, sizeof(Proxy)); + Image* img = Image::createTexture(b.data, b.size); + proxy->bind(new Ref<Image>(img, JIN_GRAPHICS_IMAGE)); + return 1; + } + + static int l_newShader(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_SHADER, sizeof(Proxy)); + const char* program = luax_checkstring(L, 1); + JSLProgram* jsl = JSLProgram::createJSLProgram(program); + proxy->bind(new Ref<JSLProgram>(jsl, JIN_GRAPHICS_SHADER)); + return 1; + } + + static int l_newCanvas(lua_State* L) + { + int w = luax_checknumber(L, 1); + int h = luax_checknumber(L, 2); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_CANVAS, sizeof(Proxy)); + Canvas* cvs = Canvas::createCanvas(w, h); + proxy->bind(new Ref<Canvas>(cvs, JIN_GRAPHICS_CANVAS)); + return 1; + } + + static int l_clear(lua_State* L) + { + if (luax_gettop(L) == 0) + { + glClearColor(0, 0, 0, 1); + } + else + { + int r = luax_checknumber(L, 1); + int g = luax_checknumber(L, 2); + int b = luax_checknumber(L, 3); + int a = luax_checknumber(L, 4); + glClearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f); + } + glClear(GL_COLOR_BUFFER_BIT); + return 0; + } + + static int l_present(lua_State* L) + { + Window::get()->swapBuffers(); + return 0; + } + + static int l_draw(lua_State* L) + { + int x = luax_optnumber(L, 2, 0); + int y = luax_optnumber(L, 3, 0); + float sx = luax_optnumber(L, 4, 1); + float sy = luax_optnumber(L, 5, 1); + float r = luax_optnumber(L, 6, 0); + if (luax_istype(L, 1, JIN_GRAPHICS_IMAGE)) + { + Proxy* proxy = (Proxy*)luax_toudata(L, 1); + Ref<Image>& tex = proxy->getRef<Image>(); + tex->draw(x, y, sx, sy, r); + } + else if (luax_istype(L, 1, JIN_GRAPHICS_CANVAS)) + { + Proxy* proxy = (Proxy*)luax_toudata(L, 1); + Ref<Canvas>& p = proxy->getRef<Canvas>(); + p->draw(x, y, sx, sy, r); + } + else + { + /* wrong type */ + luax_typerror(L, 1, "image or canvas"); + } + return 0; + } + + static int l_setColor(lua_State* L) + { + if (luax_gettop(L) == 0) + { + glColor4f(1, 1, 1, 1); + return 0; + } + + context.curRenderColor.rgba.r = luax_checknumber(L, 1); + context.curRenderColor.rgba.g = luax_checknumber(L, 2); + context.curRenderColor.rgba.b = luax_checknumber(L, 3); + context.curRenderColor.rgba.a = luax_checknumber(L, 4); + + glColor4f(context.curRenderColor.rgba.r / 255.f, + context.curRenderColor.rgba.g / 255.f, + context.curRenderColor.rgba.b / 255.f, + context.curRenderColor.rgba.a / 255.f); + return 0; + } + + static int l_getColor(lua_State * L) + { + luax_pushnumber(L, context.curRenderColor.rgba.r); + luax_pushnumber(L, context.curRenderColor.rgba.g); + luax_pushnumber(L, context.curRenderColor.rgba.b); + luax_pushnumber(L, context.curRenderColor.rgba.a); + return 4; + } + + static int l_bindCanvas(lua_State* L) + { + if (luax_gettop(L) == 0) + { + // bind to default canvas + Canvas::unbind(); + return 0; + } + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_CANVAS); + Ref<Canvas>& ref = proxy->getRef<Canvas>(); + ref->bind(); + return 0; + } + + static int l_unbindCanvas(lua_State* L) + { + Canvas::unbind(); + return 0; + } + + static int l_useShader(lua_State* L) + { + if (luax_gettop(L) == 0) + { + JSLProgram::unuse(); + return 0; + } + if (luax_istype(L, 1, JIN_GRAPHICS_SHADER)) + { + Proxy* proxy = (Proxy*)luax_toudata(L, 1); + Ref<JSLProgram>& jsl = proxy->getRef<JSLProgram>(); + jsl->use(); + } + else + { + luax_typerror(L, 1, "JSL shader"); + } + return 0; + } + + static int l_unuseShader(lua_State* L) + { + JSLProgram::unuse(); + return 0; + } + + static int l_setBlend(lua_State* L) + { + + return 0; + } + + static RENDER_MODE strtomode(const char* str) + { + std::string s = std::string(str); + if (s == "fill") return RENDER_MODE::FILL; + else if (s == "line") return RENDER_MODE::LINE; + else return RENDER_MODE::NONE; + } + + static int l_drawpoint(lua_State* L) + { + int x = luax_checknumber(L, 1); + int y = luax_checknumber(L, 2); + jin::graphics::point(x, y); + + return 0; + } + + static int l_drawLine(lua_State* L) + { + int x1 = luax_checknumber(L, 1); + int y1 = luax_checknumber(L, 2); + int x2 = luax_checknumber(L, 3); + int y2 = luax_checknumber(L, 4); + jin::graphics::line(x1, y1, x2, y2); + + return 0; + } + + static int l_drawRect(lua_State* L) + { + const char* modestr = luax_checkstring(L, 1); + RENDER_MODE mode = strtomode(modestr); + if (mode != RENDER_MODE::NONE) + { + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + int w = luax_checknumber(L, 4); + int h = luax_checknumber(L, 5); + rect(mode, x, y, w, h); + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } + + return 0; + } + + static int l_drawCircle(lua_State* L) + { + const char* modestr = luax_checkstring(L, 1); + RENDER_MODE mode = strtomode(modestr); + if (mode != RENDER_MODE::NONE) + { + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + float r = luax_checknumber(L, 4); + circle(mode, x, y, r); + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } + + return 0; + } + + static int l_drawTriangle(lua_State* L) + { + const char* modestr = luax_checkstring(L, 1); + RENDER_MODE mode = strtomode(modestr); + if (mode != RENDER_MODE::NONE) + { + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + + int x2 = luax_checknumber(L, 3); + int y2 = luax_checknumber(L, 4); + + int x3 = luax_checknumber(L, 5); + int y3 = luax_checknumber(L, 6); + + triangle(mode, x, y, x2, y2, x3, y3); + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } + + return 0; + } + + static int l_drawPolygon(lua_State* L) + { + const char* modestr = luax_checkstring(L, 1); + int n = luax_checknumber(L, 2); + RENDER_MODE mode = strtomode(modestr); + if (mode != RENDER_MODE::NONE) + { + if (!luax_istable(L, 3)) + { + luax_typerror(L, 3, "table"); + return 1; + } + int tn = luax_tableidxlen(L, 3); + if (tn != n * 2) + { + static char* emsg = \ + "number of polygon vertices doesn't match " \ + "provided n, expect %d numbers but get %d"; + luax_error(L, emsg, n * 2, tn); + return 1; + } + float* p = new float[2 * n]; + for (int i = 1; i <= 2 * n; ++i) + p[i - 1] = luax_rawgetnumber(L, 3, i); + polygon(mode, p, n); + delete[] p; + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } + + return 0; + } + + static int l_newFont(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_FONT, sizeof(Proxy)); + Font* font = new Font(); + { + const char* path = luax_checkstring(L, 1); + Filesystem* fs = Filesystem::get(); + Buffer b = {}; + if (!fs->exists(path)) + { + printf("Error: no such font %s\n", path); + exit(1); + } + fs->read(path, &b); + font->loadb((const unsigned char*)b.data); + } + proxy->bind(new Ref<Font>(font, JIN_GRAPHICS_FONT)); + return 1; + } + + static int l_study(lua_State* L) + { + int n = luax_gettop(L); + if (n == 0) + { + if (context.defaultFont == 0) + { + #include "lua/resources/font.ttf.h" + // load default font + context.defaultFont = new Font(); + context.defaultFont->loadb(font_ttf); + } + context.curFont = context.defaultFont; + return 0; + } + Font* font = (Font*)luax_checktype(L, 1, JIN_GRAPHICS_FONT); + context.curFont = font; + return 0; + } + + static int l_write(lua_State* L) + { + if (context.curFont == 0) + return 0; + + const char* text = luax_checkstring(L, 1); + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + + int fh = luax_optnumber(L, 4, 15); + int spacing = luax_optnumber(L, 5, 1); + int lh = luax_optnumber(L, 6, 18); + + context.curFont->render(text, x, y, fh, spacing, lh); + + return 0; + } + + static int l_box(lua_State* L) + { + const char* text = luax_checkstring(L, 1); + int fontheight = luax_checknumber(L, 2); + int spacing = luax_checknumber(L, 3); + int lineheight = luax_checknumber(L, 4); + int w, h; + context.curFont->box(text, fontheight, spacing, lineheight, &w, &h); + luax_pushnumber(L, w); + luax_pushnumber(L, h); + return 2; + } + + static const luaL_Reg f[] = { + { "init", l_init }, + { "size", l_getSize }, + { "getWidth", l_getWidth }, + { "getHeight", l_getHeight }, + { "newImage", l_newImage }, + { "newShader", l_newShader }, + { "newCanvas", l_newCanvas }, + { "newFont", l_newFont }, + { "box", l_box }, + { "write", l_write }, + { "clear", l_clear }, + { "draw", l_draw }, + { "color", l_setColor }, + { "palette", l_getColor }, + { "present", l_present }, + { "study", l_study }, + { "bind", l_bindCanvas }, + { "unbind", l_unbindCanvas }, + { "use", l_useShader }, + { "unuse", l_unuseShader }, + { "point", l_drawpoint }, + { "line", l_drawLine }, + { "rect", l_drawRect }, + { "circle", l_drawCircle }, + { "triangle", l_drawTriangle }, + { "polygon", l_drawPolygon }, + { "destroy", l_destroy }, + { 0, 0 } + }; + + extern int luaopen_Image(lua_State* L); + extern int luaopen_Font(lua_State* L); + extern int luaopen_Canvas(lua_State* L); + extern int luaopen_JSL(lua_State* L); + + int luaopen_graphics(lua_State* L) + { + // register types + luaopen_Image(L); + luaopen_Canvas(L); + luaopen_Font(L); + luaopen_JSL(L); + + // load whole lib + luax_newlib(L, f); + + return 1; + } + +}// lua +}// jin
\ No newline at end of file diff --git a/src/lua/modules/joypad/luaopen_joypad.cpp b/src/lua/modules/joypad/luaopen_joypad.cpp new file mode 100644 index 0000000..d305878 --- /dev/null +++ b/src/lua/modules/joypad/luaopen_joypad.cpp @@ -0,0 +1,21 @@ +#include "libjin/jin.h" +#include "lua/modules/luax.h" + +namespace jin +{ +namespace lua +{ + + static const luaL_Reg f[] = { + { 0, 0 } + }; + + int luaopen_joypad(lua_State* L) + { + luax_newlib(L, f); + + return 1; + } + +} +}
\ No newline at end of file diff --git a/src/lua/modules/keyboard/luaopen_keyboard.cpp b/src/lua/modules/keyboard/luaopen_keyboard.cpp new file mode 100644 index 0000000..9d27a4f --- /dev/null +++ b/src/lua/modules/keyboard/luaopen_keyboard.cpp @@ -0,0 +1,16 @@ +#include "lua/modules/luax.h" +#include "lua/modules/embed/keyboard.lua.h" + +namespace jin +{ +namespace lua +{ + + int luaopen_keyboard(lua_State* L) + { + luax_newlib(L, 0); + return 1; + } + +} +}
\ No newline at end of file diff --git a/src/lua/modules/luaopen_jin.cpp b/src/lua/modules/luaopen_jin.cpp new file mode 100644 index 0000000..dbbac31 --- /dev/null +++ b/src/lua/modules/luaopen_jin.cpp @@ -0,0 +1,104 @@ +#include "luaopen_jin.h" +#include "lua/modules/luax.h" +#include "embed/embed.h" + +namespace jin +{ +namespace lua +{ + + extern int luaopen_core(lua_State* L); + extern int luaopen_graphics(lua_State* L); + extern int luaopen_audio(lua_State* L); + extern int luaopen_net(lua_State* L); + extern int luaopen_event(lua_State* L); + extern int luaopen_time(lua_State* L); + extern int luaopen_mouse(lua_State* L); + extern int luaopen_keyboard(lua_State* L); + extern int luaopen_filesystem(lua_State* L); + extern int luaopen_joypad(lua_State* L); + extern int luaopen_math(lua_State* L); + extern int luaopen_thread(lua_State* L); + extern int luaopen_bit(lua_State* L); + + static int l_getversion(lua_State* L) + { + luax_pushstring(L, VERSION); + return 1; + } + + static int l_getAuthor(lua_State* L) + { + luax_pushstring(L, AUTHOR); + return 1; + } + + static int l_getOS(lua_State* L) + { + #ifdef _WIN32 + luax_pushstring(L, "windows"); + #elif defined __unix__ + luax_pushstring(L, "unix"); + #elif defined __APPLE__ + luax_pushstring(L, "macos"); + #endif + return 1; + } + + static int l_revision(lua_State* L) + { + luax_pushnumber(L, REVISION); + return 1; + } + + static const luaL_Reg f[] = { + { "version", l_getversion }, + { "revision", l_revision }, + { "author", l_getAuthor }, + { "os", l_getOS }, + { 0, 0 } + }; + + // submodules + static const luaL_Reg mods[] = { + { "core", luaopen_core }, + { "event", luaopen_event }, + { "graphics", luaopen_graphics }, + { "time", luaopen_time }, + { "mouse", luaopen_mouse }, + { "keyboard", luaopen_keyboard }, + { "filesystem", luaopen_filesystem }, + { "net", luaopen_net }, + { "audio", luaopen_audio }, + { "joypad", luaopen_joypad }, + { "math", luaopen_math }, + { "thread", luaopen_thread }, + { "bit", luaopen_bit }, + { 0, 0 } + }; + + int luaopen_jin(lua_State* L) + { + // jin module is on top of the stack + luax_newlib(L, f); + + // set to global field + luax_justglobal(L, -1, MODULE_NAME); + + // register submodules + for (int i = 0; mods[i].name; ++i) + { + mods[i].func(L); + luax_setfield(L, -2, mods[i].name); + } + + return 1; + } + + void boot(lua_State* L) + { + jin::embed::boot(L); + } + +} // lua +} // jin
\ No newline at end of file diff --git a/src/lua/modules/luaopen_jin.h b/src/lua/modules/luaopen_jin.h new file mode 100644 index 0000000..07531b2 --- /dev/null +++ b/src/lua/modules/luaopen_jin.h @@ -0,0 +1,42 @@ +/** +* Copyright (C) 2016~2018 chai +* +* Permission is hereby granted, free of charge, to any person obtaining a copyof +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to use, +* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the +* Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef __JIN_M_JIN_H +#define __JIN_M_JIN_H +#include "luax.h" + +#define MODULE_NAME "jin" +#define VERSION "0.1.1" +#define REVISION 101 +#define AUTHOR "chai" + +namespace jin +{ +namespace lua +{ + + int luaopen_jin(lua_State* L); + void boot(lua_State* L); + +} // jin +} // lua + +#endif // __JIN_M_JIN_H
\ No newline at end of file diff --git a/src/lua/modules/luax.h b/src/lua/modules/luax.h new file mode 100644 index 0000000..89e456e --- /dev/null +++ b/src/lua/modules/luax.h @@ -0,0 +1,7 @@ +#ifndef __JIN_LUA_LUAX_H +#define __JIN_LUA_LUAX_H + +#include "LuaJIT/lua.hpp" +#include "lua/libraries/luax/luax.h" + +#endif
\ No newline at end of file diff --git a/src/lua/modules/math/luaopen_math.cpp b/src/lua/modules/math/luaopen_math.cpp new file mode 100644 index 0000000..fa59e04 --- /dev/null +++ b/src/lua/modules/math/luaopen_math.cpp @@ -0,0 +1,30 @@ +#include "lua/modules/luax.h" +#include "libjin/jin.h" + +namespace jin +{ +namespace lua +{ + + static int l_mod(lua_State* L) + { + int n = luax_checkinteger(L, 1); + int m = luax_checkinteger(L, 2); + int mod = n % m; + luax_pushinteger(L, mod); + return 1; + } + + static const luaL_Reg f[] = { + { "mod", l_mod }, + { 0, 0 } + }; + + int luaopen_math(lua_State* L) + { + luax_newlib(L, f); + return 1; + } + +} +}
\ No newline at end of file diff --git a/src/lua/modules/mouse/luaopen_mouse.cpp b/src/lua/modules/mouse/luaopen_mouse.cpp new file mode 100644 index 0000000..f907abb --- /dev/null +++ b/src/lua/modules/mouse/luaopen_mouse.cpp @@ -0,0 +1,31 @@ +#include "lua/modules/luax.h" +#include "libjin/jin.h" + +namespace jin +{ +namespace lua +{ + using namespace jin::input; + + static int l_pos(lua_State* L) + { + static Mouse* mouse = Mouse::get(); + int x, y; + mouse->getState(&x, &y); + luax_pushnumber(L, x); + luax_pushnumber(L, y); + return 2; + } + + static const luaL_Reg f[] = { + { "position", l_pos }, + { 0, 0 } + }; + + int luaopen_mouse(lua_State* L) + { + luax_newlib(L, f); + return 1; + } +} +}
\ No newline at end of file diff --git a/src/lua/modules/net/Buffer.h b/src/lua/modules/net/Buffer.h new file mode 100644 index 0000000..31e6df8 --- /dev/null +++ b/src/lua/modules/net/Buffer.h @@ -0,0 +1,96 @@ +#ifndef __JIN_LUA_NET_NETBUFFER_H +#define __JIN_LUA_NET_NETBUFFER_H + +#include <cstring> +#include <cstdlib> +#include "lua/common/common.h" + +namespace jin +{ +namespace lua +{ +namespace net +{ + + class Buffer + { + public: + Buffer(size_t s = 0) + : size(s) + { + buffer = new char[size]; + memset(buffer, 0, size); + } + + Buffer(const char* data, size_t s) + : size(s) + { + buffer = new char[size]; + memcpy(buffer, data, size); + } + + ~Buffer() + { + if (buffer != nullptr) + { + delete[] buffer; + buffer = nullptr; + size = 0; + } + } + + void append(const void* data, size_t s) + { + if (data == nullptr) + return; + char* buf = buffer; + buffer = new char[size + s]; + memcpy(buffer, buf, size); + memcpy(buffer + size, data, s); + delete[] buf; + size += s; + return; + } + + const char* grabString(int* length, int offset = 0) + { + int l = offset; + for (; l < size; ++l) + { + if (buffer[l] == 0) + break; + } + *length = l - offset + 1; + char* str = (char*)malloc(*length); + memcpy(str, buffer + offset, *length); + return str; + } + + int grabInteger(int* length, int offset = 0) + { + *length = sizeof(int); + return *((int*)(buffer + offset)); + } + + float grabFloat(int* length, int offset = 0) + { + *length = sizeof(float); + return *((float*)(buffer + offset)); + } + + bool grabBoolean(int* length, int offset = 0) + { + *length = sizeof(bool); + return *((bool*)(buffer + offset)); + } + + char* buffer; + size_t size; + + }; + +} // net +} // lua +} // jin + +#endif
\ No newline at end of file diff --git a/src/lua/modules/net/luaopen_Buffer.cpp b/src/lua/modules/net/luaopen_Buffer.cpp new file mode 100644 index 0000000..cb5b952 --- /dev/null +++ b/src/lua/modules/net/luaopen_Buffer.cpp @@ -0,0 +1,135 @@ +#include "lua/modules/luax.h" +#include "lua/common/common.h" +#include "libjin/jin.h" +#include "Buffer.h" + +namespace jin +{ +namespace lua +{ +namespace net +{ + + static inline Ref<Buffer>& checkNetBuffer(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_NETWORK_BUFFER); + return proxy->getRef<Buffer>(); + } + + // net.Buffer:append(value) -> value_length + static int l_append(lua_State* L) + { + Ref<Buffer>& ref = checkNetBuffer(L); + const int vp = 2; + if (luax_isintegerstrict(L, vp)) + { + int n = luax_checkinteger(L, vp); + int size = sizeof(n); + ref->append(&n, size); + luax_pushinteger(L, size); + return 1; + } + else if (luax_isfloatstrict(L, vp)) + { + float n = luax_checknumber(L, vp); + int size = sizeof(n); + ref->append(&n, size); + luax_pushinteger(L, size); + return 1; + } + else if (luax_isbooleanstrict(L, vp)) + { + bool n = luax_checkbool(L, vp); + int size = sizeof(n); + ref->append(&n, size); + luax_pushinteger(L, size); + return 1; + } + else if (luax_isstringstrict(L, vp)) + { + const char* str = luax_checkstring(L, vp); + int size = strlen(str) + 1; + ref->append(str, size); + luax_pushinteger(L, size); + return 1; + } + else + { + luax_typerror(L, vp, "number, bool or string"); + return 0; + } + } + + // net.Buffer:grabString(offset) -> string, length + static int l_grabString(lua_State* L) + { + Ref<Buffer>& ref = checkNetBuffer(L); + int offset = luax_checkinteger(L, 2); + int len; + const char* str = ref->grabString(&len, offset); + luax_pushstring(L, str); + luax_pushinteger(L, len); + return 2; + } + + // net.Buffer:grabInteger(offset) -> integer, length + static int l_grabInteger(lua_State* L) + { + Ref<Buffer>& ref = checkNetBuffer(L); + int offset = luax_checkinteger(L, 2); + int len; + int integer = ref->grabInteger(&len, offset); + luax_pushinteger(L, integer); + luax_pushinteger(L, len); + return 2; + } + + static int l_grabFloat(lua_State* L) + { + Ref<Buffer>& ref = checkNetBuffer(L); + int offset = luax_checkinteger(L, 2); + int len; + float floatv = ref->grabFloat(&len, offset); + luax_pushnumber(L, floatv); + luax_pushinteger(L, len); + return 2; + } + + static int l_grabBoolean(lua_State* L) + { + Ref<Buffer>& ref = checkNetBuffer(L); + int offset = luax_checkinteger(L, 2); + int len; + bool boolean = ref->grabBoolean(&len, offset); + luax_pushboolean(L, boolean); + luax_pushinteger(L, len); + return 2; + } + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_NETWORK_BUFFER); + proxy->release(); + return 0; + } + + static const luaL_Reg netbuffer_function[] = { + { "__gc", l_gc }, + { "append", l_append }, + { "grabString", l_grabString }, + { "grabInteger", l_grabInteger }, + { "grabBoolean", l_grabBoolean }, + { "grabFloat", l_grabFloat }, + { 0, 0 } + }; + +} // net + + int luaopen_Buffer(lua_State* L) + { + luax_newtype(L, JIN_NETWORK_BUFFER, net::netbuffer_function); + return 0; + } + +} // lua +} // jin
\ No newline at end of file diff --git a/src/lua/modules/net/luaopen_Socket.cpp b/src/lua/modules/net/luaopen_Socket.cpp new file mode 100644 index 0000000..2e5d9f3 --- /dev/null +++ b/src/lua/modules/net/luaopen_Socket.cpp @@ -0,0 +1,126 @@ +#include "lua/modules/luax.h" +#include "lua/common/common.h" +#include "libjin/jin.h" +#include "Buffer.h" + +namespace jin +{ +namespace lua +{ + + using namespace jin::net; + using namespace lua::net; + + const int BUFFER_SIZE = 1024; + + static inline Ref<Socket>& checkSocket(lua_State* L, int pos = 1) + { + Proxy* proxy = (Proxy*)luax_checktype(L, pos, JIN_NETWORK_SOCKET); + return proxy->getRef<Socket>(); + } + + static inline Ref<Buffer>& checkNetBuffer(lua_State* L, int pos = 1) + { + Proxy* proxy = (Proxy*)luax_checktype(L, pos, JIN_NETWORK_BUFFER); + return proxy->getRef<Buffer>(); + } + + // return net.Socket + static int l_accept(lua_State* L) + { + Ref<Socket>& socket = checkSocket(L); + Socket* client = socket->accept(); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_SOCKET, sizeof(Proxy)); + proxy->bind(new Ref<Socket>(client, JIN_NETWORK_SOCKET)); + return 1; + } + + // return net.Buffer + static int l_receive(lua_State* L) + { + Ref<Socket>& socket = checkSocket(L); + char buffer[BUFFER_SIZE] = {0}; + int size = socket->receive(buffer, BUFFER_SIZE); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_BUFFER, sizeof(Proxy)); + net::Buffer* netBuffer = new net::Buffer(buffer, size); + proxy->bind(new Ref<Buffer>(netBuffer, JIN_NETWORK_BUFFER)); + return 1; + } + + // Socket:receiveFrom(address, port) + static int l_receiveFrom(lua_State* L) + { + Ref<Socket>& socket = checkSocket(L); + int address = luax_checkinteger(L, 2); + int port = luax_checkinteger(L, 3); + char buffer[BUFFER_SIZE]; + int size = socket->receiveFrom(buffer, BUFFER_SIZE, address, port); + net::Buffer* netBuffer = new net::Buffer(buffer, size); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_BUFFER, sizeof(Proxy)); + proxy->bind(new Ref<Buffer>(netBuffer, JIN_NETWORK_BUFFER)); + return 1; + } + + // Socket:send(net.Buffer) -> data_length + static int l_send(lua_State* L) + { + Ref<Socket>& socket = checkSocket(L); + Ref<Buffer>& ref = checkNetBuffer(L, 2); + int len = socket->send(ref->buffer, ref->size); + luax_pushinteger(L, len); + return 1; + } + + // Socket:sendTo(address, port, net.Buffer) + static int l_sendTo(lua_State* L) + { + Ref<Socket>& socket = checkSocket(L); + int address = luax_checkinteger(L, 2); + int port = luax_checkinteger(L, 3); + Ref<Buffer>& buffer = checkNetBuffer(L, 4); + socket->sendTo(buffer->buffer, buffer->size, address, port); + return 0; + } + + static int l_close(lua_State* L) + { + Ref<Socket>& socket = checkSocket(L); + socket->close(); + return 0; + } + + static int l_configBlocking(lua_State* L) + { + Ref<Socket>& socket = checkSocket(L); + bool blocking = luax_checkbool(L, 2); + socket->configureBlocking(blocking); + return 0; + } + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_NETWORK_SOCKET); + proxy->release(); + return 0; + } + + static const luaL_Reg socket_function[] = { + { "__gc", l_gc }, + { "accept", l_accept }, + { "receive", l_receive }, + { "receiveFrom", l_receiveFrom }, + { "send", l_send }, + { "sendTo", l_sendTo }, + { "close", l_close }, + { "configBlocking", l_configBlocking }, + { 0, 0 } + }; + + int luaopen_Socket(lua_State* L) + { + luax_newtype(L, JIN_NETWORK_SOCKET, socket_function); + return 0; + } + +} // lua +} // jin
\ No newline at end of file diff --git a/src/lua/modules/net/luaopen_net.cpp b/src/lua/modules/net/luaopen_net.cpp new file mode 100644 index 0000000..e7e55c4 --- /dev/null +++ b/src/lua/modules/net/luaopen_net.cpp @@ -0,0 +1,86 @@ +#include "lua/modules/luax.h" +#include "libjin/jin.h" +#include "lua/common/common.h" +#include "Buffer.h" + +namespace jin +{ +namespace lua +{ + using namespace jin::lua::net; + using namespace jin::net; + + static int l_initNetwork(lua_State* L) + { + jin::net::Net::get()->init(); + return 1; + } + + // jin.net.Socket() + static int l_Socket(lua_State* L) + { + SocketInformation info = { 0 }; + { + const char* socketType = luax_checkstring(L, 1); + if (strcmp(socketType, "TCP") == 0) + info.type = SocketType::TCP; + else if (strcmp(socketType, "UDP") == 0) + info.type = SocketType::UDP; + else + { + luax_error(L, "jin.net.Socket() first paramter wrong, must be TCP or UDP"); + return 0; + } + // type, port + if (luax_gettop(L) == 2) + { + info.port = luax_checkinteger(L, 2); + } + // type, address, port + else if (luax_gettop(L) == 3) + { + if (luax_isstringstrict(L, 2)) + info.address = tk_strtohl(luax_checkstring(L, 2)); + else if (luax_isintegerstrict(L, 2)) + info.address = luax_checkinteger(L, 2); + info.port = luax_checkinteger(L, 3); + } + } + Socket* socket = new Socket(info); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_SOCKET, sizeof(Proxy)); + proxy->bind(new Ref<Socket>(socket, JIN_NETWORK_SOCKET)); + return 1; + } + + // jin.net.Buffer() + static int l_Buffer(lua_State* L) + { + int size = luax_checkinteger(L, 1); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_BUFFER, sizeof(Proxy)); + net::Buffer* buffer = new net::Buffer(size); + proxy->bind(new Ref<Buffer>(buffer, JIN_NETWORK_BUFFER)); + return 1; + } + + static const luaL_Reg f[] = { + { "init", l_initNetwork }, + { "newSocket", l_Socket }, + { "newBuffer", l_Buffer }, + { 0, 0 } + }; + + extern int luaopen_Socket(lua_State* L); + extern int luaopen_Buffer(lua_State* L); + + int luaopen_net(lua_State* L) + { + luaopen_Socket(L); + luaopen_Buffer(L); + + luax_newlib(L, f); + + return 1; + } + +} // lua +} // jin
\ No newline at end of file diff --git a/src/lua/modules/thread/Thread.cpp b/src/lua/modules/thread/Thread.cpp new file mode 100644 index 0000000..8df3255 --- /dev/null +++ b/src/lua/modules/thread/Thread.cpp @@ -0,0 +1,14 @@ +#include "Thread.h" + +namespace jin +{ +namespace lua +{ +namespace thread +{ + + + +} // thread +} // lua +} // jin
\ No newline at end of file diff --git a/src/lua/modules/thread/Thread.h b/src/lua/modules/thread/Thread.h new file mode 100644 index 0000000..645d4a1 --- /dev/null +++ b/src/lua/modules/thread/Thread.h @@ -0,0 +1,94 @@ +#include "libjin/jin.h" +#include "lua/common/common.h" + +namespace jin +{ +namespace lua +{ +namespace thread +{ + + class Thread + { + public: + typedef jin::thread::Thread::Variant Variant; + typedef jin::thread::Thread::ThreadRunner ThreadRunner; + + Thread(std::string _name, std::string _code, ThreadRunner runner) + : name(_name) + , code(_code) + { + thread = new jin::thread::Thread(_name, runner); + } + + ~Thread() + { + delete thread; + } + + bool start(void* p) + { + return thread->start(p); + } + + void wait() + { + thread->wait(); + } + + void send(int slot, const Variant& value) + { + thread->send(slot, value); + } + + bool receive(int slot) + { + return thread->receive(slot); + } + + Variant fetch(int slot) + { + return thread->fetch(slot); + } + + Variant demand(int slot) + { + return thread->demand(slot); + } + + void remove(int slot) + { + thread->remove(slot); + } + + const char* getName() + { + return name.c_str(); + } + + bool isRunning() + { + return thread->isRunning(); + } + + void lock() + { + thread->lock(); + } + + void unlock() + { + thread->unlock(); + } + + const std::string name; + const std::string code; + + private: + jin::thread::Thread* thread; + + }; + +} // thread +} // lua +} // jin
\ No newline at end of file diff --git a/src/lua/modules/thread/luaopen_thread.cpp b/src/lua/modules/thread/luaopen_thread.cpp new file mode 100644 index 0000000..65a7c29 --- /dev/null +++ b/src/lua/modules/thread/luaopen_thread.cpp @@ -0,0 +1,248 @@ +#include "lua/modules/luax.h" +#include "libjin/jin.h" +#include "lua/modules/luaopen_jin.h" +#include "lua/common/common.h" +#include "Thread.h" + +namespace jin +{ +namespace lua +{ + + using thread::Thread; + + int luaopen_thread(lua_State* L); + + static inline Ref<Thread>& checkThread(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_THREAD_THREAD); + return proxy->getRef<Thread>(); + } + + static int threadRunner(void* t) + { + Ref<Thread>& ref = *(Ref<Thread>*)t; + lua_State* L = lua_open(); + luax_openlibs(L); + luaopen_jin(L); + luax_getglobal(L, MODULE_NAME); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_THREAD_THREAD, sizeof(Proxy)); + ref.retain(); + proxy->bind(&ref); + luax_setfield(L, -2, "_curThread"); + luax_dostring(L, ref->code.c_str()); + luax_close(L); + return 0; + } + + static int l_thread_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_THREAD_THREAD); + proxy->release(); + return 0; + } + + static int l_start(lua_State* L) + { + Ref<Thread>& ref = checkThread(L); + bool result = ref->start(&ref); + luax_pushboolean(L, result); + return 1; + } + + static int l_wait(lua_State* L) + { + Ref<Thread>& ref = checkThread(L); + ref->wait(); + return 0; + } + + static int l_send(lua_State* L) + { + Ref<Thread>& ref = checkThread(L); + int slot = luax_checkinteger(L, 2); + const int vp = 3; + if (luax_isnumberstrict(L, vp)) + { + float real = luax_checknumber(L, vp); + ref->send(slot, real); + } + else if (luax_isbooleanstrict(L, vp)) + { + bool bol = luax_checkbool(L, vp); + ref->send(slot, bol); + } + else if (luax_isstringstrict(L, vp)) + { + const char* str = luax_checkstring(L, vp); + ref->send(slot, str); + } + else if (luax_isuserdata(L, vp)) + { + void* p = luax_touserdata(L, vp); + ref->send(slot, p); + } + else if (luax_islightuserdata(L, vp)) + { + void* p = luax_tolightuserdata(L, vp); + ref->send(slot, p); + } + return 0; + } + + static int l_receive(lua_State* L) + { + Ref<Thread>& ref = checkThread(L); + int slot = luax_checkinteger(L, 2); + bool result = ref->receive(slot); + luax_pushboolean(L, result); + return 1; + } + + static int l_fetch(lua_State* L) + { + Ref<Thread>& ref = checkThread(L); + int slot = luax_checkinteger(L, 2); + Thread::Variant v = ref->fetch(slot); + switch (v.type) + { + case thread::Thread::Variant::INTERGER: + luax_pushinteger(L, v.integer); + break; + + case thread::Thread::Variant::BOOLEAN: + luax_pushboolean(L, v.boolean); + break; + + case thread::Thread::Variant::CSTRING: + luax_pushstring(L, v.cstring); + break; + + case thread::Thread::Variant::REAL: + luax_pushnumber(L, v.real); + break; + + case thread::Thread::Variant::POINTER: + Proxy* p = (Proxy*)v.pointer; + Proxy* proxy = (Proxy*)luax_newinstance(L, p->getObjectType(), sizeof(Proxy)); + p->reference->retain(); + proxy->bind(p->reference); + break; + + } + return 1; + } + + static int l_demand(lua_State* L) + { + Ref<Thread>& ref = checkThread(L); + int slot = luax_checkinteger(L, 2); + Thread::Variant v = ref->demand(slot); + switch (v.type) + { + case thread::Thread::Variant::INTERGER: + luax_pushinteger(L, v.integer); + break; + + case thread::Thread::Variant::BOOLEAN: + luax_pushboolean(L, v.boolean); + break; + + case thread::Thread::Variant::CSTRING: + luax_pushstring(L, v.cstring); + break; + + case thread::Thread::Variant::REAL: + luax_pushnumber(L, v.real); + break; + + case thread::Thread::Variant::POINTER: + Proxy* p = (Proxy*)v.pointer; + Proxy* proxy = (Proxy*)luax_newinstance(L, p->getObjectType(), sizeof(Proxy)); + p->reference->retain(); + proxy->bind(p->reference); + break; + + } + return 1; + } + + static int l_remove(lua_State* L) + { + Ref<Thread>& ref = checkThread(L); + int slot = luax_checkinteger(L, 2); + ref->remove(slot); + return 0; + } + + static int l_getName(lua_State* L) + { + Ref<Thread>& ref = checkThread(L); + const char* name = ref->getName(); + luax_pushstring(L, name); + return 1; + } + + static int l_isRunning(lua_State* L) + { + Ref<Thread>& ref = checkThread(L); + bool running = ref->isRunning(); + luax_pushboolean(L, running); + return 1; + } + + static const luaL_Reg thread_function[] = { + { "__gc", l_thread_gc }, + { "start", l_start }, + { "wait", l_wait }, + { "send", l_send }, + { "receive", l_receive }, + { "fetch", l_fetch }, + { "demand", l_demand }, + { "remove", l_remove }, + { "getName", l_getName }, + { "isRunning", l_isRunning }, + { 0, 0 } + }; + + static int luaopen_Thread(lua_State* L) + { + luax_newtype(L, JIN_THREAD_THREAD, thread_function); + + return 0; + } + + static int l_newThread(lua_State* L) + { + const char* name = luax_checkstring(L, 1); + const char* code = luax_checkstring(L, 2); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_THREAD_THREAD, sizeof(Proxy)); + Thread* thread = new Thread(name, code, threadRunner); + proxy->bind(new Ref<Thread>(thread, JIN_THREAD_THREAD)); + return 1; + } + + static int l_getThread(lua_State* L) + { + luax_getglobal(L, MODULE_NAME); + luax_getfield(L, -1, "_curThread"); + return 1; + } + + static const luaL_Reg f[] = { + { "newThread", l_newThread }, + { "getThread", l_getThread }, + { 0, 0 } + }; + + int luaopen_thread(lua_State* L) + { + luaopen_Thread(L); + + luax_newlib(L, f); + + return 1; + } + +} // lua +} // jin
\ No newline at end of file diff --git a/src/lua/modules/time/luaopen_time.cpp b/src/lua/modules/time/luaopen_time.cpp new file mode 100644 index 0000000..39743b4 --- /dev/null +++ b/src/lua/modules/time/luaopen_time.cpp @@ -0,0 +1,38 @@ +#include "lua/modules/luax.h" +#include <SDL2/SDL.h> +#include "libjin/jin.h" + +namespace jin +{ +namespace lua +{ + + using namespace jin::time; + + static int l_sec(lua_State* L) + { + luax_pushnumber(L, getSecond()); + return 1; + } + + static int l_sleep(lua_State* L) + { + double sec = luax_checknumber(L, 1); + sleep(sec * 1000.0f); + return 0; + } + + static const luaL_Reg f[] = { + { "second", l_sec }, + { "sleep", l_sleep }, + { 0, 0 }, + }; + + int luaopen_time(lua_State* L) + { + luax_newlib(L, f); + return 1; + } + +} // lua +} // jin
\ No newline at end of file |