From 36ad6ac957f2f6161c1ac4345a0004b7b6249ce5 Mon Sep 17 00:00:00 2001 From: "Garcia-Hernandez, Ruben Jesus (rgarcia)" <garcia@lrz.de> Date: Tue, 15 May 2018 11:42:10 +0200 Subject: [PATCH] Early multiuser support for HTC Vive. World status is saved in server. --- OpenVR/TimestepData/hellovr_opengl_main.cpp | 135 ++++++++++++++++---- proxy/Makefile | 2 +- proxy/proxy.cpp | 81 ++++++++++-- 3 files changed, 178 insertions(+), 40 deletions(-) diff --git a/OpenVR/TimestepData/hellovr_opengl_main.cpp b/OpenVR/TimestepData/hellovr_opengl_main.cpp index ebbbaca..8f8eeda 100644 --- a/OpenVR/TimestepData/hellovr_opengl_main.cpp +++ b/OpenVR/TimestepData/hellovr_opengl_main.cpp @@ -257,6 +257,8 @@ private: // OpenGL bookkeeping int currentset; + void IncrementTimestep(); + void DecrementTimestep(); float elapsedtime; static const float videospeed; int currentiso; @@ -353,6 +355,13 @@ private: // OpenGL bookkeeping std::thread *tcpconn; void connectTCP(); int sock; + void Send(char c, int32_t value); + void Send(char c, bool value); + void SendConfigFile(); + void SendTimestep(); + void SendIso(); + void SendShowAtoms(); + }; const float CMainApplication::videospeed = 0.01f; @@ -453,6 +462,7 @@ void CMainApplication::connectTCP() struct sockaddr_in serv_addr; struct hostent *he; if ( (he = gethostbyname(server) ) == nullptr ) { + eprintf ("Connect to server, could not get host name %s\n", server); return; /* error */ } memset((char *) &serv_addr, 0, sizeof(serv_addr)); @@ -461,6 +471,7 @@ void CMainApplication::connectTCP() serv_addr.sin_port = htons(port); sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if ( connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) { + eprintf ("Connect to server, could not get connection %s\n", server); return; /* error */ } //read state @@ -473,32 +484,42 @@ void CMainApplication::connectTCP() char what; while (true) { n=recv(sock, &what, sizeof(what), 0); - if (n<1) + if (n<1) { + eprintf ("closed socket\n"); return; + } switch (what) { case 't': n=recv (sock, (char*)&tmp, sizeof(tmp), 0); - if (n<sizeof(tmp)) + if (n<sizeof(tmp)) { + eprintf ("short read at socket\n"); return; + } currentset=ntohl(tmp)%TIMESTEPS; break; case 'i': n=recv (sock, (char*)&tmp, sizeof(tmp), 0); - if (n<sizeof(tmp)) + if (n<sizeof(tmp)) { + eprintf ("short read at socket\n"); return; + } currentiso=ntohl(tmp)%(ISOS+1); break; case 's': char s; n=recv (sock, &s, sizeof(s), 0); - if (n<sizeof(s)) + if (n<sizeof(s)) { + eprintf ("short read at socket\n"); return; + } showAtoms=(bool)s; break; case 'n': n=recv (sock, (char*)&tmp, sizeof(tmp), 0); - if (n<sizeof(tmp)) + if (n<sizeof(tmp)) { + eprintf ("short read at socket\n"); return; + } //load config file if (currentConfig!=ntohl(tmp)%myargc) { currentConfig=ntohl(tmp)%myargc; @@ -980,6 +1001,76 @@ void CMainApplication::Shutdown() SDL_Quit(); } +void CMainApplication::Send(char c, int32_t value) +{ + if (sock>=0) { + int32_t tmp; + tmp=htonl(value); + int n; + n=send(sock, &c, sizeof(c), 0); + if (n<sizeof(c)) { + closesocket(sock); + sock=-1; + } + n=send(sock, (char*)&tmp, sizeof(tmp), 0); + if (n<sizeof(tmp)) { + closesocket(sock); + sock=-1; + } + } +} + +void CMainApplication::Send(char c, bool value) +{ + if (sock>=0) { + int n; + n=send(sock, &c, sizeof(c), 0); + if (n<sizeof(c)) { + closesocket(sock); + sock=-1; + } + n=send(sock, (char*)&value, 1, 0); + if (n<1) { + closesocket(sock); + sock=-1; + } + } +} +void CMainApplication::SendConfigFile() +{ + Send('n', currentConfig); +} + +void CMainApplication::SendTimestep() +{ + Send('t', currentset); +} + +void CMainApplication::SendIso() +{ + Send('i', currentiso); +} + +void CMainApplication::SendShowAtoms() +{ + Send('s', showAtoms); +} + +void CMainApplication::IncrementTimestep() +{ + currentset++; + if (currentset >= TIMESTEPS) + currentset = 0; + SendTimestep(); +} + +void CMainApplication::DecrementTimestep() +{ +currentset--; +if (currentset < 0) + currentset = TIMESTEPS -1; +SendTimestep(); +} //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1012,19 +1103,16 @@ bool CMainApplication::HandleInput() } //rgh: add keyboard navigation here if (sdlEvent.key.keysym.sym == SDLK_1) { - currentset++; - if (currentset >= TIMESTEPS) - currentset = 0; + IncrementTimestep(); } if (sdlEvent.key.keysym.sym == SDLK_2) { - currentset--; - if (currentset < 0) - currentset = TIMESTEPS -1; + DecrementTimestep(); } if (sdlEvent.key.keysym.sym == SDLK_0) { currentiso++; if (currentiso > ISOS) currentiso = 0; + SendIso(); } if (sdlEvent.key.keysym.sym == SDLK_a) { Matrix4 tmp = m_mat4HMDPose; @@ -1089,22 +1177,7 @@ bool CMainApplication::HandleInput() currentConfig++; if (currentConfig>=myargc) currentConfig=1; - if (sock>=0) { - char w='c'; - int32_t tmp; - tmp=htonl(currentConfig); - int n; - n=send(sock, &w, sizeof(w), 0); - if (n<sizeof(w)) { - closesocket(sock); - sock=-1; - } - n=send(sock, (char*)&tmp, sizeof(tmp), 0); - if (n<sizeof(tmp)) { - closesocket(sock); - sock=-1; - } - } + SendConfigFile(); CleanScene(); LoadConfigFile(myargv[currentConfig]); SetupScene(); @@ -1113,6 +1186,7 @@ bool CMainApplication::HandleInput() currentConfig--; if (currentConfig<=0) currentConfig=myargc-1; + SendConfigFile(); CleanScene(); LoadConfigFile(myargv[currentConfig]); SetupScene(); @@ -1131,8 +1205,10 @@ bool CMainApplication::HandleInput() */ if (firstdevice==unDevice) savetodisk = !savetodisk; - else + else { showAtoms= !showAtoms; + SendShowAtoms(); + } } else if (buttonPressed[1][unDevice] && 0 == (state.ulButtonTouched&vr::ButtonMaskFromId(vr::k_EButton_ApplicationMenu)) && @@ -1161,10 +1237,12 @@ bool CMainApplication::HandleInput() currentset = TIMESTEPS - 1; else if (currentset > TIMESTEPS - 1) currentset=0; + SendTimestep(); } else { currentiso++; if (currentiso > ISOS) currentiso = 0; + SendIso(); } } else if (buttonPressed[0][unDevice] && ( (state.ulButtonTouched&vr::ButtonMaskFromId(vr::k_EButton_Grip)) == 0 && @@ -1197,6 +1275,7 @@ bool CMainApplication::HandleInput() currentset++; if (currentset >= TIMESTEPS) currentset = 0; + SendTimestep(); } } } diff --git a/proxy/Makefile b/proxy/Makefile index 7fcc2cd..15fd70c 100644 --- a/proxy/Makefile +++ b/proxy/Makefile @@ -1,5 +1,5 @@ proxy: proxy.cpp Makefile - g++ -g proxy.cpp -o proxy + g++ -std=c++11 -g proxy.cpp -o proxy clean: rm -f proxy.o proxy diff --git a/proxy/proxy.cpp b/proxy/proxy.cpp index f7a06b2..561295f 100644 --- a/proxy/proxy.cpp +++ b/proxy/proxy.cpp @@ -74,7 +74,7 @@ bool initNewSocket (unsigned int secret) tmp=htonl(state.iso); memcpy (buffer+6, &tmp, sizeof(state.iso)); buffer[10]='s'; - buffer[11]=(char)true; + buffer[11]=(char)state.showatoms; buffer[12]='n'; tmp=htonl(state.ncfg); memcpy (buffer+13, &tmp, sizeof(state.iso)); @@ -110,6 +110,20 @@ bool initNewSocket (unsigned int secret) return true; } +int myrecv(int sock,char *buffer,int len, int flags) { + int n=len; + char *mybuff=buffer; + int r; + do { + r=recv (sock, mybuff, n, flags); + if (r<0) + return r; + mybuff+=r; + n-=r; + } while (n>0); + return len; +} + int main(int argc, char *argv[]) { unsigned int secret; @@ -205,45 +219,90 @@ for (;;) { for (unsigned i=1;i<sockfds.size();i++) if (FD_ISSET (sockfds[i], &read_fd_set)) { - n = recv(sockfds[i],buffer,255, 0); + n = myrecv(sockfds[i],buffer,1, 0); + fprintf (stderr, "received %d bytes from socket %d\n", n, i); + if (n<0) { //disconnected + printf ("client closed socket\n"); + sockfds[i]=-1; + continue; + } buffer[n]=0; - if (n < 0) error("ERROR reading from socket"); - if (n==0) error ("client closed socket, exiting"); + if (n==0) { + printf ("client closed socket\n"); + sockfds[i]=-1; + continue; + } - printf("Here is the message: %s\n",buffer); + printf("Here is the message: '%s'\n",buffer); + //update state if (buffer[0]=='t') { + n = myrecv(sockfds[i],buffer+1,4, 0); + if (n<0) { //disconnected + sockfds[i]=-1; + continue; + } int32_t time; memcpy(&time, buffer+1, sizeof(int32_t)); time=ntohl(time); state.timestep=time; + printf("Timestep: %d\n",time); } else if (buffer[0]=='i') { + n = myrecv(sockfds[i],buffer+1,4, 0); + if (n<0) { //disconnected + sockfds[i]=-1; + continue; + } int32_t iso; memcpy(&iso, buffer+1, sizeof(int32_t)); iso=ntohl(iso); - state.timestep=iso; + state.iso=iso; + printf("Iso: %d\n",iso); } else if (buffer[0]=='n') { + n = myrecv(sockfds[i],buffer+1,4, 0); + if (n<0) { //disconnected + sockfds[i]=-1; + continue; + } int32_t ncfg; memcpy(&ncfg, buffer+1, sizeof(int32_t)); ncfg=ntohl(ncfg); - state.timestep=ncfg; + state.ncfg=ncfg; + printf("ncfg: %d\n",ncfg); } else if (buffer[0]=='s') { + n = myrecv(sockfds[i],buffer+1,1, 0); + if (n<0) { //disconnected + sockfds[i]=-1; + continue; + } state.showatoms=buffer[1]!=0; + printf("showatoms: %d\n",state.showatoms); } else { - fprintf (stderr, "Unknown state request %c\n", buffer[0]); + fprintf (stderr, "Unknown state request '%c'\n", buffer[0]); error ("unknown state" ); } for (unsigned j=1;j<sockfds.size();j++) { - n = send(sockfds[j], buffer , n, 0); - if (n < 0) error("ERROR writing to socket"); + if (sockfds[j]>=0) { + if (buffer[0]=='s') + n=2; + else + n=5; + n = send(sockfds[j], buffer , n, 0); + if (n < 0) { + fprintf(stderr, "ERROR writing to socket, closing\n"); + sockfds[j]=-1; + } + } } } //unblockingly see if new connections were made and add to sockfds if (FD_ISSET (sockfds[0], &read_fd_set)) { - if (initNewSocket (secret)); + if (initNewSocket (secret)) { + printf ("Connected to new client\n"); FD_SET (sockfds.back(), &active_fd_set); + } } } #ifdef WIN32 -- GitLab