aboutsummaryrefslogtreecommitdiff
path: root/src/lua/modules/thread/je_lua_thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua/modules/thread/je_lua_thread.cpp')
-rw-r--r--src/lua/modules/thread/je_lua_thread.cpp252
1 files changed, 252 insertions, 0 deletions
diff --git a/src/lua/modules/thread/je_lua_thread.cpp b/src/lua/modules/thread/je_lua_thread.cpp
new file mode 100644
index 0000000..d086595
--- /dev/null
+++ b/src/lua/modules/thread/je_lua_thread.cpp
@@ -0,0 +1,252 @@
+#include "lua/modules/luax.h"
+#include "lua/modules/types.h"
+#include "libjin/jin.h"
+#include "lua/jin.h"
+#include "lua/common/common.h"
+#include "je_lua_thread.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ using thread::Thread;
+
+ typedef Ref<Thread>& ThreadRef;
+
+ int luaopen_thread(lua_State* L);
+
+ static inline ThreadRef checkThread(lua_State* L)
+ {
+ Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_THREAD_THREAD);
+ return proxy->getRef<Thread>();
+ }
+
+ static int threadRunner(void* t)
+ {
+ ThreadRef 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)
+ {
+ ThreadRef ref = checkThread(L);
+ bool result = ref->start(&ref);
+ luax_pushboolean(L, result);
+ return 1;
+ }
+
+ static int l_wait(lua_State* L)
+ {
+ ThreadRef ref = checkThread(L);
+ ref->wait();
+ return 0;
+ }
+
+ static int l_send(lua_State* L)
+ {
+ ThreadRef 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)
+ {
+ ThreadRef 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)
+ {
+ ThreadRef 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)
+ {
+ ThreadRef 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;
+ const char* objType = p->getObjectType();
+ Proxy* proxy = (Proxy*)luax_newinstance(L, objType, sizeof(Proxy));
+ p->reference->retain();
+ proxy->bind(p->reference);
+ break;
+
+ }
+ return 1;
+ }
+
+ static int l_remove(lua_State* L)
+ {
+ ThreadRef ref = checkThread(L);
+ int slot = luax_checkinteger(L, 2);
+ ref->remove(slot);
+ return 0;
+ }
+
+ static int l_getName(lua_State* L)
+ {
+ ThreadRef ref = checkThread(L);
+ const char* name = ref->getName();
+ luax_pushstring(L, name);
+ return 1;
+ }
+
+ static int l_isRunning(lua_State* L)
+ {
+ ThreadRef 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;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file