diff options
Diffstat (limited to 'src/lua/modules/thread/Thread.cpp')
-rw-r--r-- | src/lua/modules/thread/Thread.cpp | 243 |
1 files changed, 239 insertions, 4 deletions
diff --git a/src/lua/modules/thread/Thread.cpp b/src/lua/modules/thread/Thread.cpp index 8df3255..5c9cb1f 100644 --- a/src/lua/modules/thread/Thread.cpp +++ b/src/lua/modules/thread/Thread.cpp @@ -1,14 +1,249 @@ -#include "Thread.h" +#include "lua/modules/luax.h" +#include "lua/modules/types.h" +#include "libjin/jin.h" +#include "lua/modules/jin.h" +#include "lua/common/common.h" +#include "thread.h" namespace jin { namespace lua { -namespace thread -{ + 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; + } -} // thread } // lua } // jin
\ No newline at end of file |