extern "C" { #include #include #include } #include #include #include //nanomsg things #include #include #include #include #include #include #include #include #include "load_net.hpp" //#include #include "../util/hashmap.h" std::map> netfuncs; void gameloop_net(lua_State* L){ //printf("Doing net of gameloop\n"); for(std::map>::iterator it = netfuncs.begin(); it != netfuncs.end(); ++it){ //printf("Looking for new data for socket %d\n",it->first); char* buf = NULL; int bytes = nn_recv(it->first, &buf, NN_MSG,NN_DONTWAIT); //printf("After recv\n"); if(bytes < 0 && nn_errno() != EAGAIN){ lua_pushstring(L,"Failed to receive"); lua_error(L); }else if( bytes < 0 && nn_errno() == EAGAIN){ //do nothing }else{ //find how long until the first null character int msglen = strlen(buf); char msg[msglen]; msg[msglen] = '\0'; sprintf(msg,"%s",buf); std::map themap = it->second; std::string s = std::string(msg); std::map::iterator in = themap.find(s); if(in != themap.end()){ lua_rawgeti(L,LUA_REGISTRYINDEX,(*in).second); lua_newtable(L); lua_call(L,1,0); } nn_freemsg(buf); } } //hashmap_iterate(netfuncs,check_socket,0); } int bindsocket(lua_State*L){ const char* s = lua_tostring(L,-1); lua_pushstring(L,"fd"); lua_gettable(L,-2); lua_pop(L,2); int fd = lua_tonumber(L,-1); int id = nn_bind(fd,s); if(id < 0){ const char* errstr = nn_strerror(nn_errno()); char* failmsg = "Failed to bind socket: "; int faillen = strlen(failmsg + 2); char buf[faillen + strlen(errstr)]; sprintf(buf,"%s%s\n",failmsg,errstr); lua_pushstring(L,buf); lua_error(L); } lua_pushstring(L,"endpoint"); lua_pushinteger(L,id); lua_settable(L,-3); netfuncs[fd] = std::map(); return 0; } int connectsocket(lua_State* L){ const char* s = lua_tostring(L,-1); lua_pushstring(L,"fd"); lua_gettable(L,-2); int fd = lua_tonumber(L,-1); lua_pop(L,2); int id = nn_connect(fd,s); lua_pushstring(L,"endpoint"); lua_pushinteger(L,id); lua_settable(L,-3); netfuncs[fd] = std::map(); return 0; } int send(lua_State* L){ const char* data = lua_tostring(L,-1); lua_pushstring(L,"fd"); lua_gettable(L,-2); int fd = lua_tonumber(L,-1); int dlen = strlen(data); int err = nn_send(fd,(void*)data,dlen,0); if(err < 0){ const char* errstr = nn_strerror(nn_errno()); char* failmsg = "Failed to bind socket: "; int faillen = strlen(failmsg + 2); char buf[faillen + strlen(errstr)]; sprintf(buf,"%s%s\n",failmsg,errstr); lua_pushstring(L,buf); lua_error(L); } return 0; } //LUA: //socket:receive(s_name,function(socket)) int netreceive(lua_State* L){ const char* name = lua_tostring(L,-2); int slen = strlen(name); std::string s = std::string(name); int func = luaL_ref(L,LUA_REGISTRYINDEX); lua_pushstring(L,"fd"); lua_gettable(L,-2); int fd = lua_tonumber(L,-1); lua_pop(L,1); netfuncs[fd].insert(std::pair(s,func)); return 0; } int socketFactory(lua_State*L){ int domain = luaL_optint(L,-1,0); int type = luaL_optint(L,-2,0); int c = nn_socket(AF_SP,NN_PAIR); if(c < 0){ lua_pushstring(L,"Failed to create socket"); lua_error(L); } luaL_getmetatable(L,"net.socket"); lua_setmetatable(L,-2); lua_newtable(L); lua_pushstring(L,"fd"); lua_pushinteger(L,c); lua_settable(L,-3); lua_pushstring(L,"bind"); lua_pushcfunction(L,bindsocket); lua_settable(L,-3); lua_pushstring(L,"connect"); lua_pushcfunction(L,connectsocket); lua_settable(L,-3); lua_pushstring(L,"send"); lua_pushcfunction(L,send); lua_settable(L,-3); lua_pushstring(L,"receive"); lua_pushcfunction(L,netreceive); lua_settable(L,-3); return 1; } static const struct luaL_Reg socket_m[] = { {"bind", bindsocket}, {NULL,NULL} }; #define set_const(l,x) lua_pushstring(l,#x);lua_pushinteger(l,x);lua_settable(l,-3); void loadNetLibs(lua_State* L){ //A table to hold all our net funcs lua_newtable(L); //Push some enums set_const(L,AF_SP); set_const(L,AF_SP_RAW); set_const(L,NN_PROTO_PAIR); set_const(L,NN_PAIR); set_const(L,NN_SUB); set_const(L,NN_SUB_SUBSCRIBE); set_const(L,NN_PUB); set_const(L,NN_SUB_UNSUBSCRIBE); set_const(L,NN_PUSH); set_const(L,NN_PULL); set_const(L,NN_PROTO_PIPELINE); set_const(L,NN_PROTO_SURVEY); set_const(L,NN_SURVEYOR); set_const(L,NN_RESPONDENT); set_const(L,NN_SURVEYOR_DEADLINE); set_const(L,NN_TCP_NODELAY); set_const(L,NN_TCP); set_const(L,NN_PROTO_BUS); set_const(L,NN_BUS); set_const(L,NN_DONTWAIT); set_const(L,PROTO_SP); set_const(L,SP_HDR); lua_pushstring(L,"create_socket"); lua_pushcfunction(L,socketFactory); lua_settable(L,-3); //Set the table to gobal "net" lua_setglobal(L,"net"); //Create the metatable for sockets luaL_newmetatable(L,"net.socket"); lua_pushvalue(L,-1); lua_setfield(L,-2,"__index"); luaL_register(L,NULL,socket_m); }