void Purge() { if (!bAbandoned) { bAbandoned = true; WrappedObject.Reset(); ClearDelegateObjects(); context_.Reset(); } }
void ObjectManager::CheckWeakObjectsAreAlive(const vector<PersistentObjectIdPair>& instances, DirectBuffer& inputBuff, DirectBuffer& outputBuff) { JEnv env; for (const auto& poIdPair : instances) { int javaObjectId = poIdPair.javaObjectId; bool success = inputBuff.Write(javaObjectId); if (!success) { int length = inputBuff.Length(); env.CallStaticVoidMethod(PlatformClass, CHECK_WEAK_OBJECTS_ARE_ALIVE_METHOD_ID, (jobject) inputBuff, (jobject) outputBuff, length); // int *released = outputBuff.GetData(); for (int i = 0; i < length; i++) { bool isReleased = *released++ != 0; if (isReleased) { Persistent<Object> *po = instances[i].po; po->Reset(); } } // inputBuff.Reset(); success = inputBuff.Write(javaObjectId); assert(success); } } int size = inputBuff.Size(); if (size > 0) { env.CallStaticVoidMethod(PlatformClass, CHECK_WEAK_OBJECTS_ARE_ALIVE_METHOD_ID, (jobject) inputBuff, (jobject) outputBuff, size); int *released = outputBuff.GetData(); for (int i = 0; i < size; i++) { bool isReleased = *released++ != 0; if (isReleased) { Persistent<Object> *po = instances[i].po; po->Reset(); } } } }
extern "C" void Java_io_neft_Native_renderer_1callAnimationFrame(JNIEnv * env, jobject obj) { using namespace renderer; // enter isolate Isolate* isolate = JS::GetIsolate(); Locker locker(isolate); Isolate::Scope isolate_scope(isolate); HandleScope handle_scope(isolate); // get local context and enter it Local<Context> context = Local<Context>::New(isolate, JS::GetContext()); Context::Scope context_scope(context); // call all registered functions const int length = animationFrameCalls.size(); for (int i = 0; i < length; i++){ Persistent<Function, CopyablePersistentTraits<Function>> func = animationFrameCalls[i]; // get local function Local<Function> localFunc = Local<Function>::New(isolate, func); // call function localFunc->Call(context->Global(), 0, NULL); // clear persistent func.Reset(); } // remove called functions animationFrameCalls.erase(animationFrameCalls.begin(), animationFrameCalls.begin() + length); }
void onConnection(const FunctionCallbackInfo<Value> &args) { uWS::Server *server = (uWS::Server *) args.Holder()->GetAlignedPointerFromInternalField(0); Isolate *isolate = args.GetIsolate(); Persistent<Function> *connectionCallback = (Persistent<Function> *) args.Holder()->GetAlignedPointerFromInternalField(CONNECTION_CALLBACK); connectionCallback->Reset(isolate, Local<Function>::Cast(args[0])); server->onConnection([isolate, connectionCallback](uWS::Socket socket) { HandleScope hs(isolate); Local<Value> argv[] = {wrapSocket(socket, isolate)}; node::MakeCallback(isolate, isolate->GetCurrentContext()->Global(), Local<Function>::New(isolate, *connectionCallback), 1, argv); }); }
void Shape::New(const v8::FunctionCallbackInfo<Value>& args) { HandleScope scope; Handle<Object> self = args.Holder(); Shape *shape; if (args[0]->IsExternal()) { Local<External> ext = Local<External>::Cast(args[0]); void *ptr = ext->Value(); shape = static_cast<Shape*>(ptr); shape->Wrap(args.Holder()); } else { shapeObj *s = (shapeObj *)msSmallMalloc(sizeof(shapeObj)); msInitShape(s); if(args.Length() >= 1) { s->type = args[0]->Int32Value(); } else { s->type = MS_SHAPE_NULL; } shape = new Shape(s); shape->Wrap(self); } /* create the attribute template. should use ObjectWrap in future */ Handle<ObjectTemplate> attributes_templ = ObjectTemplate::New(); attributes_templ->SetInternalFieldCount(2); attributes_templ->SetNamedPropertyHandler(attributeGetValue, attributeSetValue); Handle<Object> attributes = attributes_templ->NewInstance(); map<string, int> *attributes_map = new map<string, int>(); attributes->SetInternalField(0, External::New(attributes_map)); attributes->SetInternalField(1, External::New(shape->get()->values)); attributes->SetHiddenValue(String::New("__parent__"), self); if (shape->layer) { for (int i=0; i<shape->layer->numitems; ++i) { (*attributes_map)[string(shape->layer->items[i])] = i; } } Persistent<Object> pattributes; pattributes.Reset(Isolate::GetCurrent(), attributes); pattributes.MakeWeak(attributes_map, attributeWeakCallback); pattributes.MarkIndependent(); self->Set(String::New("attributes"), attributes); }
void on(const FunctionCallbackInfo<Value> &args) { lws::Server *server = (lws::Server *) args.Holder()->GetAlignedPointerFromInternalField(0); Isolate *isolate = args.GetIsolate(); String::Utf8Value eventName(args[0]->ToString()); if (!strncmp(*eventName, "error", eventName.length()) && !server) { Local<Function>::Cast(args[1])->Call(Null(isolate), 0, nullptr); } else if (server && !strncmp(*eventName, "connection", eventName.length())) { connectionCallback.Reset(isolate, Local<Function>::Cast(args[1])); server->onConnection([isolate](lws::Socket socket) { *socket.getUser() = nullptr; HandleScope hs(isolate); Local<Value> argv[] = {wrapSocket(&socket, isolate)->Clone()}; Local<Function>::New(isolate, connectionCallback)->Call(Null(isolate), 1, argv); }); } else if (server && !strncmp(*eventName, "close", eventName.length())) { closeCallback.Reset(isolate, Local<Function>::Cast(args[1])); server->onDisconnection([isolate](lws::Socket socket) { HandleScope hs(isolate); Local<Value> argv[] = {wrapSocket(&socket, isolate)}; Local<Function>::New(isolate, closeCallback)->Call(Null(isolate), 1, argv); delete ((string *) *socket.getUser()); }); } else if (server && !strncmp(*eventName, "message", eventName.length())) { messageCallback.Reset(isolate, Local<Function>::Cast(args[1])); server->onMessage([isolate](lws::Socket socket, char *data, size_t length, bool binary) { HandleScope hs(isolate); Local<Value> argv[] = {wrapSocket(&socket, isolate), /*ArrayBuffer::New(isolate, data, length)*/ node::Buffer::New(isolate, data, length, [](char *data, void *hint) {}, nullptr).ToLocalChecked(), Boolean::New(isolate, binary)}; Local<Function>::New(isolate, messageCallback)->Call(Null(isolate), 3, argv); }); } }
void MySQL::JS_Query(const FunctionCallbackInfo<Value> & args){ auto mysql = Instance(args.Holder()); auto mysqlconn = ConnectionInstance(args.Holder()); string query = JS2STRING(args[0]); if (args[1]->IsFunction()){ Persistent<Function, CopyablePersistentTraits<Function>> func; func.Reset(args.GetIsolate(), Local<Function>::Cast(args[1])); mysql->QueryAsync(mysqlconn->id, query, func); return; } }
void onDisconnection(const FunctionCallbackInfo<Value> &args) { uWS::Server *server = (uWS::Server *) args.Holder()->GetAlignedPointerFromInternalField(0); Isolate *isolate = args.GetIsolate(); Persistent<Function> *disconnectionCallback = (Persistent<Function> *) args.Holder()->GetAlignedPointerFromInternalField(DISCONNECTION_CALLBACK); disconnectionCallback->Reset(isolate, Local<Function>::Cast(args[0])); server->onDisconnection([isolate, disconnectionCallback](uWS::Socket socket, int code, char *message, size_t length) { HandleScope hs(isolate); Local<Value> argv[] = {wrapSocket(socket, isolate), Integer::New(isolate, code), node::Buffer::New(isolate, (char *) message, length, [](char *data, void *hint) {}, nullptr).ToLocalChecked(), getDataV8(socket, isolate)}; node::MakeCallback(isolate, isolate->GetCurrentContext()->Global(), Local<Function>::New(isolate, *disconnectionCallback), 4, argv); }); }
void onMessage(const FunctionCallbackInfo<Value> &args) { uWS::Server *server = (uWS::Server *) args.Holder()->GetAlignedPointerFromInternalField(0); Isolate *isolate = args.GetIsolate(); Persistent<Function> *messageCallback = (Persistent<Function> *) args.Holder()->GetAlignedPointerFromInternalField(MESSAGE_CALLBACK); messageCallback->Reset(isolate, Local<Function>::Cast(args[0])); server->onMessage([isolate, messageCallback](uWS::Socket socket, const char *message, size_t length, uWS::OpCode opCode) { HandleScope hs(isolate); Local<Value> argv[] = {wrapSocket(socket, isolate), node::Buffer::New(isolate, (char *) message, length, [](char *data, void *hint) {}, nullptr).ToLocalChecked(), Boolean::New(isolate, opCode == BINARY), getDataV8(socket, isolate)}; node::MakeCallback(isolate, isolate->GetCurrentContext()->Global(), Local<Function>::New(isolate, *messageCallback), 4, argv); }); }
void udeb_setLogger(const Arguments &args) { EscapableHandleScope scope(args.GetIsolate()); if(! udeb_initialized) { JSLoggerFunction.Reset(args.GetIsolate(), args[0]->ToObject()); // JSLoggerFunction.Reset(Function::Cast(* (args[0]))); // Local<Function> f = Function::Cast(* (args[0])); // JSLoggerFunction = Persistent<Function>::New(f); udeb_initialized = 1; udeb_print("unified_debug.cpp", UDEB_DEBUG, "unified_debug.cpp C++ unified_debug enabled"); } args.GetReturnValue().Set(true); }
Handle<Object> Log::Wrap() { Isolate *isolate = jsCompiler_.GetIsolate(); HandleScope scope(isolate); if (logTemplate.IsEmpty()) { Handle<ObjectTemplate> objTemplate = MakeLogTemplate(isolate); logTemplate.Reset(isolate, objTemplate); } Handle<ObjectTemplate> local = Local<ObjectTemplate>::New(isolate, logTemplate); Handle<Object> obj = local->NewInstance(); Handle<External> log_ptr = External::New(this); obj->SetInternalField(0, log_ptr); return scope.Close(obj); }
void Init(Isolate * isolate) { Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New); tpl->SetClassName(v8::String::NewFromUtf8(isolate, "Transformable")); tpl->InstanceTemplate()->SetInternalFieldCount(2); Local<ObjectTemplate> proto = tpl->PrototypeTemplate(); // proto->SetInternalFieldCount(1); proto->SetAccessor(v8::String::NewFromUtf8(isolate, "x"), GetX, SetX); proto->SetAccessor(v8::String::NewFromUtf8(isolate, "y"), GetY, SetY); proto->SetAccessor(v8::String::NewFromUtf8(isolate, "rotation"), GetRotation, SetRotation); proto->SetAccessor(v8::String::NewFromUtf8(isolate, "scaleX"), GetScaleX, SetScaleX); proto->SetAccessor(v8::String::NewFromUtf8(isolate, "scaleY"), GetScaleY, SetScaleY); proto->SetAccessor(v8::String::NewFromUtf8(isolate, "originX"), GetOriginX, SetOriginX); proto->SetAccessor(v8::String::NewFromUtf8(isolate, "originY"), GetOriginY, SetOriginY); tpl_ref.Reset(isolate, tpl); }
void Main(Local<Object> exports) { Isolate *isolate = exports->GetIsolate(); Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, constructor); tpl->InstanceTemplate()->SetInternalFieldCount(1); NODE_SET_PROTOTYPE_METHOD(tpl, "on", on); NODE_SET_PROTOTYPE_METHOD(tpl, "send", send); NODE_SET_PROTOTYPE_METHOD(tpl, "setUserData", setUserData); NODE_SET_PROTOTYPE_METHOD(tpl, "getUserData", getUserData); NODE_SET_PROTOTYPE_METHOD(tpl, "getFd", getFd); exports->Set(String::NewFromUtf8(isolate, "Server"), tpl->GetFunction()); Local<ObjectTemplate> socketTemplate = ObjectTemplate::New(isolate); socketTemplate->SetInternalFieldCount(2); persistentSocket.Reset(isolate, socketTemplate->NewInstance()); }
~executeBaton() { obj = NULL; // the StmtObject will free sqlany_stmt sqlany_stmt = NULL; CLEAN_STRINGS( string_vals ); CLEAN_STRINGS( colNames ); CLEAN_NUMS( num_vals ); CLEAN_NUMS( int_vals ); CLEAN_NUMS( string_len ); col_types.clear(); callback.Reset(); for( size_t i = 0; i < params.size(); i++ ) { if( params[i].value.is_null != NULL ) { delete params[i].value.is_null; params[i].value.is_null = NULL; } } params.clear(); }
/* Execute a javascript file */ static Handle<Value> msV8ExecuteScript(const char *path, int throw_exception = MS_FALSE) { char fullpath[MS_MAXPATHLEN]; map<string, Persistent<Script> >::iterator it; Isolate *isolate = Isolate::GetCurrent(); V8Context *v8context = (V8Context*)isolate->GetData(); /* construct the path */ msBuildPath(fullpath, v8context->paths.top().c_str(), path); char *filepath = msGetPath((char*)fullpath); v8context->paths.push(filepath); free(filepath); Handle<Script> script; it = v8context->scripts.find(fullpath); if (it == v8context->scripts.end()) { Handle<Value> source = msV8ReadFile(v8context, fullpath); Handle<String> script_name = String::New(msStripPath((char*)path)); script = msV8CompileScript(source->ToString(), script_name); if (script.IsEmpty()) { v8context->paths.pop(); if (throw_exception) { return ThrowException(String::New("Error compiling script")); } } /* cache the compiled script */ Persistent<Script> pscript; pscript.Reset(isolate, script); v8context->scripts[fullpath] = pscript; } else { script = v8context->scripts[fullpath]; } Handle<Value> result = msV8RunScript(script); v8context->paths.pop(); if (result.IsEmpty() && throw_exception) { return ThrowException(String::New("Error running script")); } return result; }
void executeAfter( uv_work_t *req ) /*********************************/ { Isolate *isolate = Isolate::GetCurrent(); HandleScope scope( isolate ); executeBaton *baton = static_cast<executeBaton*>( req->data ); Persistent<Value> ResultSet; fillResult( baton, ResultSet ); ResultSet.Reset(); scoped_lock lock( baton->obj->conn_mutex ); if( baton->sqlany_stmt != NULL && baton->prepared_stmt ) { if( api.initialized ) { api.sqlany_free_stmt( baton->sqlany_stmt ); } baton->sqlany_stmt = NULL; } delete baton; delete req; }
void MySQL::JS_Connect(const FunctionCallbackInfo<Value> & args){ auto mysql = Instance(args.Holder()); auto mysqlconn = ConnectionInstance(args.Holder()); string host = JS2STRING(args[0]); string user = JS2STRING(args[1]); string password = JS2STRING(args[2]); string database = JS2STRING(args[3]); if (args[4]->IsFunction()){ Persistent<Function,CopyablePersistentTraits<Function>> func; func.Reset(args.GetIsolate(), Local<Function>::Cast(args[4])); thread( [mysql, mysqlconn, host, user, password, database,func](){ mysql_thread_init(); std::lock_guard<std::mutex> lock{ mysqlconn->lock }; mysql->ConnectAsync(mysqlconn->id, host, user, password, database,func); mysql_thread_end(); }).detach(); } else { if (mysql_real_connect( mysqlconn->mysql, host.c_str(), user.c_str(), password.c_str(), database.c_str(), 0, NULL, 0) == NULL){ sjs::logger::error("MySQL Connect Error: %s", mysql_error(mysqlconn->mysql)); args.GetReturnValue().Set(false); return; } } args.GetReturnValue().Set(true); }
void Main(Local<Object> exports) { Isolate *isolate = exports->GetIsolate(); Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, ::Server); tpl->InstanceTemplate()->SetInternalFieldCount(4); NODE_SET_PROTOTYPE_METHOD(tpl, "onConnection", onConnection); NODE_SET_PROTOTYPE_METHOD(tpl, "onMessage", onMessage); NODE_SET_PROTOTYPE_METHOD(tpl, "onDisconnection", onDisconnection); NODE_SET_PROTOTYPE_METHOD(tpl, "close", close); NODE_SET_PROTOTYPE_METHOD(tpl, "broadcast", broadcast); NODE_SET_PROTOTYPE_METHOD(tpl, "upgrade", upgrade); NODE_SET_PROTOTYPE_METHOD(tpl, "transfer", transfer); NODE_SET_PROTOTYPE_METHOD(tpl, "setData", setData); NODE_SET_PROTOTYPE_METHOD(tpl, "getData", getData); NODE_SET_PROTOTYPE_METHOD(tpl, "send", send); NODE_SET_PROTOTYPE_METHOD(tpl, "getAddress", getAddress); exports->Set(String::NewFromUtf8(isolate, "Server"), tpl->GetFunction()); Local<ObjectTemplate> ticketTemplate = ObjectTemplate::New(isolate); ticketTemplate->SetInternalFieldCount(2); persistentTicket.Reset(isolate, ticketTemplate->NewInstance()); }
~connectBaton() { obj = NULL; sqlca = NULL; callback.Reset(); }
void MySQL::QueryAsync(int id, string query, Persistent<Function, CopyablePersistentTraits<Function>> callback){ // We need to do this or for some reason it loses its persistence and goes out of scope :( Persistent<Function, CopyablePersistentTraits<Function>> cb; cb.Reset(isolate, callback); thread( [this, id, cb, query](){ mysql_thread_init(); std::lock_guard<std::mutex> lock{ connections[id]->lock }; MYSQL* msql = connections[id]->mysql; if (!isConnected(msql)){ sjs::logger::error("MYSQL Error: Not connected"); } else { mysql_query(msql, query.c_str()); unsigned int err_no = mysql_errno(msql); if (err_no){ sjs::logger::error("MYSQL Query Error: %s", mysql_error(msql)); V8PCONTEXT(isolate, context); TryCatch try_catch; Local<String> err = String::NewFromUtf8(isolate, mysql_error(msql)); Local<Value> argv[1] = { err }; Local<Function> func = Local<Function>::New(isolate, cb); func->Call(func, 1, argv); if (try_catch.HasCaught()){ Utils::PrintException(&try_catch); } mysql_thread_end(); return; } MYSQL_RES *result = mysql_store_result(msql); if (result == NULL){ // No error and result was null meaning it wasn't a SELECT type statement my_ulonglong affected = mysql_affected_rows(msql); my_ulonglong insert_id = mysql_insert_id(msql); V8PCONTEXT(isolate, context); TryCatch try_catch; JS_Object jsresult(isolate); jsresult.Set("insertId", insert_id); jsresult.Set("affectedRows", affected); Local<Value> empty = Undefined(isolate); Local<Value> argv[2] = { empty, jsresult.get() }; Local<Function> func = Local<Function>::New(isolate, cb); func->Call(func, 2, argv); if (try_catch.HasCaught()){ Utils::PrintException(&try_catch); } } else { int num_fields = mysql_num_fields(result); MYSQL_ROW row; MYSQL_FIELD *field; vector<string> fields; V8PCONTEXT(isolate, context); TryCatch try_catch; Local<Array> jsrows = Array::New(isolate, 0); Local<Array> jsfields = Array::New(isolate, num_fields); for (int j = 0; j < num_fields; j++){ field = mysql_fetch_field_direct(result, j); fields.push_back(field->name); jsfields->Set(j, String::NewFromUtf8(isolate, field->name)); } int row_count = 0; while ((row = mysql_fetch_row(result))){ JS_Object jsrow(isolate); for (int i = 0; i < num_fields; i++){ if (row[i] == NULL) jsrow.SetNull(fields[i]); else jsrow.Set(fields[i], string(row[i])); } jsrows->Set(row_count++, jsrow.get()); } Local<Value> empty = Undefined(isolate); Local<Value> argv[3] = { empty, jsrows, jsfields }; Local<Function> func = Local<Function>::New(isolate, cb); func->Call(func, 3, argv); if (try_catch.HasCaught()){ Utils::PrintException(&try_catch); } mysql_free_result(result); } } mysql_thread_end(); }).detach(); }
void Finalize() { tpl_ref.Reset(); }
~dropBaton() { obj = NULL; callback.Reset(); }
/* static */ void V8Runtime::collectWeakRef(Persistent<Value> ref, void *parameter) { jobject v8Object = (jobject) parameter; ref.Reset(); JNIScope::getEnv()->DeleteGlobalRef(v8Object); }
Local<Object> Initialize(Local<Context> context) { isolate_ = context->GetIsolate(); context_.Reset(isolate_, context); auto out = Object::New(isolate_); auto add = [](const FunctionCallbackInfo<Value>& info) { for (;;) { auto payload = reinterpret_cast<FJavascriptDelegate*>(Local<External>::Cast(info.Data())->Value()); if (info.Length() == 1) { auto func = Local<Function>::Cast(info[0]); if (!func.IsEmpty()) { payload->Add(func); break; } } UE_LOG(Javascript, Log, TEXT("Invalid argument for delegate")); break; } }; auto remove = [](const FunctionCallbackInfo<Value>& info) { for (;;) { auto payload = reinterpret_cast<FJavascriptDelegate*>(Local<External>::Cast(info.Data())->Value()); if (info.Length() == 1) { auto func = Local<Function>::Cast(info[0]); if (!func.IsEmpty()) { payload->Remove(func); break; } } UE_LOG(Javascript, Log, TEXT("Invalid argument for delegate")); break; } }; auto clear = [](const FunctionCallbackInfo<Value>& info) { auto payload = reinterpret_cast<FJavascriptDelegate*>(Local<External>::Cast(info.Data())->Value()); payload->Clear(); }; auto toJSON = [](const FunctionCallbackInfo<Value>& info) { auto payload = reinterpret_cast<FJavascriptDelegate*>(Local<External>::Cast(info.Data())->Value()); uint32_t Index = 0; auto arr = Array::New(info.GetIsolate(), payload->DelegateObjects.Num()); const bool bIsMulticastDelegate = payload->Property->IsA(UMulticastDelegateProperty::StaticClass()); for (auto DelegateObject : payload->DelegateObjects) { auto JavascriptFunction = payload->functions.Find(DelegateObject->UniqueId); if (JavascriptFunction) { auto function = Local<Function>::New(info.GetIsolate(), *JavascriptFunction); if (!bIsMulticastDelegate) { info.GetReturnValue().Set(function); return; } arr->Set(Index++, function); } } if (!bIsMulticastDelegate) { info.GetReturnValue().Set(Null(info.GetIsolate())); } else { info.GetReturnValue().Set(arr); } }; auto data = External::New(isolate_, this); out->Set(V8_KeywordString(isolate_, "Add"), Function::New(isolate_, add, data)); out->Set(V8_KeywordString(isolate_, "Remove"), Function::New(isolate_, remove, data)); out->Set(V8_KeywordString(isolate_, "Clear"), Function::New(isolate_, clear, data)); out->Set(V8_KeywordString(isolate_, "toJSON"), Function::New(isolate_, toJSON, data)); WrappedObject.Reset(isolate_, out); return out; }
~prepareBaton() { obj = NULL; callback.Reset(); StmtObj.Reset(); }
void Setup(const FunctionCallbackInfo<Value>& args) { Isolate * isolate = args.GetIsolate(); // Save a persistent handle to this object for later use in Mutate persist.Reset(isolate, args[0]->ToObject()); }
void UiWindow::InvokeEventCallback(Isolate* isolate, WindowEventData* data) { WINDOW_EVENT evt = data->Evt; Local<Object> hndl = handle(); Local<Function> emitFn = Local<Function>::New(isolate, _emitFn); if (evt == WINDOW_EVENT_READY) { Handle<Value> argv[] = { String::NewFromUtf8(isolate, "ready") }; emitFn->Call(hndl, 1, argv); } else if (evt == WINDOW_EVENT_CLOSING) { if (!_shouldClose) { auto closeArg = Object::New(isolate); Handle<Value> argv[] = { String::NewFromUtf8(isolate, "closing"), closeArg }; auto result = emitFn->Call(hndl, 2, argv); result->BooleanValue(); _shouldClose = !closeArg->Get(String::NewFromUtf8(isolate, "cancel"))->BooleanValue(); } if (_shouldClose) { Close(); } } else if (evt == WINDOW_EVENT_CLOSED) { Handle<Value> argv[] = { String::NewFromUtf8(isolate, "closed") }; emitFn->Call(hndl, 1, argv); } else if (evt == WINDOW_EVENT_RESIZE) { Handle<Value> argv[] = { String::NewFromUtf8(isolate, "resize"), Int32::New(isolate, (int)data->Arg1), Int32::New(isolate, (int)data->Arg2) }; emitFn->Call(hndl, 3, argv); } else if (evt == WINDOW_EVENT_STATE) { Handle<Value> argv[] = { String::NewFromUtf8(isolate, "state"), Int32::New(isolate, (int)data->Arg1) }; emitFn->Call(hndl, 2, argv); } else if (evt == WINDOW_EVENT_MOVE) { Handle<Value> argv[] = { String::NewFromUtf8(isolate, "move"), Int32::New(isolate, (int)data->Arg1), Int32::New(isolate, (int)data->Arg2) }; emitFn->Call(hndl, 3, argv); } else if (evt == WINDOW_EVENT_DOCUMENT_COMPLETE) { Handle<Value> argv[] = { String::NewFromUtf8(isolate, "documentComplete") }; emitFn->Call(hndl, 1, argv); } else if (evt == WINDOW_EVENT_MENU) { UiMenu* menu = (UiMenu*)data->Arg1; Handle<Value> argId = menu->Id ? (Handle<Value>)*menu->Id : (Handle<Value>)Null(isolate); Handle<Value> argTitle = menu->Title ? (Handle<Value>)*menu->Title : (Handle<Value>)Null(isolate); Handle<Value> argv[] = { String::NewFromUtf8(isolate, "menu"), argId, argTitle }; emitFn->Call(hndl, 3, argv); if (!menu->Callback.IsEmpty()) { Local<Function> fn = Local<Function>::New(isolate, menu->Callback); Handle<Value> callbackArgv[] = { argId, argTitle }; fn->Call(hndl, 2, callbackArgv); } } else if (evt == WINDOW_EVENT_MESSAGE) { Utf8String* msg = (Utf8String*)data->Arg1; auto callback = (void*)data->Arg2; if (!_onMessageFn.IsEmpty()) { auto onMessage = Local<Function>::New(isolate, _onMessageFn); Handle<Value> argv[] = { JsonParse(*msg) }; auto result = onMessage->Call(hndl, 1, argv); if (callback) { TryCatch tc; result = JsonStringify(result); Utf8String* resultStr = new Utf8String(result); Utf8String* errorStr = NULL; if (tc.HasCaught()) errorStr = new Utf8String(tc.Exception()->ToString()); this->MsgCallback(callback, resultStr, errorStr); } } delete msg; } else if (evt == WINDOW_EVENT_MESSAGE_CALLBACK) { Persistent<Function>* callback = (Persistent<Function>*)data->Arg1; Utf8String* result = (Utf8String*)data->Arg2; Utf8String* error = (Utf8String*)data->Arg3; if (callback) { auto callbackFn = Local<Function>::New(isolate, *callback); Handle<Value> argv[] = { Null(isolate), Null(isolate) }; if (result) argv[0] = JsonParse(*result); if (error) argv[0] = *error; callbackFn->Call(hndl, 2, argv); callback->Reset(); delete callback; } if (result) delete result; if (error) delete error; } else if (evt == WINDOW_EVENT_SELECT_FILE) { auto params = (WindowOpenFileParams*)data->Arg1; auto result = (Utf8String**)data->Arg2; Handle<Value> callbackResult; if (result) { auto len = 0; for (len = 0; result[len]; ) { len++; } auto resArr = Array::New(isolate, len); callbackResult = resArr; for (auto i = 0; result[i]; i++) { resArr->Set(i, *result[i]); delete result[i]; } delete[] result; } else { callbackResult = (Handle<Value>)Null(isolate); } if (!params->Complete.IsEmpty()) { auto callbackFn = Local<Function>::New(isolate, params->Complete); Handle<Value> argv[] = { callbackResult }; callbackFn->Call(hndl, 1, argv); } delete params; } }