int32_t NpcScriptInterface::luaNpcOpenShopWindow(lua_State* L) { // npc:openShopWindow(cid, items, buyCallback, sellCallback) if(!isTable(L, 3)) { reportErrorFunc("item list is not a table."); pushBoolean(L, false); return 1; } Player* player = getPlayer(L, 2); if (!player) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); pushBoolean(L, false); return 1; } Npc* npc = getUserdata<Npc>(L, 1); if (!npc) { reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND)); pushBoolean(L, false); return 1; } int32_t sellCallback = -1; if (isFunction(L, 5)) { sellCallback = luaL_ref(L, LUA_REGISTRYINDEX); } int32_t buyCallback = -1; if (isFunction(L, 4)) { buyCallback = luaL_ref(L, LUA_REGISTRYINDEX); } std::list<ShopInfo> items; pushNil(L); while (lua_next(L, 3) != 0) { ShopInfo item; item.itemId = popField<uint32_t>(L, "id"); item.subType = popField<int32_t>(L, "subType"); if (item.subType == 0) { item.subType = popField<int32_t>(L, "subtype"); } item.buyPrice = popField<uint32_t>(L, "buy"); item.sellPrice = popField<uint32_t>(L, "sell"); item.realName = popFieldString(L, "name"); items.push_back(item); lua_pop(L, 1); } lua_pop(L, 1); player->closeShopWindow(false); npc->addShopPlayer(player); player->setShopOwner(npc, buyCallback, sellCallback); player->openShopWindow(npc, items); pushBoolean(L, true); return 1; }
// Lua: net.dns.resolve( domain, function(ip) ) static int net_dns_static( lua_State* L ) { const char *mt = "net.socket"; if (!lua_isstring( L, 1 )) return luaL_error( L, "wrong parameter type (domain)" ); int rfunc = LUA_NOREF; //save reference to func if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION){ rfunc = luaL_ref(L, LUA_REGISTRYINDEX); } int rdom = luaL_ref(L, LUA_REGISTRYINDEX); //save reference to domain lua_settop(L,0); //empty stack lua_getfield(L, LUA_GLOBALSINDEX, "net"); lua_getfield(L, -1, "createConnection"); lua_remove(L, -2); //remove "net" from stack lua_pushinteger(L, UDP); // we are going to create a new dummy UDP socket lua_call(L,1,1);// after this the stack should have a socket lua_rawgeti(gL, LUA_REGISTRYINDEX, rdom); // load domain back to the stack lua_rawgeti(gL, LUA_REGISTRYINDEX, rfunc); // load the callback function back to the stack luaL_unref(L, LUA_REGISTRYINDEX, rdom); //free reference luaL_unref(L, LUA_REGISTRYINDEX, rfunc); //free reference bool isserver = false; struct espconn *pesp_conn = NULL; lnet_userdata *nud; size_t l; nud = (lnet_userdata *)luaL_checkudata(L, 1, mt); luaL_argcheck(L, nud, 1, "Server/Socket expected"); if(nud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } if(nud->pesp_conn == NULL){ NODE_DBG("nud->pesp_conn is NULL.\n"); return 0; } pesp_conn = nud->pesp_conn; lua_pushvalue(L, 1); // copy to the top of stack if(nud->self_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->self_ref); nud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); const char *domain = luaL_checklstring( L, 2, &l ); if (l>128 || domain == NULL) return luaL_error( L, "need <128 domain" ); if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION){ lua_pushvalue(L, 3); // copy argument (func) to the top of stack if(nud->cb_dns_found_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_dns_found_ref); nud->cb_dns_found_ref = luaL_ref(L, LUA_REGISTRYINDEX); } host_ip.addr = 0; if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, net_dns_found)) net_dns_found(domain, &host_ip, pesp_conn); // ip is returned in host_ip. return 0; }
// Lua: server:listen( port, ip, function(con) ) // Lua: socket:connect( port, ip, function(con) ) static int net_start( lua_State* L, const char* mt ) { NODE_DBG("net_start is called.\n"); struct espconn *pesp_conn = NULL; lnet_userdata *nud; unsigned port; size_t il; bool isserver = false; ip_addr_t ipaddr; const char *domain; uint8_t stack = 1; if (mt!=NULL && c_strcmp(mt, "net.server")==0) isserver = true; else if (mt!=NULL && c_strcmp(mt, "net.socket")==0) isserver = false; else { NODE_DBG("wrong metatable for net_start.\n"); return 0; } nud = (lnet_userdata *)luaL_checkudata(L, stack, mt); luaL_argcheck(L, nud, stack, "Server/Socket expected"); stack++; if(nud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } if(nud->pesp_conn == NULL){ NODE_DBG("nud->pesp_conn is NULL.\n"); return 0; } pesp_conn = nud->pesp_conn; port = luaL_checkinteger( L, stack ); stack++; if( pesp_conn->type == ESPCONN_TCP ) { if(isserver) pesp_conn->proto.tcp->local_port = port; else{ pesp_conn->proto.tcp->remote_port = port; pesp_conn->proto.tcp->local_port = espconn_port(); } NODE_DBG("TCP port is set: %d.\n", port); } else if (pesp_conn->type == ESPCONN_UDP) { if(isserver) pesp_conn->proto.udp->local_port = port; else{ pesp_conn->proto.udp->remote_port = port; pesp_conn->proto.udp->local_port = espconn_port(); } NODE_DBG("UDP port is set: %d.\n", port); } if( lua_isstring(L,stack) ) // deal with the domain string { domain = luaL_checklstring( L, stack, &il ); stack++; if (domain == NULL) { if(isserver) domain = "0.0.0.0"; else domain = "127.0.0.1"; } ipaddr.addr = ipaddr_addr(domain); if( pesp_conn->type == ESPCONN_TCP ) { if(isserver) c_memcpy(pesp_conn->proto.tcp->local_ip, &ipaddr.addr, 4); else c_memcpy(pesp_conn->proto.tcp->remote_ip, &ipaddr.addr, 4); NODE_DBG("TCP ip is set: "); NODE_DBG(IPSTR, IP2STR(&ipaddr.addr)); NODE_DBG("\n"); } else if (pesp_conn->type == ESPCONN_UDP) { if(isserver) c_memcpy(pesp_conn->proto.udp->local_ip, &ipaddr.addr, 4); else c_memcpy(pesp_conn->proto.udp->remote_ip, &ipaddr.addr, 4); NODE_DBG("UDP ip is set: "); NODE_DBG(IPSTR, IP2STR(&ipaddr.addr)); NODE_DBG("\n"); } } // call back function when a connection is obtained, tcp only if ( pesp_conn->type == ESPCONN_TCP ) { if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION){ lua_pushvalue(L, stack); // copy argument (func) to the top of stack if(isserver) // for tcp server connected callback { if(tcpserver_cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, tcpserver_cb_connect_ref); tcpserver_cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); } else { if(nud->cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_connect_ref); nud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); } } } if(!isserver || pesp_conn->type == ESPCONN_UDP){ // self_ref is only needed by socket userdata, or udp server lua_pushvalue(L, 1); // copy to the top of stack if(nud->self_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->self_ref); nud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); } if( pesp_conn->type == ESPCONN_TCP ) { if(isserver){ // no secure server support for now espconn_regist_connectcb(pesp_conn, net_server_connected); // tcp server, SSL is not supported #ifdef CLIENT_SSL_ENABLE // if(nud->secure) // espconn_secure_accept(pesp_conn); // else #endif espconn_accept(pesp_conn); // if it's a server, no need to dns. espconn_regist_time(pesp_conn, tcp_server_timeover, 0); } else{ espconn_regist_connectcb(pesp_conn, net_socket_connected); espconn_regist_reconcb(pesp_conn, net_socket_reconnected); #ifdef CLIENT_SSL_ENABLE if(nud->secure){ if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_secure_disconnect(pesp_conn); // espconn_secure_connect(pesp_conn); } else #endif { if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_disconnect(pesp_conn); // espconn_connect(pesp_conn); } } } else if (pesp_conn->type == ESPCONN_UDP) { espconn_regist_recvcb(pesp_conn, net_socket_received); espconn_regist_sentcb(pesp_conn, net_socket_sent); if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_delete(pesp_conn); if(isserver) espconn_create(pesp_conn); // if it's a server, no need to dns. } if(!isserver){ if((ipaddr.addr == IPADDR_NONE) && (c_memcmp(domain,"255.255.255.255",16) != 0)) { host_ip.addr = 0; dns_reconn_count = 0; if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, socket_dns_found)){ socket_dns_found(domain, &host_ip, pesp_conn); // ip is returned in host_ip. } } else { socket_connect(pesp_conn); } } return 0; }
////////////////////////////////////////////////////////////////////////// // Заносит в реестр то, что лежит на вершине стека, и возвращает ссылку на него // При этом с вершины стека оно удаляется LuaRegRef LuaScript::AddToRegistry( ) { // Стек: ... data return luaL_ref( Lst, LUA_REGISTRYINDEX ); // Стек: }
int main(int argc, char *argv[]) { int i,ii; lua_State *L; L = lua_open(); luaopen_base(L); /* opens the basic library */ luaopen_table(L); /* opens the table library */ luaopen_string(L); /* opens the string lib. */ luaopen_math(L); /* opens the math lib. */ lua_pop(L,5); static const luaL_reg EventNet_meta[] = { {"__gc", Bla_gc}, {"__tostring", Bla_tostring}, {0, 0} }; static const luaL_Reg RegisterEventNet[] = { {"new", BlaNew}, {"sleep", BlaSleep}, {"bla", BlaBla}, {NULL, NULL} }; luaL_openlib(L, "Bla", RegisterEventNet, 0); luaL_newmetatable(L, "Bla"); luaL_openlib(L, 0, EventNet_meta, 0); lua_pushliteral(L, "__index"); lua_pushvalue(L, -3); lua_rawset(L, -3); lua_pushliteral(L, "__metatable"); lua_pushvalue(L, -3); lua_rawset(L, -3); lua_pop(L, 2); luaL_loadstring(L,"function main() local bla=Bla:new() bla:sleep() bla:bla() end"); int count=0; lua_pcall(L,0,0,0); printf("Memory used = %d\n",lua_gc(L, LUA_GCCOUNT, 0)); for(i=0;i<1;i++) { for(ii=0;ii<=len;ii++) { count++; snprintf(bla[ii].bla,50,"bla%d",ii); bla[ii].thread = lua_newthread(L); bla[ii].table = luaL_ref (L,LUA_REGISTRYINDEX); lua_pushthread(bla[ii].thread); lua_pushlightuserdata(bla[ii].thread,(void*) &bla[ii]); lua_settable(bla[ii].thread, LUA_REGISTRYINDEX); lua_getglobal(bla[ii].thread, "main"); lua_resume(bla[ii].thread, 0); // printf("init %s %p\n",bla[ii].bla,bla[ii].thread); } for(ii=0;ii<=len;ii++) { lua_resume(bla[ii].thread, 0); // printf("in c bla[%d] = %p and bla string is %s\n\n",ii,bla[ii].thread,bla[ii].bla); lua_pushthread(bla[ii].thread); lua_pushnil(bla[ii].thread); lua_settable(bla[ii].thread, LUA_REGISTRYINDEX); luaL_unref(L, LUA_REGISTRYINDEX, bla[ii].table ); } } printf("Memory used = %d, cycle %d\n",lua_gc(L, LUA_GCCOUNT, 0),count); lua_gc(L, LUA_GCCOLLECT, 0); printf("Memory used = %d, cycle %d\n",lua_gc(L, LUA_GCCOUNT, 0),count); lua_close(L); return 0; }
/*cfg={} cfg.ssid="" cfg.pwd="" cfg.ip (optional,default:11.11.11.1) cfg.netmask(optional,default:255.255.255.0) cfg.gateway(optional,default:11.11.11.1) cfg.dnsSrv(optional,default:11.11.11.1) cfg.retry_interval(optional,default:1000ms) wifi.startap(cfg,function(optional))*/ static int lwifi_startap( lua_State* L ) {//4 stations Max network_InitTypeDef_st wNetConfig; size_t len=0; memset(&wNetConfig, 0x0, sizeof(network_InitTypeDef_st)); if (!lua_istable(L, 1)) return luaL_error( L, "table arg needed" ); //ssid lua_getfield(L, 1, "ssid"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the string { const char *ssid = luaL_checklstring( L, -1, &len ); if(len>32) return luaL_error( L, "ssid:<32" ); strncpy(wNetConfig.wifi_ssid,ssid,len); } else return luaL_error( L, "wrong arg type:ssid" ); } else return luaL_error( L, "arg: ssid needed" ); //pwd lua_getfield(L, 1, "pwd"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the string { const char *pwd = luaL_checklstring( L, -1, &len ); if(len>64) return luaL_error( L, "pwd:<64" ); if(len>0) strncpy(wNetConfig.wifi_key,pwd,len); else strcpy(wNetConfig.wifi_key,""); } else return luaL_error( L, "wrong arg type:pwd" ); } else return luaL_error( L, "arg: pwd needed" ); //ip lua_getfield(L, 1, "ip"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *ip = luaL_checklstring( L, -1, &len ); if(len>16) return luaL_error( L, "ip:<16" ); if(is_valid_ip(ip)==false) return luaL_error( L, "ip invalid" ); strncpy(wNetConfig.local_ip_addr,ip,len); } else return luaL_error( L, "wrong arg type:ip" ); } else { strcpy(wNetConfig.local_ip_addr,"11.11.11.1"); //return luaL_error( L, "arg: ip needed" ); } //netmask lua_getfield(L, 1, "netmask"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *netmask = luaL_checklstring( L, -1, &len ); if(len>16) return luaL_error( L, "netmask:<16" ); if(is_valid_ip(netmask)==false) return luaL_error( L, "netmask invalid" ); strncpy(wNetConfig.net_mask,netmask,len); } else return luaL_error( L, "wrong arg type:netmask" ); } else { strcpy(wNetConfig.net_mask,"255.255.255.0"); //return luaL_error( L, "arg: netmask needed" ); } //gateway lua_getfield(L, 1, "gateway"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *gateway = luaL_checklstring( L, -1, &len ); if(len>16) return luaL_error( L, "gateway:<16" ); if(is_valid_ip(gateway)==false) return luaL_error( L, "gateway invalid" ); strncpy(wNetConfig.gateway_ip_addr,gateway,len); } else return luaL_error( L, "wrong arg type:gateway" ); } else { strcpy(wNetConfig.gateway_ip_addr,"11.11.11.1"); // return luaL_error( L, "arg: gateway needed" ); } //dnsSrv lua_getfield(L, 1, "dnsSrv"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *dnsSrv = luaL_checklstring( L, -1, &len ); if(len>16) return luaL_error( L, "dnsSrv:<16" ); if(is_valid_ip(dnsSrv)==false) return luaL_error( L, "dnsSrv invalid" ); strncpy(wNetConfig.dnsServer_ip_addr,dnsSrv,len); } else return luaL_error( L, "wrong arg type:dnsSrv" ); } else { strcpy(wNetConfig.dnsServer_ip_addr,"11.11.11.1"); //return luaL_error( L, "arg: dnsSrv needed" ); } //retry_interval signed retry_interval=0; lua_getfield(L, 1, "retry_interval"); if (!lua_isnil(L, -1)){ /* found? */ retry_interval= luaL_checknumber( L, -1 ); if(retry_interval<=0) return luaL_error( L, "retry_interval:>0ms" ); } else retry_interval = 1000; wNetConfig.wifi_retry_interval = retry_interval; /*MCU_DBG("wifi_ssid:%s\r\n",wNetConfig.wifi_ssid); MCU_DBG("wifi_key:%s\r\n",wNetConfig.wifi_key); MCU_DBG("local_ip_addr:%s\r\n",wNetConfig.local_ip_addr); MCU_DBG("net_mask:%s\r\n",wNetConfig.net_mask); MCU_DBG("gateway_ip_addr:%s\r\n",wNetConfig.gateway_ip_addr); MCU_DBG("dnsServer_ip_addr:%s\r\n",wNetConfig.dnsServer_ip_addr); MCU_DBG("wifi_retry_interval:%d\r\n",wNetConfig.wifi_retry_interval);*/ //notify gL = L; if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION) { lua_pushvalue(L, 2); // copy argument (func) to the top of stack if(wifi_status_changed_AP != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, wifi_status_changed_AP); wifi_status_changed_AP = luaL_ref(L, LUA_REGISTRYINDEX); MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)_micoNotify_WifiStatusHandler ); } else { if(wifi_status_changed_AP != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, wifi_status_changed_AP); wifi_status_changed_AP = LUA_NOREF; } //start wNetConfig.dhcpMode = DHCP_Server; wNetConfig.wifi_mode = Soft_AP; micoWlanStart(&wNetConfig); return 0; }
void LuaReference::SetFromStack( Lua *L ) { if( m_iReference != LUA_NOREF ) luaL_unref( L, LUA_REGISTRYINDEX, m_iReference ); m_iReference = luaL_ref( L, LUA_REGISTRYINDEX ); }
/// Registers the luaCell object in the Lua stack int luaCell::setReference( lua_State* L) { ref = luaL_ref(L, LUA_REGISTRYINDEX ); return 0; }
static void on_export_selection(gpointer instance,dt_control_image_enumerator_t * export_descriptor, gpointer user_data){ lua_State* L = darktable.lua_state; dt_control_export_t *export_data= (dt_control_export_t*)export_descriptor->data; dt_imageio_module_storage_t *mstorage = dt_imageio_get_storage_by_index(export_data->storage_index); g_assert(mstorage); dt_imageio_module_data_t *fdata = mstorage->get_params(mstorage); luaA_push_typeid(L,mstorage->parameter_lua_type,fdata); mstorage->free_params(mstorage,fdata); dt_imageio_module_format_t *mformat = dt_imageio_get_format_by_index(export_data->format_index); g_assert(mformat); fdata = mformat->get_params(mformat); luaA_push_typeid(L,mformat->parameter_lua_type,fdata); mformat->free_params(mformat,fdata); GList * elt = export_descriptor->index; lua_newtable(L); while(elt) { luaA_push(L,dt_lua_image_t,&elt->data); luaL_ref(L,-2); elt = g_list_next(elt); } g_list_free(export_descriptor->index); export_descriptor->index =NULL; dt_lua_trigger_event("pre-export",3,3); // get the new storage data and the new storage luaL_getmetafield(L,-3,"__associated_object"); mstorage = lua_touserdata(L,-1); lua_pop(L,1); fdata = mstorage->get_params(mstorage); luaL_getmetafield(L,-3,"__luaA_Type"); luaA_Type storage_type = lua_tointeger(L,-1); lua_pop(L,1); luaA_to_typeid(L,storage_type,fdata,-3); mstorage->set_params(mstorage,fdata,mstorage->params_size(mstorage)); mstorage->free_params(mstorage,fdata); export_data->storage_index = dt_imageio_get_index_of_storage(mstorage); // get the new format data and the new format luaL_getmetafield(L,-2,"__associated_object"); mformat = lua_touserdata(L,-1); lua_pop(L,1); fdata = mformat->get_params(mformat); luaL_getmetafield(L,-2,"__luaA_Type"); luaA_Type format_type = lua_tointeger(L,-1); lua_pop(L,1); luaA_to_typeid(L,format_type,fdata,-2); mformat->set_params(mformat,fdata,mstorage->params_size(mstorage)); mformat->free_params(mformat,fdata); export_data->format_index = dt_imageio_get_index_of_format(mformat); // load the new list of images to process if(lua_isnoneornil(L,-1)) {lua_pop(L,3); return; }// everything already has been removed luaA_to(L,dt_lua_image_t,&export_descriptor->index,-1); lua_pop(L,1); }
static int luaL_checkfunction(lua_State *L, int arg) { luaL_checktype(L, arg, LUA_TFUNCTION); lua_pushvalue(L, arg); return luaL_ref(L, LUA_REGISTRYINDEX); }
static xmp_main(lua_State *L) { /* * called in lua as fuse.main(dispatch_table, fuse_table) */ L_VM = L; int argc = lua_objlen(L, 2); char *argv[256]; int i; if (argc < 2) luaL_error(L, "check parameter fusemount parameter table"); #if 0 lua_pushstring(L, "pulse_freq"); lua_gettable(L, 1); pulse_freq = lua_tointeger(L,-1); lua_pop(L,1); if (pulse_freq == 0) pulse_freq = 10; #endif /* * save dispatch table for future reference by C program */ lua_pushvalue(L, 1); dispatch_table = luaL_ref(L_VM, LUA_REGISTRYINDEX); /* * turn fuse option table(effectively cmdline) to argv style */ for (i=0; i < argc && i < 255; i++) { lua_rawgeti(L, 2, i + 1); argv[i]=lua_tostring(L, -1); } argv[i] = NULL; #if 0 if (pulse_freq > 0) { signal(SIGALRM,l_signal); alarm(pulse_freq); } #endif /* * hand over to fuse loop */ fuse_main(argc, argv, &xmp_oper); /* * remove argv strings from L stack */ lua_pop(L, i); /* * discard reference to dispatch_table */ luaL_unref(L, LUA_REGISTRYINDEX, dispatch_table); #if 0 signal(SIGALRM, SIG_DFL); #endif return 0; }
int luaopen_tek_lib_display_x11(lua_State *L) { TAPTR exec; TEKDisplay *display; /* require "tek.lib.exec": */ lua_getglobal(L, "require"); /* s: "require" */ lua_pushliteral(L, "tek.lib.exec"); /* s: "require", "tek.lib.exec" */ lua_call(L, 1, 1); /* s: exectab */ lua_getfield(L, -1, "base"); /* s: exectab, execbase */ exec = *(TAPTR *) lua_touserdata(L, -1); /* register functions: */ #if LUA_VERSION_NUM < 502 luaL_register(L, "tek.lib.display.x11", tek_lib_display_x11_funcs); #else luaL_newlib(L, tek_lib_display_x11_funcs); #endif /* s: exectab, execbase, libtab */ lua_pushvalue(L, -1); /* s: exectab, execbase, libtab, libtab */ lua_insert(L, -4); /* s: libtab, exectab, execbase, libtab */ /* create userdata: */ display = lua_newuserdata(L, sizeof(TEKDisplay)); /* s: exectab, execbase, libtab, libbase */ display->Base = TNULL; display->ExecBase = exec; display->IsBase = TTRUE; /* register base: */ lua_pushvalue(L, -1); /* s: exectab, execbase, libtab, libbase, libbase */ lua_setfield(L, LUA_REGISTRYINDEX, TEK_LIB_DISPLAY_X11_BASECLASSNAME); /* s: exectab, execbase, libtab, libbase */ /* create metatable for userdata, register methods: */ luaL_newmetatable(L, TEK_LIB_DISPLAY_X11_CLASSNAME); /* s: exectab, execbase, libtab, libbase, libmeta */ lua_pushvalue(L, -1); /* s: exectab, execbase, libtab, libbase, libmeta, libmeta */ lua_setfield(L, -2, "__index"); /* s: exectab, execbase, libtab, libbase, libmeta */ #if LUA_VERSION_NUM < 502 luaL_register(L, NULL, tek_lib_display_x11_methods); #else luaL_setfuncs(L, tek_lib_display_x11_methods, 0); #endif /* s: exectab, execbase, libtab, libbase, libmeta */ lua_setmetatable(L, -2); /* s: exectab, execbase, libtab, libbase */ /* place exec reference in metatable: */ lua_getmetatable(L, -1); /* s: exectab, execbase, libtab, libbase, libmeta */ lua_pushvalue(L, -4); /* s: exectab, execbase, libtab, libbase, libmeta, execbase */ luaL_ref(L, -2); /* index returned is always 1 */ /* s: exectab, execbase, libtab, libbase, libmeta */ lua_pop(L, 5); /* Add visual module to TEKlib's internal module list: */ TExecAddModules(exec, (struct TModInitNode *) &im_display, 0); return 1; }
RegistoryRef(lua_State* state, StackTop) :state_(state), ref_(LUA_REFNIL) { if (!state_) { return; } ref_ = luaL_ref(state_, LUA_REGISTRYINDEX); state_ = util::toMainThread(state_); }
RegistoryRef(lua_State* state, StackTop, NoMainCheck) :state_(state), ref_(LUA_REFNIL) { if (!state_) { return; } ref_ = luaL_ref(state_, LUA_REGISTRYINDEX); }
int LuaInterface::ref() { return luaL_ref(L, LUA_REGISTRYINDEX); }
EventData::EventData(lua_State *st) { this->_st = st; this->_ref = luaL_ref(st, LUA_REGISTRYINDEX); }
int check_daoack(lua_State *L) { lua_pushlightfunction(L, libmsgpack_mp_unpack); lua_pushvalue(L, lua_upvalueindex(1)); lua_call(L, 1, 1); int t_idx=lua_gettop(L); lua_pushstring(L, "dest"); lua_gettable(L, t_idx); char *d_ip= (char *)lua_tostring(L, -1); lua_getglobal(L, "DAO_ACK"); int dt_idx=lua_gettop(L); lua_pushstring(L, -2); //ip address of required destination lua_gettable(L, -2); if(isnil(L, -1)) //No dao_ack for this ip addr { lua_getglobal(L, "PFLAG"); int pflag = lua_tonumber(L, -1); if(pflag > 5) //more than 5 retransmissions already occured to this parent { //Parent is dead, find new parent lua_getglobal(L, "parent_table"); int p_idx=lua_gettop(L); lua_pushnil(L); if(lua_next(L, p_idx)==0) // no elements in the parent table { //send poisoning DIO to release all children //rebroadcast DIS //reinitialise dio, dis, all tables } else { //IP Addr of next parent is at index -2 char *p_ip = (char *)lua_tostring(L, -2); int p_rank = lua_tonumber(L, -1); //rank of new parent lua_pop(L, 1); //now Parent IP is on top of the stack (after popping rank) lua_setglobal(L, "PrefParent"); //remove node from parent table lua_pushstring(L, p_ip); int ref = luaL_ref (L, p_idx); luaL_unref(L, p_idx, ref); //remove all nodes from parent table whose rank is less than new rank lua_pushnil(L); while(lua_next(L, p_idx)!=0) { if(lua_tonumber(L, -1) > p_rank) { lua_pushvalue(L, -2); // srcip (key) of next parent) ref = luaL_ref (L, p_idx); luaL_unref(L, p_idx, ref); //remove entry from table //lua_pop(L, 1); //if lua_unref does not pop reference from top of the stack } lua_pop(L, 1); } //send dis to preferred parent, wait for DIO lua_pushlightfunction(L, libstorm_net_sendto); lua_getglobal(L,"diomcast_sock"); lua_pushlightfunction(L, libmsgpack_mp_pack); lua_getglobal(L, "DIS"); lua_call(L, 1, 1); lua_pushstring(L, p_ip); lua_pushnumber(L, disrecvport); lua_call(L, 4, 1); //send new DAO all the way to the root with your own information } lua_pushnumber(L, 0); lua_setglobal(L, "PFLAG"); return 0; } lua_pushnumber(L, pflag + 1); lua_setglobal(L, "PFLAG"); lua_pushlightfunction(L, send_dao); lua_pushvalue(L, 1); //push the packed prefix table onto the stack lua_call(L, 1, 0); } else //ACK Received, no need to call send again, remove DAO_ACK from table { lua_pushstring(L, d_ip); int ref = luaL_ref (L, p_idx); luaL_unref(L, p_idx, ref); lua_pushvalue(L, dt_idx); lua_setglobal(L, "DAO_ACK"); lua_pushnumber(L, 0); lua_setglobal(L, "PFLAG"); //Parent flag, to check if prefparent is alive } return 0; }
// Stores item at the given stack position into the registry. int luah_store_in_registry(lua_State *L, int stackpos) { lua_pushvalue(L, stackpos); return luaL_ref(L, LUA_REGISTRYINDEX); }
const char *luaex_cmd_Reslist(cmd_parms *cmd, void *dcfg, const char *resource, const char *script) { struct dir_config *conf = dcfg; const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); module* lua_module = ml_find_module(cmd->server, "lua_module"); if (err != NULL) return err; if (conf->resource == NULL) { conf->resource = apr_hash_make(cmd->pool); } if (conf->L == NULL) { conf->L = luaL_newstate(); #ifdef AP_ENABLE_LUAJIT luaopen_jit(conf->L); #endif luaL_openlibs(conf->L); } if (apr_hash_get(conf->resource, resource, strlen(resource)) == NULL) { lua_State *L = conf->L; int err = luaL_loadfile(L, script); if (err == LUA_ERRFILE) return apr_psprintf(cmd->pool, "cannot open/read: %s. ", script); if (err == LUA_ERRSYNTAX) return apr_psprintf(cmd->pool, "syntax error during pre-compilation for: %s. ", script); if (err == LUA_ERRMEM) return apr_psprintf(cmd->pool, "memory allocation error for load: %s. ", script); if (err) return apr_psprintf(cmd->pool, "unknown error)(%d) for load: %s. ", err, script); err = lua_pcall(L, 0, LUA_MULTRET, 0); if (err == LUA_ERRRUN) return apr_psprintf(cmd->pool, "a runtime error. %s", lua_tostring(L, -1)); if (err == LUA_ERRMEM) return apr_psprintf(cmd->pool, "memory allocation error. %s", lua_tostring(L, -1)); if (err == LUA_ERRERR) return apr_psprintf(cmd->pool, "error while running the error handler function. %s", lua_tostring(L, -1)); if (err) return apr_psprintf(cmd->pool, "unknown error(%d:%s) for load: %s. ", err, lua_tostring(L, -1), script); { int min, smax, hmax, ttl; apr_reslist_t* reslist; reslist_cb_t* cb = apr_palloc(cmd->pool, sizeof(reslist_cb_t)); luaL_getmetatable(L, resource); if (lua_isnil(L, -1)) return apr_psprintf(cmd->pool, "%s not support %s object(metatable)", script, resource); cb->name = resource; lua_pop(L, 1); if (!lua_istable(L, -1)) return apr_psprintf(cmd->pool, "%s not return a table which makes a reslist for %s", script, resource); cb->L = conf->L; lua_getfield(L, -1, "constructor"); if (!lua_isfunction(L, -1)) return apr_psprintf(cmd->pool, "%s not have a table field(constructor) function", script); cb->constructor_ref = luaL_ref(L, LUA_REGISTRYINDEX); lua_getfield(L, -1, "destructor"); if (!lua_isfunction(L, -1)) return apr_psprintf(cmd->pool, "%s not have a table field(destructor) function", script); cb->destructor_ref = luaL_ref(L, LUA_REGISTRYINDEX); lua_getfield(L, -1, "min"); min = luaL_optint(L, -1, 0); lua_pop(L, 1); lua_getfield(L, -1, "smax"); smax = luaL_optint(L, -1, 16); lua_pop(L, 1); lua_getfield(L, -1, "hmax"); hmax = luaL_optint(L, -1, 16); lua_pop(L, 1); lua_getfield(L, -1, "ttl"); ttl = luaL_optint(L, -1, 0); lua_pop(L, 1); if (apr_reslist_create(&reslist, min, smax, hmax, ttl, ml_apr_reslist_constructor, ml_apr_reslist_destructor, cb, cmd->pool) == APR_SUCCESS) { apr_hash_set(conf->resource, resource, strlen(resource), reslist); } else return "apr_reslist_create failed"; } } if (conf->resource == NULL) return "Out of memory"; return NULL; }
static int lgetopt_long_t(lua_State *l, func_t func) { const char *optstring = NULL; int result = 1; /* assume success */ int argc, ch, idx; char **argv = NULL; int error_func = 0; int numargs = lua_gettop(l); if ((numargs != 2 && numargs != 3 && numargs != 4) || lua_type(l,1) != LUA_TSTRING || lua_type(l,2) != LUA_TTABLE || (numargs >= 3 && (lua_type(l,3) != LUA_TTABLE && lua_type(l,3) != LUA_TNIL))) { ERROR("usage: getopt.long(optionstring, longopts[, resulttable[, errorfunc]])"); } if (numargs == 4 && lua_type(l,4) != LUA_TFUNCTION && lua_type(l,4) != LUA_TNIL) { ERROR("usage: getopt.long(optionstring, longopts[, resulttable[, errorfunc]])"); } if (numargs == 4 && lua_type(l,4) == LUA_TFUNCTION) { // We can't copy the error function - but we can make a // registry pointer. error_func = luaL_ref(l, LUA_REGISTRYINDEX); } optstring = lua_tostring(l, 1); /* Construct fake argc/argv from the magic lua 'arg' table. */ lua_getglobal(l, "arg"); construct_args(l, lua_gettop(l), &argc, &argv); lua_pop(l, 1); /* Construct a longopts struct from the one given. */ char **bound_variable_name = NULL; int *bound_variable_value = NULL; struct option *longopts = build_longopts(l, 2, &bound_variable_name, &bound_variable_value); /* Parse the options and store them in the Lua table. */ idx = -1; /* initialize idx to -1 so we can tell whether or not it's * updated by getopt_long (or whatever func() is) */ while ((ch=func(argc, argv, optstring, longopts, &idx)) > -1) { char buf[2] = { ch, 0 }; if (ch == '?' || ch == ':') { /* This is a special "got a bad option" character. Don't put it * in the table of results; just record that there's a failure. * The getopt call will have emitted an error to stderr. */ if (error_func) { lua_rawgeti(l, LUA_REGISTRYINDEX, error_func); lua_pushstring(l, buf); lua_call(l, 1, 0); // 1 argument, 0 results. Not protecting against errors. } result = 0; break; } if (idx == -1) { /* If idx == -1, then it wasn't updated by the library call; * that happens if it matches a short option. We'll have to dig * through and find it ourself. */ struct option *l = longopts; int i = 0; while (l[i].name) { if (l[i].val != 0 && l[i].val == ch) { idx = i; if (l[i].flag != NULL) { /* Fake the longopt "this is a bound variable thing" even * though it was called with a short variable? :/ */ ch = 0; *l[i].flag = l[i].val; } break; } i++; } } else { /* If we matched a long option with a val set, but the 'ch' is zero, * then we need to dig the character out of the option's "val" field * so we can set the captured value appropriately in the return opts. */ if (longopts[idx].val) { buf[0] = longopts[idx].val; if (longopts[idx].val <= 9) { /* Coerce to a character, rather than an integer */ buf[0] += '0'; } } } /* Call any available callbacks for this element, if we found the * element in the longopts struct list. */ if (idx != -1) { _call_callback(l, 2, &longopts[idx]); } /* Save the values in the user-specified return table. */ if (buf[0] && numargs >= 3 && lua_type(l,3) == LUA_TTABLE) { if (optarg) { lua_pushstring(l, optarg); } else { lua_pushboolean(l, 1); } lua_setfield(l, 3, buf); } if (ch == 0) { /* This is the special "bound a variable" return value. Perform * the bind. */ set_lua_variable(l, bound_variable_name[idx], bound_variable_value[idx]); } idx = -1; } /* Since the default behavior of many (but not all) getopt libraries is to * reorder argv so that non-arguments are all at the end (unless * POSIXLY_CORRECT is set or the options string begins with a '+'), we'll * go do that now. We do it by modifying the existing global table, which * will leave index [-1] in place if it's set (as it sometimes is). */ lua_getglobal(l, "arg"); int i; for (i=0; i<argc; i++) { lua_pushinteger(l, i); lua_pushstring(l, argv[i]); lua_rawset(l, -3); } free_longopts(longopts, bound_variable_name, bound_variable_value); free_args(argc, argv); if (error_func) { luaL_unref(l, LUA_REGISTRYINDEX, error_func); } /* Return 1 item on the stack (boolean) */ lua_pushboolean(l, result); return 1; /* # of arguments returned on stack */ }
static void dt_film_import1(dt_job_t *job, dt_film_t *film) { gboolean recursive = dt_conf_get_bool("ui_last/import_recursive"); /* first of all gather all images to import */ GList *images = NULL; images = _film_recursive_get_files(film->dirname, recursive, &images); if(g_list_length(images) == 0) { dt_control_log(_("no supported images were found to be imported")); return; } #ifdef USE_LUA /* pre-sort image list for easier handling in Lua code */ images = g_list_sort(images, (GCompareFunc)_film_filename_cmp); dt_lua_lock(); lua_State *L = darktable.lua_state.state; { GList *elt = images; lua_newtable(L); while(elt) { lua_pushstring(L, elt->data); luaL_ref(L, -2); elt = g_list_next(elt); } } lua_pushvalue(L, -1); dt_lua_event_trigger(L, "pre-import", 1); { g_list_free_full(images, g_free); // recreate list of images images = NULL; lua_pushnil(L); /* first key */ while(lua_next(L, -2) != 0) { /* uses 'key' (at index -2) and 'value' (at index -1) */ void *filename = strdup(luaL_checkstring(L, -1)); lua_pop(L, 1); images = g_list_prepend(images, filename); } } lua_pop(L, 1); // remove the table again from the stack dt_lua_unlock(); #endif if(g_list_length(images) == 0) { // no error message, lua probably emptied the list on purpose return; } /* we got ourself a list of images, lets sort and start import */ images = g_list_sort(images, (GCompareFunc)_film_filename_cmp); /* let's start import of images */ gchar message[512] = { 0 }; double fraction = 0; guint total = g_list_length(images); g_snprintf(message, sizeof(message) - 1, ngettext("importing %d image", "importing %d images", total), total); dt_control_job_set_progress_message(job, message); /* loop thru the images and import to current film roll */ dt_film_t *cfr = film; GList *image = g_list_first(images); do { gchar *cdn = g_path_get_dirname((const gchar *)image->data); /* check if we need to initialize a new filmroll */ if(!cfr || g_strcmp0(cfr->dirname, cdn) != 0) { // FIXME: maybe refactor into function and call it? if(cfr && cfr->dir) { /* check if we can find a gpx data file to be auto applied to images in the jsut imported filmroll */ g_dir_rewind(cfr->dir); const gchar *dfn = NULL; while((dfn = g_dir_read_name(cfr->dir)) != NULL) { /* check if we have a gpx to be auto applied to filmroll */ size_t len = strlen(dfn); if(strcmp(dfn + len - 4, ".gpx") == 0 || strcmp(dfn + len - 4, ".GPX") == 0) { gchar *gpx_file = g_build_path(G_DIR_SEPARATOR_S, cfr->dirname, dfn, NULL); gchar *tz = dt_conf_get_string("plugins/lighttable/geotagging/tz"); dt_control_gpx_apply(gpx_file, cfr->id, tz); g_free(gpx_file); g_free(tz); } } } /* cleanup previously imported filmroll*/ if(cfr && cfr != film) { if(dt_film_is_empty(cfr->id)) { dt_film_remove(cfr->id); } dt_film_cleanup(cfr); free(cfr); cfr = NULL; } /* initialize and create a new film to import to */ cfr = malloc(sizeof(dt_film_t)); dt_film_init(cfr); dt_film_new(cfr, cdn); } g_free(cdn); /* import image */ dt_image_import(cfr->id, (const gchar *)image->data, FALSE); fraction += 1.0 / total; dt_control_job_set_progress(job, fraction); } while((image = g_list_next(image)) != NULL); g_list_free_full(images, g_free); // only redraw at the end, to not spam the cpu with exposure events dt_control_queue_redraw_center(); dt_control_signal_raise(darktable.signals, DT_SIGNAL_TAG_CHANGED); dt_control_signal_raise(darktable.signals, DT_SIGNAL_FILMROLLS_IMPORTED, film->id); // FIXME: maybe refactor into function and call it? if(cfr && cfr->dir) { /* check if we can find a gpx data file to be auto applied to images in the just imported filmroll */ g_dir_rewind(cfr->dir); const gchar *dfn = NULL; while((dfn = g_dir_read_name(cfr->dir)) != NULL) { /* check if we have a gpx to be auto applied to filmroll */ size_t len = strlen(dfn); if(strcmp(dfn + len - 4, ".gpx") == 0 || strcmp(dfn + len - 4, ".GPX") == 0) { gchar *gpx_file = g_build_path(G_DIR_SEPARATOR_S, cfr->dirname, dfn, NULL); gchar *tz = dt_conf_get_string("plugins/lighttable/geotagging/tz"); dt_control_gpx_apply(gpx_file, cfr->id, tz); g_free(gpx_file); g_free(tz); } } } /* cleanup previously imported filmroll*/ if(cfr && cfr != film) { dt_film_cleanup(cfr); free(cfr); } }
static int laura_do_async_call(lua_State *L) { struct laura_node *lnode = NULL; const char *name; struct aura_buffer *buf; struct aura_object *o; int ret; int callback_ref; TRACE(); /* Sanity */ lnode = lua_fetch_node(L, 1); if (!lnode) { lua_stackdump(L); return aura_typeerror(L, 1, "userdata (node)"); } if (!lua_isstring(L, 2)) { lua_stackdump(L); return aura_typeerror(L, 2, "string (object name)"); } if (!lua_isfunction(L, 3)) { lua_stackdump(L); return aura_typeerror(L, 3, "function (callback)"); } name = lua_tostring(L, 2); o = aura_etable_find(lnode->node->tbl, name); if (!o) return luaL_error(L, "Attempt to call non-existend method"); if (!object_is_method(o)) { lua_stackdump(L); return luaL_error(L, "Attempt to call an event"); } /* Now we're sane! */ buf = lua_to_buffer(L, lnode->node, 5, o); if (!buf) return luaL_error(L, "Serializer failed!"); /* Let's create a table to store our callback and arg */ lua_newtable(L); /* Push the callback function there */ lua_pushnumber(L, 1); lua_pushvalue(L, 3); lua_settable(L, -3); /* And the user argument */ lua_pushnumber(L, 2); lua_pushvalue(L, 4); lua_settable(L, -3); /* And fetch the reference to out table that we'll use in callback */ callback_ref = luaL_ref(L, LUA_REGISTRYINDEX); slog(4, SLOG_DEBUG, "Callback tbl reference: %d", callback_ref); ret = aura_core_start_call(lnode->node, o, calldone_cb, (void *)(long)callback_ref, buf); if (ret != 0) { aura_buffer_release(buf); return luaL_error(L, "Async call for %s failed: %s code (%d)", o->name, strerror(-ret), ret); } return 0; }
/* * rspamd_dispatcher.create(base,fd, read_cb, write_cb, err_cb[, timeout]) */ static int lua_io_dispatcher_create (lua_State *L) { struct rspamd_io_dispatcher_s *io_dispatcher, **pdispatcher; gint fd; struct lua_dispatcher_cbdata *cbdata; struct timeval tv = {0, 0}; double tv_num, tmp; if (lua_gettop (L) >= 5 && lua_isfunction (L, 3) && lua_isfunction (L, 5)) { cbdata = g_slice_alloc0 (sizeof (struct lua_dispatcher_cbdata)); cbdata->base = lua_check_event_base (L); if (cbdata->base == NULL) { /* Create new event base */ msg_warn ("create new event base as it is not specified"); cbdata->base = event_init (); } cbdata->L = L; fd = lua_tointeger (L, 2); lua_pushvalue (L, 3); cbdata->cbref_read = luaL_ref (L, LUA_REGISTRYINDEX); if (lua_isfunction (L, 4)) { /* Push write callback as well */ lua_pushvalue (L, 4); cbdata->cbref_write = luaL_ref (L, LUA_REGISTRYINDEX); } /* Error callback */ lua_pushvalue (L, 5); cbdata->cbref_err = luaL_ref (L, LUA_REGISTRYINDEX); if (lua_gettop (L) > 5) { tv_num = lua_tonumber (L, 6); tv.tv_sec = trunc (tv_num); tv.tv_usec = modf (tv_num, &tmp) * 1000.; io_dispatcher = rspamd_create_dispatcher (cbdata->base, fd, BUFFER_LINE, lua_io_read_cb, lua_io_write_cb, lua_io_err_cb, &tv, cbdata); } else { io_dispatcher = rspamd_create_dispatcher (cbdata->base, fd, BUFFER_LINE, lua_io_read_cb, lua_io_write_cb, lua_io_err_cb, NULL, cbdata); } cbdata->d = io_dispatcher; /* Push result */ pdispatcher = lua_newuserdata (L, sizeof (struct rspamd_io_dispatcher_s *)); rspamd_lua_setclass (L, "rspamd{io_dispatcher}", -1); *pdispatcher = io_dispatcher; } else { msg_err ("invalid number of arguments to io_dispatcher.create: %d", lua_gettop (L)); lua_pushnil (L); } return 1; }
static int gas_new(lua_State *L) { int w = luaL_checknumber(L, 1); int h = luaL_checknumber(L, 2); // int density = luaL_checknumber(L, 3); GLuint *t = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 5); int t_ref = luaL_ref(L, LUA_REGISTRYINDEX); int p_ref = luaL_ref(L, LUA_REGISTRYINDEX); gaszone_type *gz = (gaszone_type*)lua_newuserdata(L, sizeof(gaszone_type)); auxiliar_setclass(L, "core{gas}", -1); gz->last_tick = -1; gz->w = w; gz->h = h; gz->n = (w*2 > h*2) ? w*2 : h*2; gz->size = (gz->n + 2) * (gz->n + 2); gz->visc = 1E-4f; gz->diff = 1E-5f; gz->force = 20.0f; gz->source = 3000.0f; gz->stepDelay = 0.0f; gz->texture = *t; gz->texture_ref = t_ref; gz->u = calloc(gz->size, sizeof(float)); gz->v = calloc(gz->size, sizeof(float)); gz->dens = calloc(gz->size, sizeof(float)); gz->u_prev = calloc(gz->size, sizeof(float)); gz->v_prev = calloc(gz->size, sizeof(float)); gz->dens_prev = calloc(gz->size, sizeof(float)); int i; for (i=0; i < gz->size; i++) { gz->u[i] = 0.0f; gz->u_prev[i] = 0.0f; gz->v[i] = 0.0f; gz->v_prev[i] = 0.0f; gz->dens[i] = 0.0f; gz->dens_prev[i] = 0.0f; } printf("Making gas emitter with size %dx%d\n", w, h); // Grab all parameters lua_rawgeti(L, LUA_REGISTRYINDEX, p_ref); lua_pushstring(L, "generator"); lua_gettable(L, -2); if (lua_isnil(L, -1)) { lua_pop(L, 1); gz->generator_ref = LUA_NOREF; } else gz->generator_ref = luaL_ref(L, LUA_REGISTRYINDEX); if (gz->generator_ref == LUA_NOREF) { lua_pushstring(L, "Gas cloud created without a lua generator!"); lua_error(L); } lua_pop(L, 1); luaL_unref(L, LUA_REGISTRYINDEX, p_ref); return 1; }
// Lua: server/socket:send( string, function(sent) ) static int net_send( lua_State* L, const char* mt ) { // NODE_DBG("net_send is called.\n"); bool isserver = false; struct espconn *pesp_conn = NULL; lnet_userdata *nud; size_t l; nud = (lnet_userdata *)luaL_checkudata(L, 1, mt); luaL_argcheck(L, nud, 1, "Server/Socket expected"); if(nud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } if(nud->pesp_conn == NULL){ NODE_DBG("nud->pesp_conn is NULL.\n"); return 0; } pesp_conn = nud->pesp_conn; if (mt!=NULL && c_strcmp(mt, "net.server")==0) isserver = true; else if (mt!=NULL && c_strcmp(mt, "net.socket")==0) isserver = false; else { NODE_DBG("wrong metatable for net_send.\n"); return 0; } if(isserver && nud->pesp_conn->type == ESPCONN_TCP){ return luaL_error( L, "tcp server send not supported" ); } #if 0 char temp[20] = {0}; c_sprintf(temp, IPSTR, IP2STR( &(pesp_conn->proto.tcp->remote_ip) ) ); NODE_DBG("remote "); NODE_DBG(temp); NODE_DBG(":"); NODE_DBG("%d",pesp_conn->proto.tcp->remote_port); NODE_DBG(" sending data.\n"); #endif const char *payload = luaL_checklstring( L, 2, &l ); if (l>1460 || payload == NULL) return luaL_error( L, "need <1460 payload" ); if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION){ lua_pushvalue(L, 3); // copy argument (func) to the top of stack if(nud->cb_send_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_send_ref); nud->cb_send_ref = luaL_ref(L, LUA_REGISTRYINDEX); } // SDK 1.4.0 changed behaviour, for UDP server need to look up remote ip/port if (isserver && pesp_conn->type == ESPCONN_UDP) { remot_info *pr = 0; if (espconn_get_connection_info (pesp_conn, &pr, 0) != ESPCONN_OK) return luaL_error (L, "remote ip/port unavailable"); pesp_conn->proto.udp->remote_port = pr->remote_port; os_memmove (pesp_conn->proto.udp->remote_ip, pr->remote_ip, 4); // The remot_info apparently should *not* be os_free()d, fyi } #ifdef CLIENT_SSL_ENABLE if(nud->secure) espconn_secure_sent(pesp_conn, (unsigned char *)payload, l); else #endif espconn_sent(pesp_conn, (unsigned char *)payload, l); return 0; }
int readline(lua_State *L) { int rc; char *termtype = getenv("TERM"); luaL_checktype(L, 1, LUA_TFUNCTION); // push onto the stack and then get a reference lua_pushvalue(L, 1); function_index = luaL_ref(L, LUA_REGISTRYINDEX); if(!termtype) { fprintf(stderr, "no TERM defined!\n"); exit(1); } ioctl(0, TCGETS, &old_termio); new_termio = old_termio; new_termio.c_lflag &= ~ECHO; new_termio.c_lflag &= ~ICANON; ioctl(0, TCSETS, &new_termio); signal(SIGQUIT, int_handler); signal(SIGINT, int_handler); signal(SIGWINCH, winch_handler); printf(sample); printf("\n"); // Setup terminfo stuff... rc = setupterm((char *)0, 1, (int *)0); fprintf(stderr, "rc=%d\n", rc); // rc = tgetent(NULL, termtype); // fprintf(stderr, "rc=%d\n", rc); // /* int y; for(y=0; strnames[y]; y++) { fprintf(stderr, "%d: %s\n", y, strnames[y]); } fprintf(stderr, "lines=%s\n", cursor_down); */ height = lines; width = columns; printf("w=%d h=%d\n", width, height); col = 0; row = 0; init_terminfo_data(); char *x = parm_down_cursor; printf("p=%p (%d)\n", x, strlen(x)); // for(t=0; t < strlen(x); t++) { // printf("> %d [%c] %d\n", t, x[t], x[t]); // } printf("arm=%d, eng=%d\n", auto_right_margin, eat_newline_glitch); // printf(tparm(setb, 4)); printf("HELLO\n"); // printf(tparm(setb, 0)); line = malloc(8192); strcpy(line, sample); line_len = strlen(line); int c; move_to((line_len/width), line_len%width); // show_line(); // fflush(stdout); int redraw = 1; while(1) { if(redraw) { redraw_line(L); redraw = 0; } fflush(stdout); c = read_key(); switch(c) { case KEY_LEFT: if(((row * width)+col) > 0) move_back(); break; case KEY_RIGHT: if(((row * width)+col) < line_len) move_on(); break; case KEY_DC: if(((row * width)+col) < line_len) { remove_char_at((row * width) + col); redraw = 1; } break; case 27: printf("X"); break; case 127: case 8: // if we are the first char of the screen then we need to backup to the // end of the previous line // if(((row * width)+col) > 0) { move_back(); remove_char_at((row * width) + col); redraw = 1; } break; default: insert_char_at((row * width) + col, c); move_on(); redraw = 1; } } return 0; }
static void net_server_connected(void *arg) // for tcp only { NODE_DBG("net_server_connected is called.\n"); struct espconn *pesp_conn = arg; int i = 0; lnet_userdata *skt = NULL; if(pesp_conn == NULL) return; #if 0 char temp[20] = {0}; c_sprintf(temp, IPSTR, IP2STR( &(pesp_conn->proto.tcp->remote_ip) ) ); NODE_DBG("remote "); NODE_DBG(temp); NODE_DBG(":"); NODE_DBG("%d",pesp_conn->proto.tcp->remote_port); NODE_DBG(" connected.\n"); #endif for(i=0;i<MAX_SOCKET;i++){ if(socket[i] == LUA_NOREF) // found empty slot { break; } } if(i>=MAX_SOCKET) // can't create more socket { NODE_ERR("MAX_SOCKET\n"); pesp_conn->reverse = NULL; // not accept this conn if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_disconnect(pesp_conn); return; } if(tcpserver_cb_connect_ref == LUA_NOREF) return; if(!gL) return; lua_rawgeti(gL, LUA_REGISTRYINDEX, tcpserver_cb_connect_ref); // get function // create a new client object skt = (lnet_userdata *)lua_newuserdata(gL, sizeof(lnet_userdata)); if(!skt){ NODE_ERR("can't newudata\n"); lua_pop(gL, 1); return; } // set its metatable luaL_getmetatable(gL, "net.socket"); lua_setmetatable(gL, -2); // pre-initialize it, in case of errors skt->self_ref = LUA_NOREF; lua_pushvalue(gL, -1); // copy the top of stack skt->self_ref = luaL_ref(gL, LUA_REGISTRYINDEX); // ref to it self, for module api to find the userdata socket[i] = skt->self_ref; // save to socket array socket_num++; skt->cb_connect_ref = LUA_NOREF; // this socket already connected skt->cb_reconnect_ref = LUA_NOREF; skt->cb_disconnect_ref = LUA_NOREF; skt->cb_receive_ref = LUA_NOREF; skt->cb_send_ref = LUA_NOREF; skt->cb_dns_found_ref = LUA_NOREF; #ifdef CLIENT_SSL_ENABLE skt->secure = 0; // as a server SSL is not supported. #endif skt->pesp_conn = pesp_conn; // point to the espconn made by low level sdk pesp_conn->reverse = skt; // let espcon carray the info of this userdata(net.socket) espconn_regist_recvcb(pesp_conn, net_socket_received); espconn_regist_sentcb(pesp_conn, net_socket_sent); espconn_regist_disconcb(pesp_conn, net_server_disconnected); espconn_regist_reconcb(pesp_conn, net_server_reconnected); // now socket[i] has the client ref, and stack top has the userdata lua_call(gL, 1, 0); // function(conn) }
LLUV_INTERNAL void lluv_req_ref_ctx(lua_State *L, lluv_req_t *req){ luaL_unref(L, LLUV_LUA_REGISTRY, req->ctx); req->ctx = luaL_ref(L, LLUV_LUA_REGISTRY); }
// Lua: socket/udpserver:on( "method", function(s) ) static int net_on( lua_State* L, const char* mt ) { NODE_DBG("net_on is called.\n"); bool isserver = false; lnet_userdata *nud; size_t sl; nud = (lnet_userdata *)luaL_checkudata(L, 1, mt); luaL_argcheck(L, nud, 1, "Server/Socket expected"); if(nud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } if (mt!=NULL && c_strcmp(mt, "net.server")==0) isserver = true; else if (mt!=NULL && c_strcmp(mt, "net.socket")==0) isserver = false; else { NODE_DBG("wrong metatable for net_on.\n"); return 0; } const char *method = luaL_checklstring( L, 2, &sl ); if (method == NULL) return luaL_error( L, "wrong arg type" ); luaL_checkanyfunction(L, 3); lua_pushvalue(L, 3); // copy argument (func) to the top of stack if(!isserver && nud->pesp_conn->type == ESPCONN_TCP && sl == 10 && c_strcmp(method, "connection") == 0){ if(nud->cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_connect_ref); nud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else if(!isserver && nud->pesp_conn->type == ESPCONN_TCP && sl == 12 && c_strcmp(method, "reconnection") == 0){ if(nud->cb_reconnect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_reconnect_ref); nud->cb_reconnect_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else if(!isserver && nud->pesp_conn->type == ESPCONN_TCP && sl == 13 && c_strcmp(method, "disconnection") == 0){ if(nud->cb_disconnect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_disconnect_ref); nud->cb_disconnect_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else if((!isserver || nud->pesp_conn->type == ESPCONN_UDP) && sl == 7 && c_strcmp(method, "receive") == 0){ if(nud->cb_receive_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_receive_ref); nud->cb_receive_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else if((!isserver || nud->pesp_conn->type == ESPCONN_UDP) && sl == 4 && c_strcmp(method, "sent") == 0){ if(nud->cb_send_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_send_ref); nud->cb_send_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else if(!isserver && nud->pesp_conn->type == ESPCONN_TCP && sl == 3 && c_strcmp(method, "dns") == 0){ if(nud->cb_dns_found_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_dns_found_ref); nud->cb_dns_found_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else{ lua_pop(L, 1); return luaL_error( L, "method not supported" ); } return 0; }
// Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) ) static int mqtt_socket_connect( lua_State* L ) { NODE_DBG("enter mqtt_socket_connect.\n"); lmqtt_userdata *mud = NULL; unsigned port = 1883; size_t il; ip_addr_t ipaddr; const char *domain; int stack = 1; unsigned secure = 0, auto_reconnect = 0; int top = lua_gettop(L); mud = (lmqtt_userdata *)luaL_checkudata(L, stack, "mqtt.socket"); luaL_argcheck(L, mud, stack, "mqtt.socket expected"); stack++; if(mud == NULL) return 0; if(mud->connected){ return luaL_error(L, "already connected"); } if(mud->pesp_conn){ //TODO: should I free tcp struct directly or ask user to call close()??? mud->pesp_conn->reverse = NULL; if(mud->pesp_conn->proto.tcp) c_free(mud->pesp_conn->proto.tcp); mud->pesp_conn->proto.tcp = NULL; c_free(mud->pesp_conn); mud->pesp_conn = NULL; } struct espconn *pesp_conn = NULL; pesp_conn = mud->pesp_conn = (struct espconn *)c_zalloc(sizeof(struct espconn)); if(!pesp_conn) return luaL_error(L, "not enough memory"); pesp_conn->proto.udp = NULL; pesp_conn->proto.tcp = (esp_tcp *)c_zalloc(sizeof(esp_tcp)); if(!pesp_conn->proto.tcp){ c_free(pesp_conn); pesp_conn = mud->pesp_conn = NULL; return luaL_error(L, "not enough memory"); } // reverse is for the callback function pesp_conn->reverse = mud; pesp_conn->type = ESPCONN_TCP; pesp_conn->state = ESPCONN_NONE; mud->connected = false; if( (stack<=top) && lua_isstring(L,stack) ) // deal with the domain string { domain = luaL_checklstring( L, stack, &il ); stack++; if (domain == NULL) { domain = "127.0.0.1"; } ipaddr.addr = ipaddr_addr(domain); c_memcpy(pesp_conn->proto.tcp->remote_ip, &ipaddr.addr, 4); NODE_DBG("TCP ip is set: "); NODE_DBG(IPSTR, IP2STR(&ipaddr.addr)); NODE_DBG("\n"); } if ( (stack<=top) && lua_isnumber(L, stack) ) { port = lua_tointeger(L, stack); stack++; NODE_DBG("TCP port is set: %d.\n", port); } pesp_conn->proto.tcp->remote_port = port; pesp_conn->proto.tcp->local_port = espconn_port(); mud->mqtt_state.port = port; if ( (stack<=top) && lua_isnumber(L, stack) ) { secure = lua_tointeger(L, stack); stack++; if ( secure != 0 && secure != 1 ){ secure = 0; // default to 0 } } else { secure = 0; // default to 0 } mud->secure = secure; // save if ( (stack<=top) && lua_isnumber(L, stack) ) { auto_reconnect = lua_tointeger(L, stack); stack++; if ( auto_reconnect != 0 && auto_reconnect != 1 ){ auto_reconnect = 0; // default to 0 } } else { auto_reconnect = 0; // default to 0 } mud->mqtt_state.auto_reconnect = auto_reconnect; // call back function when a connection is obtained, tcp only if ((stack<=top) && (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION)){ lua_pushvalue(L, stack); // copy argument (func) to the top of stack if(mud->cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_connect_ref); mud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); stack++; } lua_pushvalue(L, 1); // copy userdata to the top of stack if(mud->self_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, mud->self_ref); mud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); espconn_regist_connectcb(pesp_conn, mqtt_socket_connected); espconn_regist_reconcb(pesp_conn, mqtt_socket_reconnected); os_timer_disarm(&mud->mqttTimer); os_timer_setfn(&mud->mqttTimer, (os_timer_func_t *)mqtt_socket_timer, mud); // timer started in socket_connect() if((ipaddr.addr == IPADDR_NONE) && (c_memcmp(domain,"255.255.255.255",16) != 0)) { host_ip.addr = 0; dns_reconn_count = 0; if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, socket_dns_found)){ socket_dns_found(domain, &host_ip, pesp_conn); // ip is returned in host_ip. } } else { socket_connect(pesp_conn); } NODE_DBG("leave mqtt_socket_connect.\n"); return 0; }