extern "C" { #include #include #include } #include #include #include //nanomsg things #include #include #include #include #include #include #include #include #include "load_net.hpp" #include #include "stream.hpp" std::map> netfuncs; // stream:readInt() int lstream_readInt(lua_State* L){//self lua_getfield(L,-1,"data");//self,lightuserdata if(!lua_islightuserdata(L,-1)){ lua_pushstring(L,"data field was not light userdata"); lua_error(L); } struct stream* s = (struct stream*)lua_touserdata(L,-1);//self,lightuserdata printf("Stream in readint was %p\n",s); stream_print(s); int i = stream_readInt(s); printf("In readint, int read from stream was %d\n",i); lua_pop(L,2);// lua_pushinteger(L,i);//int return 1; } // stream:writeInt(number) int lstream_writeInt(lua_State* L){//self,number lua_getfield(L,-2,"data");//self,number,lightuserdata struct stream* s = (struct stream*)lua_touserdata(L,-1);//self,number,lightuserdata printf("Stream in writeInt was %p\n",s); stream_print(s); int num = lua_tointeger(L,-2);//self,number,lightuserdata printf("Integer was %d\n",num); stream_writeInt(s,num); lua_pop(L,3);// return 0; } void gameloop_net(lua_State* L){ //printf("Doing net of gameloop\n"); for(std::map>::iterator it = netfuncs.begin(); it != netfuncs.end(); ++it){ char* buf = NULL; int bytes = nn_recv(it->first, &buf, NN_MSG,NN_DONTWAIT); 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 struct stream* stream = stream_create(); stream->length = bytes; stream->data = buf; stream_print(stream); char* msg = stream_readString(stream); 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_pushlightuserdata(L,stream); lua_setfield(L,-2,"data"); luaL_getmetatable(L,"net.stream"); lua_setmetatable(L,-2); lua_call(L,1,0); } nn_freemsg(buf); free(stream);//We manually set stream->data so free_stream would crash here } } } 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 = (char*)"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; } //socket:send("name",function(stream)) int send(lua_State* L){ const char* data = lua_tostring(L,-2);//socket,"name",function(stream) lua_pushstring(L,"fd");//socket,"name",function(stream),"fd" lua_gettable(L,-4);//socket,"name",function(stream),int_socketdescriptor int fd = lua_tonumber(L,-1);//socket,"name",function(stream),int_socketdescriptor lua_pop(L,1);//socket,"name",function(stream) int dlen = strlen(data); struct stream* s = stream_create(); stream_writeString(s,data,dlen); lua_newtable(L);//socket,"name",function(stream),streamtable luaL_getmetatable(L,"net.stream");//socket,"name",function(stream),streamtable,net.stream lua_setmetatable(L,-2);//socket,"name",function(stream),streamtable lua_pushlightuserdata(L,s);//socket,"name",function(stream),streamtable,lightudata lua_setfield(L,-2,"data");//socket,"name",function(stream),streamtable lua_call(L,1,0);//socket,"name" lua_pop(L,2);// int err = nn_send(fd,s->data,s->length,0); stream_free(s); if(err < 0){ const char* errstr = nn_strerror(nn_errno()); char* failmsg = (char*)"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(stream)) 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 streams luaL_newmetatable(L,"net.stream"); //net.stream lua_newtable(L); lua_pushcfunction(L,lstream_readInt);//net.stream,{},readInt() lua_setfield(L,-2,"readInt");//net.stream,{} lua_pushcfunction(L,lstream_writeInt);//net.stream,{},writeInt() lua_setfield(L,-2,"writeInt");//net.stream,{} lua_setfield(L,-2,"__index"); //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); }