/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2017 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ #ifndef __OPENSPACE_CORE___PARALLELCONNECTION___H__ #define __OPENSPACE_CORE___PARALLELCONNECTION___H__ //openspace includes #include //glm includes #include //ghoul includes #include //std includes #include #include #include #include #include #include #include #include #if defined(WIN32) || defined(__MING32__) || defined(__MING64__) typedef size_t _SOCKET; #else typedef int _SOCKET; #include #endif struct addrinfo; namespace openspace { class ParallelConnection { public: enum class Status : uint32_t { Disconnected = 0, ClientWithoutHost, ClientWithHost, Host }; enum class MessageType : uint32_t { Authentication = 0, Data, ConnectionStatus, HostshipRequest, HostshipResignation, NConnections }; struct Message { Message() {}; Message(MessageType t, const std::vector& c) : type(t) , content(c) {}; MessageType type; std::vector content; }; struct DataMessage { DataMessage() {}; DataMessage(datamessagestructures::Type t, const std::vector& c) : type(t) , content(c) {}; datamessagestructures::Type type; std::vector content; }; ParallelConnection(); ~ParallelConnection(); void clientConnect(); void setPort(const std::string &port); void setAddress(const std::string &address); void setName(const std::string& name); bool isHost(); const std::string& hostName(); void requestHostship(const std::string &password); void resignHostship(); void setPassword(const std::string &password); void signalDisconnect(); void preSynchronization(); void sendScript(const std::string& script); /** * Returns the Lua library that contains all Lua functions available to affect the * remote OS parallel connection. The functions contained are * - * \return The Lua library that contains all Lua functions available to affect the * interaction */ static scripting::LuaLibrary luaLibrary(); Status status(); size_t nConnections(); std::shared_ptr> connectionEvent(); private: //@TODO change this into the ghoul hasher for client AND server uint32_t hash(const std::string &val); void queueOutMessage(const Message& message); void queueOutDataMessage(const DataMessage& dataMessage); void queueInMessage(const Message& message); void disconnect(); void closeSocket(); bool initNetworkAPI(); void establishConnection(addrinfo *info); void sendAuthentication(); void listenCommunication(); int receiveData(_SOCKET & socket, std::vector &buffer, int length, int flags); void handleMessage(const Message&); void dataMessageReceived(const std::vector& messageContent); void connectionStatusMessageReceived(const std::vector& messageContent); void nConnectionsMessageReceived(const std::vector& messageContent); void broadcast(); void sendCameraKeyframe(); void sendTimeKeyframe(); void sendFunc(); void threadManagement(); void setStatus(Status status); void setHostName(const std::string& hostName); void setNConnections(size_t nConnections); double calculateBufferedKeyframeTime(double originalTime); uint32_t _passCode; std::string _port; std::string _address; std::string _name; _SOCKET _clientSocket; std::atomic _isConnected; std::atomic _isRunning; std::atomic _tryConnect; std::atomic _disconnect; std::atomic _initializationTimejumpRequired; std::atomic _nConnections; std::atomic _status; std::string _hostName; std::condition_variable _disconnectCondition; std::mutex _disconnectMutex; std::condition_variable _sendCondition; std::deque _sendBuffer; std::mutex _sendBufferMutex; std::deque _receiveBuffer; std::mutex _receiveBufferMutex; std::atomic _timeJumped; std::mutex _latencyMutex; std::deque _latencyDiffs; double _initialTimeDiff; std::unique_ptr _connectionThread; std::unique_ptr _broadcastThread; std::unique_ptr _sendThread; std::unique_ptr _listenThread; std::unique_ptr _handlerThread; std::shared_ptr> _connectionEvent; }; } // namespace openspace #endif // __OPENSPACE_CORE___PARALLELCONNECTION___H__