diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index e6ce8570a7..2beeafa486 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -40,6 +40,7 @@ namespace openspace { class ConfigurationManager; class LuaConsole; +class NetworkEngine; class GUI; class RenderEngine; class SyncBuffer; @@ -111,6 +112,7 @@ private: interaction::InteractionHandler* _interactionHandler; RenderEngine* _renderEngine; scripting::ScriptEngine* _scriptEngine; + NetworkEngine* _networkEngine; ghoul::cmdparser::CommandlineParser* _commandlineParser; LuaConsole* _console; gui::GUI* _gui; diff --git a/include/openspace/network/networkengine.h b/include/openspace/network/networkengine.h new file mode 100644 index 0000000000..1d0c03481a --- /dev/null +++ b/include/openspace/network/networkengine.h @@ -0,0 +1,43 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __NETWORKENGINE_H__ +#define __NETWORKENGINE_H__ + +#include + +namespace openspace { + +class NetworkEngine { +public: + NetworkEngine() = default; + + bool handleMessage(const std::string& message); + + void sendStatusMessage(); +}; + +} // namespace openspace + +#endif // __NETWORKENGINE_H__ \ No newline at end of file diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index b02763709d..1814dee2db 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -51,7 +51,7 @@ namespace openspace { * equal to the frame time. */ - class SyncBuffer; +class SyncBuffer; class Time { public: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6976e276c2..5bfeb38af5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,6 +48,12 @@ file(GLOB ENGINE_HEADER ${HEADER_ROOT_DIR}/openspace/engine/*.h) set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${ENGINE_HEADER}) source_group(Engine FILES ${ENGINE_SOURCE} ${ENGINE_HEADER}) +file(GLOB NETWORK_SOURCE ${SOURCE_ROOT_DIR}/network/*.cpp) +set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${NETWORK_SOURCE}) +file(GLOB NETWORK_HEADER ${HEADER_ROOT_DIR}/openspace/network/*.h) +set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${NETWORK_HEADER}) +source_group(Network FILES ${NETWORK_SOURCE} ${NETWORK_HEADER}) + file(GLOB GUI_SOURCE ${SOURCE_ROOT_DIR}/gui/*.cpp) set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${GUI_SOURCE}) file(GLOB GUI_HEADER ${HEADER_ROOT_DIR}/openspace/gui/*.h) diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 132b43e705..4e169dc328 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) , _interactionHandler(new interaction::InteractionHandler) , _renderEngine(new RenderEngine) , _scriptEngine(new scripting::ScriptEngine) + , _networkEngine(new NetworkEngine) , _commandlineParser(new ghoul::cmdparser::CommandlineParser(programName, true)) , _console(new LuaConsole) , _gui(new gui::GUI) @@ -115,6 +117,7 @@ OpenSpaceEngine::~OpenSpaceEngine() { delete _interactionHandler; delete _renderEngine; delete _scriptEngine; + delete _networkEngine; delete _commandlineParser; delete _console; delete _gui; @@ -700,6 +703,7 @@ void OpenSpaceEngine::encode() { _syncBuffer->write(); } + _networkEngine->sendStatusMessage(); } void OpenSpaceEngine::decode() { @@ -709,7 +713,6 @@ void OpenSpaceEngine::decode() { Time::ref().deserialize(_syncBuffer); _scriptEngine->deserialize(_syncBuffer); _renderEngine->deserialize(_syncBuffer); - } } @@ -719,17 +722,7 @@ void OpenSpaceEngine::externalControlCallback(const char* receivedChars, if (size == 0) return; - // The first byte determines the type of message - const char type = receivedChars[0]; - switch (type) { - case '0': // LuaScript - { - std::string script = std::string(receivedChars + 1); - LINFO("Received Lua Script: '" << script << "'"); - //_scriptEngine->runScript(script); - _scriptEngine->queueScript(script); - } - } + _networkEngine->handleMessage(std::string(receivedChars)); } void OpenSpaceEngine::enableBarrier() { diff --git a/src/network/networkengine.cpp b/src/network/networkengine.cpp new file mode 100644 index 0000000000..1b0c0a2599 --- /dev/null +++ b/src/network/networkengine.cpp @@ -0,0 +1,97 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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. * + ****************************************************************************************/ + +#include + +#include +#include + +#include "sgct.h" + +namespace { + const std::string _loggerCat = "NetworkEngine"; + + const uint8_t MessageTypeStatus = 0; +} + +namespace openspace { + +bool NetworkEngine::handleMessage(const std::string& message) { + // The first byte determines the type of message + const char type = message[0]; + switch (type) { + case '0': // LuaScript + { + std::string script = message.substr(1); + //LINFO("Received Lua Script: '" << script << "'"); + OsEng.scriptEngine()->queueScript(script); + return true; + } + default: + LERROR("Unknown type '" << type << "'"); + return false; + } + +} + +void NetworkEngine::sendStatusMessage() { + if (!sgct::Engine::instance()->isExternalControlConnected()) + return; + // Protocols: + // 1 byte: type of message + // 8 bytes: time as a ET double + // 24 bytes: time as a UTC string + // 8 bytes: delta time as double + // Total: 41 + + uint16_t messageSize = 0; + + double time = Time::ref().currentTime(); + std::string timeString = Time::ref().currentTimeUTC(); + double delta = Time::ref().deltaTime(); + + messageSize += sizeof(uint8_t); + messageSize += sizeof(time); + messageSize += timeString.length(); + messageSize += sizeof(delta); + + //LINFO(delta); + + ghoul_assert(messageSize == 41, "Message size is not correct"); + + unsigned int currentLocation = 0; + std::vector buffer(messageSize); + + std::memcpy(buffer.data(), &MessageTypeStatus, sizeof(MessageTypeStatus)); + currentLocation += sizeof(MessageTypeStatus); + std::memmove(buffer.data() + currentLocation, &time, sizeof(time)); + currentLocation += sizeof(time); + std::memmove(buffer.data() + currentLocation, timeString.c_str(), timeString.length()); + currentLocation += timeString.length(); + std::memmove(buffer.data() + currentLocation, &delta, sizeof(delta)); + + sgct::Engine::instance()->sendMessageToExternalControl(buffer.data(), messageSize); +} + +} // namespace openspace