From d6c5c98e6dc4c80e7b8c300e2186f1fd70ff4e35 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Fri, 17 May 2019 21:55:00 +0200 Subject: [PATCH] Feature/time topic changes (#863) * Time topic updates * Update web gui and patch jsonconverters --- data/assets/util/webgui.asset | 2 +- modules/server/include/topics/timetopic.h | 7 +- modules/server/src/jsonconverters.cpp | 3 + modules/server/src/topics/timetopic.cpp | 99 ++++++++++++----------- 4 files changed, 60 insertions(+), 51 deletions(-) diff --git a/data/assets/util/webgui.asset b/data/assets/util/webgui.asset index d038e140bd..002c01aa80 100644 --- a/data/assets/util/webgui.asset +++ b/data/assets/util/webgui.asset @@ -1,7 +1,7 @@ local guiCustomization = asset.require('customization/gui') -- Select which commit hashes to use for the frontend and backend -local frontendHash = "6a34f2b0c6cfde64b890f12aa5bfaa42ac61a40f" +local frontendHash = "4fe87ea6b119de54a45e03543b8b95d5ea3808d5" local backendHash = "408142f26d3fa3d041399fcf58645874589d5b64" local dataProvider = "data.openspaceproject.com/files/webgui" diff --git a/modules/server/include/topics/timetopic.h b/modules/server/include/topics/timetopic.h index 7ace2db1fa..7fa7b36465 100644 --- a/modules/server/include/topics/timetopic.h +++ b/modules/server/include/topics/timetopic.h @@ -41,13 +41,16 @@ public: private: const int UnsetOnChangeHandle = -1; - nlohmann::json currentTime(); - nlohmann::json deltaTime(); + void sendCurrentTime(); + void sendFullTimeData(); int _timeCallbackHandle = UnsetOnChangeHandle; int _deltaTimeCallbackHandle = UnsetOnChangeHandle; bool _isDone = false; std::chrono::system_clock::time_point _lastUpdateTime; + + bool _lastPauseState = false; + double _lastTargetDeltaTime = 0.0; }; } // namespace openspace diff --git a/modules/server/src/jsonconverters.cpp b/modules/server/src/jsonconverters.cpp index f6ec35d94b..5f17620885 100644 --- a/modules/server/src/jsonconverters.cpp +++ b/modules/server/src/jsonconverters.cpp @@ -112,6 +112,9 @@ void to_json(json& j, const Dictionary& dictionary) { else if (dictionary.hasValue(key)) { object[key] = dictionary.value(key); } + else if (dictionary.hasValue(key)) { + object[key] = dictionary.value(key); + } else if (dictionary.hasValue(key)) { json child; to_json(child, dictionary.value(key)); diff --git a/modules/server/src/topics/timetopic.cpp b/modules/server/src/topics/timetopic.cpp index 17302c7bf6..71b1ae79cb 100644 --- a/modules/server/src/topics/timetopic.cpp +++ b/modules/server/src/topics/timetopic.cpp @@ -33,11 +33,9 @@ namespace { constexpr const char* _loggerCat = "TimeTopic"; - constexpr const char* PropertyKey = "property"; constexpr const char* EventKey = "event"; + constexpr const char* SubscribeEvent = "start_subscription"; constexpr const char* UnsubscribeEvent = "stop_subscription"; - constexpr const char* CurrentTimeKey = "currentTime"; - constexpr const char* DeltaTimeKey = "deltaTime"; constexpr const std::chrono::milliseconds TimeUpdateInterval(50); } // namespace @@ -47,9 +45,7 @@ namespace openspace { TimeTopic::TimeTopic() : _lastUpdateTime(std::chrono::system_clock::now()) -{ - LDEBUG("Starting new time subscription"); -} +{} TimeTopic::~TimeTopic() { if (_timeCallbackHandle != UnsetOnChangeHandle) { @@ -71,54 +67,61 @@ void TimeTopic::handleJson(const nlohmann::json& json) { return; } - std::string requestedKey = json.at(PropertyKey).get(); - LDEBUG("Subscribing to " + requestedKey); + sendFullTimeData(); - if (requestedKey == CurrentTimeKey) { - _timeCallbackHandle = global::timeManager.addTimeChangeCallback([this]() { - std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); - if (now - _lastUpdateTime > TimeUpdateInterval) { - _connection->sendJson(currentTime()); - _lastUpdateTime = now; - } - }); - _connection->sendJson(currentTime()); - } - else if (requestedKey == DeltaTimeKey) { - _deltaTimeCallbackHandle = global::timeManager.addDeltaTimeChangeCallback( - [this]() { - std::chrono::system_clock::time_point now = - std::chrono::system_clock::now(); - if (now - _lastUpdateTime > TimeUpdateInterval) { - _connection->sendJson(deltaTime()); - if (_timeCallbackHandle != UnsetOnChangeHandle) { - _connection->sendJson(currentTime()); - _lastUpdateTime = std::chrono::system_clock::now(); - } - _lastUpdateTime = now; - } - } - ); - _connection->sendJson(deltaTime()); - } - else { - LWARNING("Cannot get " + requestedKey); + if (event != SubscribeEvent) { _isDone = true; + return; } + + _timeCallbackHandle = global::timeManager.addTimeChangeCallback([this]() { + std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); + if (now - _lastUpdateTime > TimeUpdateInterval) { + sendCurrentTime(); + } + }); + + _deltaTimeCallbackHandle = global::timeManager.addDeltaTimeChangeCallback([this]() { + // Throttle by last update, + // but force update if pause state or target delta changes. + + std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); + const double targetDeltaTime = global::timeManager.targetDeltaTime(); + const bool isPaused = global::timeManager.isPaused(); + const bool forceUpdate = + isPaused != _lastPauseState || targetDeltaTime != _lastTargetDeltaTime; + + if (forceUpdate || now - _lastUpdateTime > TimeUpdateInterval) { + sendFullTimeData(); + } + }); } -json TimeTopic::currentTime() { - json timeJson = { { "time", global::timeManager.time().ISO8601() } }; - return wrappedPayload(timeJson); -} - -json TimeTopic::deltaTime() { - json timeJson = { - { "deltaTime", global::timeManager.deltaTime() }, - { "targetDeltaTime", global::timeManager.targetDeltaTime() }, - { "isPaused", global::timeManager.isPaused() }, +void TimeTopic::sendCurrentTime() { + const json timeJson = { + { "time", global::timeManager.time().ISO8601() } }; - return wrappedPayload(timeJson); + _connection->sendJson(wrappedPayload(timeJson)); + _lastUpdateTime = std::chrono::system_clock::now(); +} + +void TimeTopic::sendFullTimeData() { + const std::string currentTime = global::timeManager.time().ISO8601(); + const double deltaTime = global::timeManager.deltaTime(); + const double targetDeltaTime = global::timeManager.targetDeltaTime(); + const bool isPaused = global::timeManager.isPaused(); + + const json timeJson = { + { "time", currentTime }, + { "deltaTime", deltaTime}, + { "targetDeltaTime", targetDeltaTime}, + { "isPaused", isPaused }, + }; + + _connection->sendJson(wrappedPayload(timeJson)); + _lastUpdateTime = std::chrono::system_clock::now(); + _lastPauseState = isPaused; + _lastTargetDeltaTime = targetDeltaTime; } } // namespace openspace