diff options
Diffstat (limited to 'src/shared/lua_api/load_net.cpp')
| -rw-r--r-- | src/shared/lua_api/load_net.cpp | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/shared/lua_api/load_net.cpp b/src/shared/lua_api/load_net.cpp new file mode 100644 index 0000000..cd155fb --- /dev/null +++ b/src/shared/lua_api/load_net.cpp @@ -0,0 +1,224 @@ +extern "C" { + #include <lua.h> + #include <lauxlib.h> + #include <lualib.h> +} +#include <string.h> + +#include <string> +#include <map> + +//nanomsg things +#include <nn.h> +#include <tcp.h> +#include <pair.h> +#include <ipc.h> +#include <pipeline.h> +#include <pubsub.h> +#include <survey.h> +#include <bus.h> + +#include "load_net.hpp" + +//#include <zmq.h> +#include "../util/hashmap.h" + +std::map<int,std::map<std::string,int>> netfuncs; + +void gameloop_net(lua_State* L){ + //printf("Doing net of gameloop\n"); + for(std::map<int,std::map<std::string,int>>::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<std::string,int> themap = it->second; + std::string s = std::string(msg); + std::map<std::string,int>::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<std::string,int>(); + + 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<std::string,int>(); + + 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<std::string, int>(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); +} |
