diff --git a/src/luastate.cc b/src/luastate.cc index 083efa2..7a0b0f9 100644 --- a/src/luastate.cc +++ b/src/luastate.cc @@ -15,6 +15,15 @@ struct async_baton{ LuaState* state; }; +struct simple_baton{ + bool has_cb; + Persistent callback; + int data; + int result; + LuaState* state; +}; + + void do_file(uv_work_t *req){ async_baton* baton = static_cast(req->data); @@ -25,6 +34,43 @@ void do_file(uv_work_t *req){ } +void do_gc(uv_work_t *req){ + simple_baton* baton = static_cast(req->data); + + baton->result = lua_gc(baton->state->lua_, baton->data, 0); +} + + +void do_status(uv_work_t *req){ + simple_baton* baton = static_cast(req->data); + + baton->result = lua_status(baton->state->lua_); +} + + +void simple_after(uv_work_t *req){ + HandleScope scope; + + simple_baton* baton = static_cast(req->data); + + const int argc = 1; + Local argv[] = { Number::New(baton->result) }; + + TryCatch try_catch; + + if(baton->has_cb){ + baton->callback->Call(Context::GetCurrent()->Global(), argc, argv); + } + + baton->callback.Dispose(); + delete baton; + delete req; + + if(try_catch.HasCaught()){ + node::FatalException(try_catch); + } +} + void do_string(uv_work_t *req){ async_baton* baton = static_cast(req->data); @@ -65,7 +111,7 @@ void async_after(uv_work_t *req){ delete baton; delete req; - if (try_catch.HasCaught()) { + if(try_catch.HasCaught()){ node::FatalException(try_catch); } } @@ -97,10 +143,19 @@ void LuaState::Init(Handle target){ tpl->PrototypeTemplate()->Set(String::NewSymbol("status"), FunctionTemplate::New(Status)->GetFunction()); - tpl->PrototypeTemplate()->Set(String::NewSymbol("close"), - FunctionTemplate::New(Close)->GetFunction()); + tpl->PrototypeTemplate()->Set(String::NewSymbol("statusSync"), + FunctionTemplate::New(StatusSync)->GetFunction()); + tpl->PrototypeTemplate()->Set(String::NewSymbol("collectGarbage"), FunctionTemplate::New(CollectGarbage)->GetFunction()); + tpl->PrototypeTemplate()->Set(String::NewSymbol("collectGarbageSync"), + FunctionTemplate::New(CollectGarbageSync)->GetFunction()); + + tpl->PrototypeTemplate()->Set(String::NewSymbol("close"), + FunctionTemplate::New(Close)->GetFunction()); + tpl->PrototypeTemplate()->Set(String::NewSymbol("getName"), + FunctionTemplate::New(GetName)->GetFunction()); + tpl->PrototypeTemplate()->Set(String::NewSymbol("registerFunction"), FunctionTemplate::New(RegisterFunction)->GetFunction()); @@ -145,7 +200,16 @@ Handle LuaState::New(const Arguments& args){ return ThrowException(Exception::TypeError(String::New("LuaState Requires The 'new' Operator To Create An Instance"))); } + if(!args.Length() > 0){ + return ThrowException(Exception::TypeError(String::New("LuaState Requires 1 Argument"))); + } + + if(!args[0]->IsString()){ + return ThrowException(Exception::TypeError(String::New("LuaState First Argument Must Be A String"))); + } + LuaState* obj = new LuaState(); + obj->name_ = get_str(args[0]); obj->lua_ = lua_open(); luaL_openlibs(obj->lua_); obj->Wrap(args.This()); @@ -154,6 +218,14 @@ Handle LuaState::New(const Arguments& args){ } +Handle LuaState::GetName(const Arguments& args){ + HandleScope scope; + + LuaState* obj = ObjectWrap::Unwrap(args.This()); + return scope.Close(String::New(obj->name_)); +} + + Handle LuaState::DoFileSync(const Arguments& args){ HandleScope scope; @@ -341,6 +413,31 @@ Handle LuaState::Close(const Arguments& args){ Handle LuaState::Status(const Arguments& args){ + HandleScope scope; + LuaState* obj = ObjectWrap::Unwrap(args.This()); + simple_baton* baton = new simple_baton(); + baton->state = obj; + obj->Ref(); + + if(args.Length() > 0 && !args[0]->IsFunction()){ + ThrowException(Exception::TypeError(String::New("LuaState.status First Argument Must Be A Function"))); + return scope.Close(Undefined()); + } + + if(args.Length() > 0){ + baton->has_cb = true; + baton->callback = Persistent::New(Local::Cast(args[0])); + } + + uv_work_t *req = new uv_work_t; + req->data = baton; + uv_queue_work(uv_default_loop(), req, do_status, simple_after); + + return scope.Close(Undefined()); +} + + +Handle LuaState::StatusSync(const Arguments& args){ HandleScope scope; LuaState* obj = ObjectWrap::Unwrap(args.This()); int status = lua_status(obj->lua_); @@ -362,6 +459,45 @@ Handle LuaState::CollectGarbage(const Arguments& args){ return scope.Close(Undefined()); } + LuaState* obj = ObjectWrap::Unwrap(args.This()); + int type = (int)args[0]->ToNumber()->Value(); + + simple_baton* baton = new simple_baton(); + baton->data = type; + baton->state = obj; + obj->Ref(); + + if(args.Length() > 1 && !args[1]->IsFunction()){ + ThrowException(Exception::TypeError(String::New("LuaState.collectGarbage Second Argument Must Be A Function"))); + return scope.Close(Undefined()); + } + + if(args.Length() > 1){ + baton->has_cb = true; + baton->callback = Persistent::New(Local::Cast(args[1])); + } + + uv_work_t *req = new uv_work_t; + req->data = baton; + uv_queue_work(uv_default_loop(), req, do_gc, simple_after); + + return scope.Close(Undefined()); +} + + +Handle LuaState::CollectGarbageSync(const Arguments& args){ + HandleScope scope; + + if(args.Length() < 1){ + ThrowException(Exception::TypeError(String::New("LuaState.collectGarbageSync Requires 1 Argument"))); + return scope.Close(Undefined()); + } + + if(!args[0]->IsNumber()){ + ThrowException(Exception::TypeError(String::New("LuaSatte.collectGarbageSync Argument 1 Must Be A Number, try nodelua.GC.[TYPE]"))); + return scope.Close(Undefined()); + } + LuaState* obj = ObjectWrap::Unwrap(args.This()); int type = (int)args[0]->ToNumber()->Value(); int gc = lua_gc(obj->lua_, type, 0); @@ -392,9 +528,11 @@ Handle LuaState::RegisterFunction(const Arguments& args){ Persistent func = Persistent::New(Local::Cast(args[1])); char* func_name = get_str(args[0]); - functions[func_name] = func; + Local func_key = String::Concat(String::New(func_name), String::New(":")); + func_key = String::Concat(func_key, String::New(obj->name_)); + functions[get_str(func_key)] = func; - lua_pushstring(obj->lua_, func_name); + lua_pushstring(obj->lua_, get_str(func_key)); lua_pushcclosure(obj->lua_, CallFunction, 1); lua_setglobal(obj->lua_, func_name); diff --git a/src/luastate.h b/src/luastate.h index 95ba6c6..255a8e5 100644 --- a/src/luastate.h +++ b/src/luastate.h @@ -15,6 +15,7 @@ extern "C"{ class LuaState : public node::ObjectWrap{ public: lua_State* lua_; + char* name_; static void Init(v8::Handle target); static int CallFunction(lua_State* L); @@ -24,9 +25,15 @@ class LuaState : public node::ObjectWrap{ ~LuaState(); static v8::Handle New(const v8::Arguments& args); - static v8::Handle Status(const v8::Arguments& args); static v8::Handle Close(const v8::Arguments& args); + static v8::Handle GetName(const v8::Arguments& args); + static v8::Handle CollectGarbage(const v8::Arguments& args); + static v8::Handle CollectGarbageSync(const v8::Arguments& args); + + static v8::Handle Status(const v8::Arguments& args); + static v8::Handle StatusSync(const v8::Arguments& args); + static v8::Handle DoFileSync(const v8::Arguments& args); static v8::Handle DoFile(const v8::Arguments& args);