From 91247d4ac9d784fb1cecf8d382d1a1ff21169b08 Mon Sep 17 00:00:00 2001 From: Joakim Kilby Date: Wed, 17 Jun 2015 08:39:34 +0200 Subject: [PATCH] added keyframe struct and functionality to broadcast keyframes --- .../openspace/network/osparallelconnection.h | 65 +++++++++- src/network/osparallelconnection.cpp | 115 +++++++++++++++--- 2 files changed, 165 insertions(+), 15 deletions(-) diff --git a/include/openspace/network/osparallelconnection.h b/include/openspace/network/osparallelconnection.h index d6a8b101b5..8169e03c2e 100644 --- a/include/openspace/network/osparallelconnection.h +++ b/include/openspace/network/osparallelconnection.h @@ -29,12 +29,15 @@ #include #include #include +#include +#include //std includes #include #include #include #include +#include #ifdef __WIN32__ #ifndef WIN32_LEAN_AND_MEAN @@ -56,6 +59,63 @@ namespace openspace{ namespace network{ + struct Keyframe{ + glm::quat _viewRotationQuat; + psc _position; + double _timeStamp; + + std::string to_string(){ + std::stringstream ss; + //position + ss << _position.dvec4().x; + ss << "\t"; + ss << _position.dvec4().y; + ss << "\t"; + ss << _position.dvec4().z; + ss << "\t"; + ss << _position.dvec4().w; + ss << "\t"; + + ss << "\n"; + //orientation + ss << _viewRotationQuat.x; + ss << "\t"; + ss << _viewRotationQuat.y; + ss << "\t"; + ss << _viewRotationQuat.z; + ss << "\t"; + ss << _viewRotationQuat.w; + + ss << "\n"; + //timestamp + ss << _timeStamp; + + return ss.str(); + } + + void from_string(std::string &val){ + std::stringstream ss(val); + double x, y, z, w; + + //position + ss >> x; + ss >> y; + ss >> z; + ss >> w; + _position = psc(x, y, z, w); + + //orientation + ss >> x; + ss >> y; + ss >> z; + ss >> w; + _viewRotationQuat = glm::quat(x, y, z, w); + + //timestamp + ss >> _timeStamp; + } + }; + class OSParallelConnection : public properties::PropertyOwner { public: @@ -153,6 +213,8 @@ namespace openspace{ void decodeInitializationRequestMessage(); + void broadcast(); + int receiveData(_SOCKET & socket, std::vector &buffer, int length, int flags); uint32_t _passCode; @@ -160,7 +222,8 @@ namespace openspace{ std::string _address; std::string _name; _SOCKET _clientSocket; - std::thread *_thread; + std::thread *_connectionThread; + std::thread *_broadcastThread; std::atomic _isRunning; std::atomic _isHost; }; diff --git a/src/network/osparallelconnection.cpp b/src/network/osparallelconnection.cpp index 6370581967..a53bfd83ac 100644 --- a/src/network/osparallelconnection.cpp +++ b/src/network/osparallelconnection.cpp @@ -60,7 +60,7 @@ const int headerSize = 8; #include #include #include -#include +#include #include "osparallelconnection_lua.inl" @@ -75,9 +75,10 @@ namespace openspace { _passCode(0), _port("20501"), _address("127.0.0.1"), - _name("No name"), + _name("Local Connection"), _clientSocket(INVALID_SOCKET), - _thread(nullptr), + _connectionThread(nullptr), + _broadcastThread(nullptr), _isRunning(false), _isHost(false) { @@ -130,7 +131,7 @@ namespace openspace { //start accept connections thread _isRunning.store(true); - _thread = new (std::nothrow) std::thread(&OSParallelConnection::connection, this, addresult); + _connectionThread = new (std::nothrow) std::thread(&OSParallelConnection::connection, this, addresult); } @@ -262,6 +263,27 @@ namespace openspace { void OSParallelConnection::decodeDataMessage(){ printf("Data message received!\n"); + int result; + uint16_t msglen; + std::vector buffer; + buffer.reserve(sizeof(msglen)); + result = receiveData(_clientSocket, buffer, sizeof(msglen), 0); + + if (result <= 0){ + //error + return; + } + + msglen = (*(reinterpret_cast(buffer.data()))); + + buffer.clear(); + buffer.reserve(msglen); + + result = receiveData(_clientSocket, buffer, msglen, 0); + if (result <= 0){ + //error + return; + } } void OSParallelConnection::decodeHostInfoMessage(){ @@ -271,14 +293,30 @@ namespace openspace { if (result > 0){ if (hostflag.at(0) == 1){ - printf("IM MASTER!\n"); - _isHost.store(true); + //we're already host, do nothing (dummy check) + if (_isHost.load()){ + return; + } + else{ + //start broadcasting + _isHost.store(true); + _broadcastThread = new (std::nothrow) std::thread(&OSParallelConnection::broadcast, this); + } } else{ - printf("IM A SLAVE!\n"); - _isHost.store(false); + //we were broadcasting but should stop now + if (_isHost.load()){ + _isHost.store(false); + if (_broadcastThread != nullptr){ + _broadcastThread->join(); + delete _broadcastThread; + _broadcastThread = nullptr; + } + } + else{ + //we were not host so nothing to do + } } - } else{ std::cerr << "Error " << _ERRNO << " detected in connection!" << std::endl; @@ -398,13 +436,23 @@ namespace openspace { } void OSParallelConnection::disconnect(){ - closeSocket(); + _isHost.store(false); - if (_thread != nullptr){ - _thread->join(); - delete _thread; - _thread = nullptr; + if (_broadcastThread != nullptr){ + _broadcastThread->join(); + delete _broadcastThread; + _broadcastThread = nullptr; } + + _isRunning.store(false); + + if (_connectionThread != nullptr){ + _connectionThread->join(); + delete _connectionThread; + _connectionThread = nullptr; + } + + closeSocket(); } void OSParallelConnection::closeSocket(){ @@ -459,6 +507,45 @@ namespace openspace { return true; } + void OSParallelConnection::broadcast(){ + + while (_isHost.load()){ + + network::Keyframe kf; + kf._position = OsEng.interactionHandler()->camera()->position(); + kf._viewRotationQuat = glm::quat_cast(OsEng.interactionHandler()->camera()->viewRotationMatrix()); + kf._timeStamp = Time::ref().currentTime(); + + std::string msg = kf.to_string(); + + uint16_t msglen = static_cast(msg.length()); + std::vector buffer; + buffer.reserve(headerSize + sizeof(msglen) + msglen); + + //header + buffer.insert(buffer.end(), 'O'); + buffer.insert(buffer.end(), 'S'); + buffer.insert(buffer.end(), 0); + buffer.insert(buffer.end(), 0); + + //type of message + int type = OSParallelConnection::MessageTypes::Data; + buffer.insert(buffer.end(), reinterpret_cast(&type), reinterpret_cast(&type) + sizeof(type)); + + //size of message + buffer.insert(buffer.end(), reinterpret_cast(&msglen), reinterpret_cast(&msglen) + sizeof(msglen)); + + //actual message + buffer.insert(buffer.end(), msg.begin(), msg.end()); + + //send message + send(_clientSocket, buffer.data(), buffer.size(), 0); + + //100 ms sleep + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + scripting::ScriptEngine::LuaLibrary OSParallelConnection::luaLibrary() { return { "parallel",