mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-06 03:29:44 -06:00
Merge remote-tracking branch 'origin/master' into feature/missions
# Conflicts: # data/assets/scene/solarsystem/missions/newhorizons/newhorizons.asset # data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset # data/assets/scene/solarsystem/missions/osirisrex/osirisrex.mission # data/assets/scene/solarsystem/missions/perseverance/perseverance.asset # include/openspace/mission/missionmanager.h # modules/server/src/connection.cpp # src/mission/missionmanager.cpp # src/mission/missionmanager_lua.inl
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -26,7 +26,9 @@
|
||||
|
||||
#include <modules/server/include/topics/authorizationtopic.h>
|
||||
#include <modules/server/include/topics/bouncetopic.h>
|
||||
#include <modules/server/include/topics/cameratopic.h>
|
||||
#include <modules/server/include/topics/documentationtopic.h>
|
||||
#include <modules/server/include/topics/enginemodetopic.h>
|
||||
#include <modules/server/include/topics/flightcontrollertopic.h>
|
||||
#include <modules/server/include/topics/getpropertytopic.h>
|
||||
#include <modules/server/include/topics/luascripttopic.h>
|
||||
@@ -34,6 +36,7 @@
|
||||
#include <modules/server/include/topics/sessionrecordingtopic.h>
|
||||
#include <modules/server/include/topics/setpropertytopic.h>
|
||||
#include <modules/server/include/topics/shortcuttopic.h>
|
||||
#include <modules/server/include/topics/skybrowsertopic.h>
|
||||
#include <modules/server/include/topics/subscriptiontopic.h>
|
||||
#include <modules/server/include/topics/timetopic.h>
|
||||
#include <modules/server/include/topics/topic.h>
|
||||
@@ -49,34 +52,18 @@
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "ServerModule: Connection";
|
||||
constexpr std::string_view _loggerCat = "ServerModule: Connection";
|
||||
|
||||
constexpr const char* MessageKeyType = "type";
|
||||
constexpr const char* MessageKeyPayload = "payload";
|
||||
constexpr const char* MessageKeyTopic = "topic";
|
||||
constexpr std::string_view MessageKeyType = "type";
|
||||
constexpr std::string_view MessageKeyPayload = "payload";
|
||||
constexpr std::string_view MessageKeyTopic = "topic";
|
||||
|
||||
constexpr const char* AuthenticationTopicKey = "authorize";
|
||||
constexpr const char* BounceTopicKey = "bounce";
|
||||
constexpr const char* DocumentationTopicKey = "documentation";
|
||||
constexpr const char* FlightControllerTopicKey = "flightcontroller";
|
||||
constexpr const char* GetPropertyTopicKey = "get";
|
||||
constexpr const char* LuaScriptTopicKey = "luascript";
|
||||
constexpr const char* MissionTopicKey = "missions";
|
||||
constexpr const char* SessionRecordingTopicKey = "sessionRecording";
|
||||
constexpr const char* SetPropertyTopicKey = "set";
|
||||
constexpr const char* ShortcutTopicKey = "shortcuts";
|
||||
constexpr const char* SubscriptionTopicKey = "subscribe";
|
||||
constexpr const char* TimeTopicKey = "time";
|
||||
constexpr const char* TriggerPropertyTopicKey = "trigger";
|
||||
constexpr const char* VersionTopicKey = "version";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
Connection::Connection(std::unique_ptr<ghoul::io::Socket> s,
|
||||
std::string address,
|
||||
bool authorized,
|
||||
const std::string& password)
|
||||
Connection::Connection(std::unique_ptr<ghoul::io::Socket> s, std::string address,
|
||||
bool authorized, const std::string& password)
|
||||
: _socket(std::move(s))
|
||||
, _address(std::move(address))
|
||||
, _isAuthorized(authorized)
|
||||
@@ -84,7 +71,7 @@ Connection::Connection(std::unique_ptr<ghoul::io::Socket> s,
|
||||
ghoul_assert(_socket, "Socket must not be nullptr");
|
||||
|
||||
_topicFactory.registerClass(
|
||||
AuthenticationTopicKey,
|
||||
"authorize",
|
||||
[password](bool, const ghoul::Dictionary&, ghoul::MemoryPoolBase* pool) {
|
||||
if (pool) {
|
||||
void* ptr = pool->allocate(sizeof(AuthorizationTopic));
|
||||
@@ -96,41 +83,46 @@ Connection::Connection(std::unique_ptr<ghoul::io::Socket> s,
|
||||
}
|
||||
);
|
||||
|
||||
_topicFactory.registerClass<DocumentationTopic>(DocumentationTopicKey);
|
||||
_topicFactory.registerClass<GetPropertyTopic>(GetPropertyTopicKey);
|
||||
_topicFactory.registerClass<LuaScriptTopic>(LuaScriptTopicKey);
|
||||
_topicFactory.registerClass<MissionTopic>(MissionTopicKey);
|
||||
_topicFactory.registerClass<SessionRecordingTopic>(SessionRecordingTopicKey);
|
||||
_topicFactory.registerClass<SetPropertyTopic>(SetPropertyTopicKey);
|
||||
_topicFactory.registerClass<ShortcutTopic>(ShortcutTopicKey);
|
||||
_topicFactory.registerClass<SubscriptionTopic>(SubscriptionTopicKey);
|
||||
_topicFactory.registerClass<TimeTopic>(TimeTopicKey);
|
||||
_topicFactory.registerClass<TriggerPropertyTopic>(TriggerPropertyTopicKey);
|
||||
_topicFactory.registerClass<BounceTopic>(BounceTopicKey);
|
||||
_topicFactory.registerClass<FlightControllerTopic>(FlightControllerTopicKey);
|
||||
_topicFactory.registerClass<VersionTopic>(VersionTopicKey);
|
||||
_topicFactory.registerClass<MissionTopic>("missions");
|
||||
_topicFactory.registerClass<DocumentationTopic>("documentation");
|
||||
_topicFactory.registerClass<GetPropertyTopic>("get");
|
||||
_topicFactory.registerClass<LuaScriptTopic>("luascript");
|
||||
_topicFactory.registerClass<EngineModeTopic>("engineMode");
|
||||
_topicFactory.registerClass<SessionRecordingTopic>("sessionRecording");
|
||||
_topicFactory.registerClass<SetPropertyTopic>("set");
|
||||
_topicFactory.registerClass<ShortcutTopic>("shortcuts");
|
||||
_topicFactory.registerClass<SubscriptionTopic>("subscribe");
|
||||
_topicFactory.registerClass<TimeTopic>("time");
|
||||
_topicFactory.registerClass<TriggerPropertyTopic>("trigger");
|
||||
_topicFactory.registerClass<BounceTopic>("bounce");
|
||||
_topicFactory.registerClass<FlightControllerTopic>("flightcontroller");
|
||||
_topicFactory.registerClass<VersionTopic>("version");
|
||||
_topicFactory.registerClass<SkyBrowserTopic>("skybrowser");
|
||||
_topicFactory.registerClass<CameraTopic>("camera");
|
||||
}
|
||||
|
||||
void Connection::handleMessage(const std::string& message) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
try {
|
||||
nlohmann::json j = nlohmann::json::parse(message.c_str());
|
||||
try {
|
||||
handleJson(j);
|
||||
} catch (const std::domain_error& e) {
|
||||
}
|
||||
catch (const std::domain_error& e) {
|
||||
LERROR(fmt::format("JSON handling error from: {}. {}", message, e.what()));
|
||||
}
|
||||
} catch (const std::out_of_range& e) {
|
||||
LERROR(fmt::format("JSON handling error from: {}. {}", message, e.what()));
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
LERROR(e.what());
|
||||
}
|
||||
catch (const std::out_of_range& e) {
|
||||
LERROR(fmt::format("JSON handling error from: {}. {}", message, e.what()));
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
LERROR(e.what());
|
||||
} catch (...) {
|
||||
if (!isAuthorized()) {
|
||||
_socket->disconnect();
|
||||
LERROR(fmt::format(
|
||||
"Could not parse JSON: '{}'. Connection is unauthorized. Disconnecting.",
|
||||
"Could not parse JSON: '{}'. Connection is unauthorized. Disconnecting",
|
||||
message
|
||||
));
|
||||
return;
|
||||
@@ -151,7 +143,7 @@ void Connection::handleMessage(const std::string& message) {
|
||||
}
|
||||
|
||||
void Connection::handleJson(const nlohmann::json& json) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
auto topicJson = json.find(MessageKeyTopic);
|
||||
auto payloadJson = json.find(MessageKeyPayload);
|
||||
@@ -174,21 +166,18 @@ void Connection::handleJson(const nlohmann::json& json) {
|
||||
// The topic id is not registered: Initialize a new topic.
|
||||
auto typeJson = json.find(MessageKeyType);
|
||||
if (typeJson == json.end() || !typeJson->is_string()) {
|
||||
LERROR(fmt::format(
|
||||
"A type must be specified (`{}`) as a string when "
|
||||
"a new topic is initialized", MessageKeyType
|
||||
));
|
||||
LERROR("Type must be specified as a string when a new topic is initialized");
|
||||
return;
|
||||
}
|
||||
std::string type = *typeJson;
|
||||
|
||||
if (!isAuthorized() && type != AuthenticationTopicKey) {
|
||||
LERROR("Connection isn't authorized.");
|
||||
if (!isAuthorized() && type != "authorize") {
|
||||
LERROR("Connection is not authorized");
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<Topic> topic = std::unique_ptr<Topic>(_topicFactory.create(type));
|
||||
topic->initialize(this, topicId);
|
||||
topic->initialize(shared_from_this(), topicId);
|
||||
topic->handleJson(*payloadJson);
|
||||
if (!topic->isDone()) {
|
||||
_topics.emplace(topicId, std::move(topic));
|
||||
@@ -196,11 +185,11 @@ void Connection::handleJson(const nlohmann::json& json) {
|
||||
}
|
||||
else {
|
||||
if (!isAuthorized()) {
|
||||
LERROR("Connection isn't authorized.");
|
||||
LERROR("Connection is not authorized");
|
||||
return;
|
||||
}
|
||||
|
||||
// Dispatch the message to the existing topic.
|
||||
// Dispatch the message to the existing topic
|
||||
Topic& topic = *topicIt->second;
|
||||
topic.handleJson(*payloadJson);
|
||||
if (topic.isDone()) {
|
||||
@@ -210,13 +199,13 @@ void Connection::handleJson(const nlohmann::json& json) {
|
||||
}
|
||||
|
||||
void Connection::sendMessage(const std::string& message) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_socket->putMessage(message);
|
||||
}
|
||||
|
||||
void Connection::sendJson(const nlohmann::json& json) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
sendMessage(json.dump());
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -34,7 +34,7 @@ using json = nlohmann::json;
|
||||
namespace openspace::properties {
|
||||
|
||||
void to_json(json& j, const Property& p) {
|
||||
std::string description = p.generateBaseJsonDescription();
|
||||
std::string description = p.generateJsonDescription();
|
||||
json desc = json::parse(description);
|
||||
|
||||
std::string value = p.jsonValue();
|
||||
@@ -130,11 +130,6 @@ void to_json(json& j, const SceneGraphNode& n) {
|
||||
|
||||
{ "subowners", n.propertySubOwners() }
|
||||
};
|
||||
/*
|
||||
auto renderable = n.renderable();
|
||||
if (renderable != nullptr) {
|
||||
j["renderable"] = renderable;
|
||||
}*/
|
||||
|
||||
SceneGraphNode* parent = n.parent();
|
||||
if (parent) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -30,18 +30,17 @@
|
||||
#include <functional>
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr const char* KeyIdentifier = "Identifier";
|
||||
constexpr const char* TcpSocketType = "TcpSocket";
|
||||
constexpr const char* WebSocketType = "WebSocket";
|
||||
constexpr const char* DenyAccess = "Deny";
|
||||
constexpr const char* RequirePassword = "RequirePassword";
|
||||
constexpr const char* AllowAccess = "Allow";
|
||||
constexpr std::string_view KeyIdentifier = "Identifier";
|
||||
constexpr std::string_view TcpSocketType = "TcpSocket";
|
||||
constexpr std::string_view WebSocketType = "WebSocket";
|
||||
constexpr std::string_view DenyAccess = "Deny";
|
||||
constexpr std::string_view RequirePassword = "RequirePassword";
|
||||
constexpr std::string_view AllowAccess = "Allow";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo EnabledInfo = {
|
||||
"Enabled",
|
||||
"Is Enabled",
|
||||
"This setting determines whether this server interface is enabled or not."
|
||||
"This setting determines whether this server interface is enabled or not"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo TypeInfo = {
|
||||
@@ -65,20 +64,20 @@ namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo AllowAddressesInfo = {
|
||||
"AllowAddresses",
|
||||
"Allow Addresses",
|
||||
"Ip addresses or domains that should always be allowed access to this interface"
|
||||
"IP addresses or domains that should always be allowed access to this interface"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
RequirePasswordAddressesInfo = {
|
||||
"RequirePasswordAddresses",
|
||||
"Require Password Addresses",
|
||||
"Ip addresses or domains that should be allowed access if they provide a password"
|
||||
"IP addresses or domains that should be allowed access if they provide a password"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DenyAddressesInfo = {
|
||||
"DenyAddresses",
|
||||
"Deny Addresses",
|
||||
"Ip addresses or domains that should never be allowed access to this interface"
|
||||
"IP addresses or domains that should never be allowed access to this interface"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo PasswordInfo = {
|
||||
@@ -86,7 +85,7 @@ namespace {
|
||||
"Password",
|
||||
"Password for connecting to this interface"
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -94,7 +93,7 @@ std::unique_ptr<ServerInterface> ServerInterface::createFromDictionary(
|
||||
const ghoul::Dictionary& config)
|
||||
{
|
||||
// TODO: Use documentation to verify dictionary
|
||||
std::unique_ptr<ServerInterface> si = std::make_unique<ServerInterface>(config);
|
||||
auto si = std::make_unique<ServerInterface>(config);
|
||||
return si;
|
||||
}
|
||||
|
||||
@@ -110,12 +109,27 @@ ServerInterface::ServerInterface(const ghoul::Dictionary& config)
|
||||
, _password(PasswordInfo)
|
||||
{
|
||||
|
||||
_type.addOption(static_cast<int>(InterfaceType::TcpSocket), TcpSocketType);
|
||||
_type.addOption(static_cast<int>(InterfaceType::WebSocket), WebSocketType);
|
||||
_type.addOption(
|
||||
static_cast<int>(InterfaceType::TcpSocket),
|
||||
std::string(TcpSocketType)
|
||||
);
|
||||
_type.addOption(
|
||||
static_cast<int>(InterfaceType::WebSocket),
|
||||
std::string(WebSocketType)
|
||||
);
|
||||
|
||||
_defaultAccess.addOption(static_cast<int>(Access::Deny), DenyAccess);
|
||||
_defaultAccess.addOption(static_cast<int>(Access::RequirePassword), RequirePassword);
|
||||
_defaultAccess.addOption(static_cast<int>(Access::Allow), AllowAccess);
|
||||
_defaultAccess.addOption(
|
||||
static_cast<int>(Access::Deny),
|
||||
std::string(DenyAccess)
|
||||
);
|
||||
_defaultAccess.addOption(
|
||||
static_cast<int>(Access::RequirePassword),
|
||||
std::string(RequirePassword)
|
||||
);
|
||||
_defaultAccess.addOption(
|
||||
static_cast<int>(Access::Allow),
|
||||
std::string(AllowAccess)
|
||||
);
|
||||
|
||||
if (config.hasKey(DefaultAccessInfo.identifier)) {
|
||||
std::string access = config.value<std::string>(DefaultAccessInfo.identifier);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -30,12 +30,12 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "AuthorizationTopic";
|
||||
constexpr std::string_view _loggerCat = "AuthorizationTopic";
|
||||
|
||||
constexpr const char* KeyStatus = "status";
|
||||
constexpr const char* Authorized = "authorized";
|
||||
constexpr const char* IncorrectKey = "incorrectKey";
|
||||
constexpr const char* BadRequest = "badRequest";
|
||||
constexpr std::string_view KeyStatus = "status";
|
||||
constexpr std::string_view Authorized = "authorized";
|
||||
constexpr std::string_view IncorrectKey = "incorrectKey";
|
||||
constexpr std::string_view BadRequest = "badRequest";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
@@ -54,18 +54,20 @@ void AuthorizationTopic::handleJson(const nlohmann::json& json) {
|
||||
}
|
||||
else {
|
||||
try {
|
||||
auto providedKey = json.at("key").get<std::string>();
|
||||
std::string providedKey = json.at("key").get<std::string>();
|
||||
if (authorize(providedKey)) {
|
||||
_connection->setAuthorized(true);
|
||||
_connection->sendJson(wrappedPayload({ KeyStatus, Authorized }));
|
||||
LINFO("Client successfully authorized.");
|
||||
LINFO("Client successfully authorized");
|
||||
}
|
||||
else {
|
||||
_connection->sendJson(wrappedPayload({ KeyStatus, IncorrectKey }));
|
||||
}
|
||||
} catch (const std::out_of_range&) {
|
||||
}
|
||||
catch (const std::out_of_range&) {
|
||||
_connection->sendJson(wrappedPayload({ KeyStatus, BadRequest }));
|
||||
} catch (const std::domain_error&) {
|
||||
}
|
||||
catch (const std::domain_error&) {
|
||||
_connection->sendJson(wrappedPayload({ KeyStatus, BadRequest }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
|
||||
100
modules/server/src/topics/cameratopic.cpp
Normal file
100
modules/server/src/topics/cameratopic.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 "modules/server/include/topics/cameratopic.h"
|
||||
|
||||
#include <modules/server/include/connection.h>
|
||||
#include <modules/server/servermodule.h>
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/dashboarditemglobelocation.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/properties/property.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/util/distanceconversion.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr std::string_view SubscribeEvent = "start_subscription";
|
||||
} // namespace
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
namespace openspace {
|
||||
|
||||
CameraTopic::CameraTopic()
|
||||
: _lastUpdateTime(std::chrono::system_clock::now())
|
||||
{}
|
||||
|
||||
CameraTopic::~CameraTopic() {
|
||||
if (_dataCallbackHandle != UnsetOnChangeHandle) {
|
||||
ServerModule* module = global::moduleEngine->module<ServerModule>();
|
||||
if (module) {
|
||||
module->removePreSyncCallback(_dataCallbackHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CameraTopic::isDone() const {
|
||||
return _isDone;
|
||||
}
|
||||
|
||||
void CameraTopic::handleJson(const nlohmann::json& json) {
|
||||
std::string event = json.at("event").get<std::string>();
|
||||
|
||||
if (event != SubscribeEvent) {
|
||||
_isDone = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ServerModule* module = global::moduleEngine->module<ServerModule>();
|
||||
_dataCallbackHandle = module->addPreSyncCallback(
|
||||
[this]() {
|
||||
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
|
||||
if (now - _lastUpdateTime > _cameraPositionUpdateTime) {
|
||||
sendCameraData();
|
||||
_lastUpdateTime = std::chrono::system_clock::now();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void CameraTopic::sendCameraData() {
|
||||
using namespace openspace;
|
||||
|
||||
GlobeBrowsingModule* module = global::moduleEngine->module<GlobeBrowsingModule>();
|
||||
glm::dvec3 position = module->geoPosition();
|
||||
std::pair<double, std::string_view> altSimplified = simplifyDistance(position.z);
|
||||
|
||||
nlohmann::json jsonData = {
|
||||
{ "latitude", position.x },
|
||||
{ "longitude", position.y },
|
||||
{ "altitude", altSimplified.first },
|
||||
{ "altitudeUnit", altSimplified.second }
|
||||
};
|
||||
|
||||
_connection->sendJson(wrappedPayload(jsonData));
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -34,41 +34,31 @@
|
||||
#include <openspace/scene/scenelicensewriter.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyType = "type";
|
||||
constexpr const char* TypeLua = "lua";
|
||||
constexpr const char* TypeFactories = "factories";
|
||||
constexpr const char* TypeKeyboard = "keyboard";
|
||||
constexpr const char* TypeAsset = "asset";
|
||||
constexpr const char* TypeMeta= "meta";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
void DocumentationTopic::handleJson(const nlohmann::json& json) {
|
||||
std::string requestedType = json.at(KeyType).get<std::string>();
|
||||
std::string requestedType = json.at("type").get<std::string>();
|
||||
|
||||
nlohmann::json response;
|
||||
|
||||
// @emiax: Proposed future refector.
|
||||
// Do not parse generated json. Instead implement ability to get
|
||||
// ghoul::Dictionary objects from ScriptEngine, FactoryManager, and KeybindingManager.
|
||||
if (requestedType == TypeLua) {
|
||||
if (requestedType == "lua") {
|
||||
response = json::parse(global::scriptEngine->generateJson());
|
||||
}
|
||||
else if (requestedType == TypeFactories) {
|
||||
else if (requestedType == "factories") {
|
||||
response = json::parse(FactoryManager::ref().generateJson());
|
||||
}
|
||||
else if (requestedType == TypeKeyboard) {
|
||||
else if (requestedType == "keyboard") {
|
||||
response = json::parse(global::keybindingManager->generateJson());
|
||||
}
|
||||
else if (requestedType == TypeAsset) {
|
||||
else if (requestedType == "asset") {
|
||||
response = json::parse(global::keybindingManager->generateJson());
|
||||
}
|
||||
else if (requestedType == TypeMeta) {
|
||||
else if (requestedType == "meta") {
|
||||
std::string docs = SceneLicenseWriter().generateJson();
|
||||
nlohmann::json parsedDocs = json::parse(docs);
|
||||
response = parsedDocs;
|
||||
|
||||
114
modules/server/src/topics/enginemodetopic.cpp
Normal file
114
modules/server/src/topics/enginemodetopic.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 "modules/server/include/topics/enginemodetopic.h"
|
||||
|
||||
#include <modules/server/include/connection.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "EngineModeTopic";
|
||||
|
||||
constexpr std::string_view SubscribeEvent = "start_subscription";
|
||||
constexpr std::string_view UnsubscribeEvent = "stop_subscription";
|
||||
constexpr std::string_view RefreshEvent = "refresh";
|
||||
} // namespace
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
namespace openspace {
|
||||
|
||||
EngineModeTopic::EngineModeTopic() {
|
||||
LDEBUG("Starting new EngineMode subscription");
|
||||
}
|
||||
|
||||
EngineModeTopic::~EngineModeTopic() {
|
||||
if (_modeCallbackHandle != UnsetOnChangeHandle) {
|
||||
global::openSpaceEngine->removeModeChangeCallback(_modeCallbackHandle);
|
||||
}
|
||||
}
|
||||
|
||||
bool EngineModeTopic::isDone() const {
|
||||
return _isDone;
|
||||
}
|
||||
|
||||
void EngineModeTopic::handleJson(const nlohmann::json& json) {
|
||||
const std::string event = json.at("event").get<std::string>();
|
||||
if (event != SubscribeEvent && event != UnsubscribeEvent &&
|
||||
event != RefreshEvent)
|
||||
{
|
||||
LERROR("Unsupported event");
|
||||
_isDone = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == UnsubscribeEvent) {
|
||||
_isDone = true;
|
||||
return;
|
||||
}
|
||||
|
||||
sendJsonData();
|
||||
|
||||
if (event == SubscribeEvent) {
|
||||
_modeCallbackHandle = global::openSpaceEngine->addModeChangeCallback(
|
||||
[this]() {
|
||||
OpenSpaceEngine::Mode currentMode =
|
||||
global::openSpaceEngine->currentMode();
|
||||
if (currentMode != _lastMode) {
|
||||
sendJsonData();
|
||||
_lastMode = currentMode;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void EngineModeTopic::sendJsonData() {
|
||||
json stateJson;
|
||||
|
||||
OpenSpaceEngine::Mode mode = global::openSpaceEngine->currentMode();
|
||||
std::string modeString;
|
||||
switch (mode) {
|
||||
case OpenSpaceEngine::Mode::UserControl:
|
||||
modeString = "user_control";
|
||||
break;
|
||||
case OpenSpaceEngine::Mode::SessionRecordingPlayback:
|
||||
modeString = "session_recording_playback";
|
||||
break;
|
||||
case OpenSpaceEngine::Mode::CameraPath:
|
||||
modeString = "camera_path";
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
stateJson["mode"] = modeString;
|
||||
|
||||
if (!stateJson.empty()) {
|
||||
_connection->sendJson(wrappedPayload(stateJson));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -27,11 +27,10 @@
|
||||
#include <modules/server/include/connection.h>
|
||||
#include <modules/server/include/jsonconverters.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/interaction/websocketcamerastates.h>
|
||||
#include <openspace/interaction/websocketinputstate.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
@@ -59,7 +58,8 @@ namespace {
|
||||
|
||||
using AxisType = openspace::interaction::WebsocketCameraStates::AxisType;
|
||||
|
||||
constexpr const char* _loggerCat = "FlightControllerTopic";
|
||||
constexpr std::string_view _loggerCat = "FlightControllerTopic";
|
||||
|
||||
constexpr const char* TypeKey = "type";
|
||||
constexpr const char* ValuesKey = "values";
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -28,9 +28,8 @@
|
||||
#include <modules/server/include/jsonconverters.h>
|
||||
#include <modules/volume/transferfunctionhandler.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/virtualpropertymanager.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/rendering/luaconsole.h>
|
||||
@@ -42,18 +41,18 @@
|
||||
using nlohmann::json;
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "GetPropertyTopic";
|
||||
constexpr const char* AllPropertiesValue = "__allProperties";
|
||||
constexpr const char* AllNodesValue = "__allNodes";
|
||||
constexpr const char* AllScreenSpaceRenderablesValue = "__screenSpaceRenderables";
|
||||
constexpr const char* PropertyKey = "property";
|
||||
constexpr const char* RootPropertyOwner = "__rootOwner";
|
||||
constexpr std::string_view _loggerCat = "GetPropertyTopic";
|
||||
constexpr std::string_view AllPropertiesValue = "__allProperties";
|
||||
constexpr std::string_view AllNodesValue = "__allNodes";
|
||||
constexpr std::string_view AllScreenSpaceRenderablesValue =
|
||||
"__screenSpaceRenderables";
|
||||
constexpr std::string_view RootPropertyOwner = "__rootOwner";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
void GetPropertyTopic::handleJson(const nlohmann::json& json) {
|
||||
std::string requestedKey = json.at(PropertyKey).get<std::string>();
|
||||
std::string requestedKey = json.at("property").get<std::string>();
|
||||
LDEBUG("Getting property '" + requestedKey + "'...");
|
||||
nlohmann::json response;
|
||||
if (requestedKey == AllPropertiesValue) {
|
||||
@@ -88,8 +87,7 @@ json GetPropertyTopic::allProperties() {
|
||||
global::renderEngine,
|
||||
global::luaConsole,
|
||||
global::parallelPeer,
|
||||
global::navigationHandler,
|
||||
global::virtualPropertyManager,
|
||||
global::navigationHandler
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -33,11 +33,11 @@
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyScript = "script";
|
||||
constexpr const char* KeyFunction = "function";
|
||||
constexpr const char* KeyArguments = "arguments";
|
||||
constexpr const char* KeyReturn = "return";
|
||||
constexpr const char* _loggerCat = "LuaScriptTopic";
|
||||
constexpr std::string_view KeyScript = "script";
|
||||
constexpr std::string_view KeyFunction = "function";
|
||||
constexpr std::string_view KeyArguments = "arguments";
|
||||
constexpr std::string_view KeyReturn = "return";
|
||||
constexpr std::string_view _loggerCat = "LuaScriptTopic";
|
||||
|
||||
std::string formatLua(const nlohmann::json::const_iterator& it);
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace {
|
||||
if (it->is_null()) {
|
||||
return "nil";
|
||||
}
|
||||
throw ghoul::lua::LuaFormatException("Format error.");
|
||||
throw ghoul::lua::LuaFormatException("Format error");
|
||||
}
|
||||
|
||||
std::string generateScript(const std::string& function,
|
||||
@@ -176,13 +176,14 @@ void LuaScriptTopic::handleJson(const nlohmann::json& json) {
|
||||
}
|
||||
}
|
||||
|
||||
void LuaScriptTopic::runScript(const std::string& script, bool shouldReturn) {
|
||||
void LuaScriptTopic::runScript(std::string script, bool shouldReturn) {
|
||||
scripting::ScriptEngine::ScriptCallback callback;
|
||||
if (shouldReturn) {
|
||||
callback = [this](ghoul::Dictionary data) {
|
||||
if (_connection) {
|
||||
nlohmann::json j = data;
|
||||
_connection->sendJson(wrappedPayload(j));
|
||||
nlohmann::json payload = wrappedPayload(j);
|
||||
_connection->sendJson(payload);
|
||||
_waitingForReturnValue = false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -30,11 +30,11 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "SessionRecordingTopic";
|
||||
constexpr const char* EventKey = "event";
|
||||
constexpr const char* SubscribeEvent = "start_subscription";
|
||||
constexpr const char* UnsubscribeEvent = "stop_subscription";
|
||||
constexpr const char* RefreshEvent = "refresh";
|
||||
constexpr std::string_view _loggerCat = "SessionRecordingTopic";
|
||||
|
||||
constexpr std::string_view SubscribeEvent = "start_subscription";
|
||||
constexpr std::string_view UnsubscribeEvent = "stop_subscription";
|
||||
constexpr std::string_view RefreshEvent = "refresh";
|
||||
|
||||
constexpr const char* PropertiesKey = "properties";
|
||||
constexpr const char* FilesKey = "files";
|
||||
@@ -60,7 +60,7 @@ bool SessionRecordingTopic::isDone() const {
|
||||
}
|
||||
|
||||
void SessionRecordingTopic::handleJson(const nlohmann::json& json) {
|
||||
const std::string event = json.at(EventKey).get<std::string>();
|
||||
const std::string event = json.at("event").get<std::string>();
|
||||
if (event != SubscribeEvent && event != UnsubscribeEvent &&
|
||||
event != RefreshEvent)
|
||||
{
|
||||
@@ -76,13 +76,13 @@ void SessionRecordingTopic::handleJson(const nlohmann::json& json) {
|
||||
|
||||
if (json.find(PropertiesKey) != json.end()) {
|
||||
if (!json.at(PropertiesKey).is_array()) {
|
||||
LERROR("Properties must be an array of strings.");
|
||||
LERROR("Properties must be an array of strings");
|
||||
}
|
||||
nlohmann::json requestedProperties = json.at(PropertiesKey).get<nlohmann::json>();
|
||||
for (const auto& p : requestedProperties) {
|
||||
if (!p.is_string()) {
|
||||
_isDone = true;
|
||||
LERROR("Properties must be an array of strings.");
|
||||
LERROR("Properties must be an array of strings");
|
||||
return;
|
||||
}
|
||||
const std::string v = p.get<std::string>();
|
||||
@@ -124,6 +124,9 @@ void SessionRecordingTopic::sendJsonData() {
|
||||
case SessionRecording::SessionState::Playback:
|
||||
stateString = "playing";
|
||||
break;
|
||||
case SessionRecording::SessionState::PlaybackPaused:
|
||||
stateString = "playing-paused";
|
||||
break;
|
||||
default:
|
||||
stateString = "idle";
|
||||
break;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -34,10 +34,8 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* PropertyKey = "property";
|
||||
constexpr const char* ValueKey = "value";
|
||||
constexpr const char* _loggerCat = "SetPropertyTopic";
|
||||
constexpr const char* SpecialKeyTime = "__time";
|
||||
constexpr std::string_view _loggerCat = "SetPropertyTopic";
|
||||
constexpr std::string_view SpecialKeyTime = "__time";
|
||||
|
||||
std::string escapedLuaString(const std::string& str) {
|
||||
std::string luaString;
|
||||
@@ -113,15 +111,15 @@ namespace openspace {
|
||||
|
||||
void SetPropertyTopic::handleJson(const nlohmann::json& json) {
|
||||
try {
|
||||
const std::string& propertyKey = json.at(PropertyKey).get<std::string>();
|
||||
const std::string& propertyKey = json.at("property").get<std::string>();
|
||||
|
||||
if (propertyKey == SpecialKeyTime) {
|
||||
Time newTime;
|
||||
newTime.setTime(json.at(ValueKey).get<std::string>());
|
||||
newTime.setTime(json.at("value").get<std::string>());
|
||||
global::timeManager->setTimeNextFrame(newTime);
|
||||
}
|
||||
else {
|
||||
nlohmann::json value = json.at(ValueKey);
|
||||
nlohmann::json value = json.at("value");
|
||||
std::string literal = luaLiteralFromJson(value);
|
||||
|
||||
global::scriptEngine->queueScript(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -26,14 +26,9 @@
|
||||
|
||||
#include <modules/server/include/connection.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/shortcutmanager.h>
|
||||
#include <openspace/interaction/actionmanager.h>
|
||||
#include <openspace/interaction/keybindingmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* EventKey = "event";
|
||||
constexpr const char* StartSubscription = "start_subscription";
|
||||
constexpr const char* StopSubscription = "stop_subscription";
|
||||
} // namespace
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
@@ -44,32 +39,50 @@ bool ShortcutTopic::isDone() const {
|
||||
}
|
||||
|
||||
std::vector<nlohmann::json> ShortcutTopic::shortcutsJson() const {
|
||||
using ShortcutInformation = interaction::ShortcutManager::ShortcutInformation;
|
||||
|
||||
const std::vector<ShortcutInformation>& shortcuts =
|
||||
global::shortcutManager->shortcuts();
|
||||
|
||||
std::vector<nlohmann::json> json;
|
||||
for (const ShortcutInformation& shortcut : shortcuts) {
|
||||
std::vector<interaction::Action> actions = global::actionManager->actions();
|
||||
std::sort(
|
||||
actions.begin(),
|
||||
actions.end(),
|
||||
[](const interaction::Action& lhs, const interaction::Action& rhs) {
|
||||
if (!lhs.name.empty() && !rhs.name.empty()) {
|
||||
return lhs.name < rhs.name;
|
||||
}
|
||||
else {
|
||||
return lhs.identifier < rhs.identifier;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
for (const interaction::Action& action : actions) {
|
||||
nlohmann::json shortcutJson = {
|
||||
{ "name", shortcut.name },
|
||||
{ "script", shortcut.script },
|
||||
{ "synchronization", static_cast<bool>(shortcut.synchronization) },
|
||||
{ "documentation", shortcut.documentation },
|
||||
{ "guiPath", shortcut.guiPath },
|
||||
{ "identifier", action.identifier },
|
||||
{ "name", action.name },
|
||||
{ "script", action.command },
|
||||
{ "synchronization", static_cast<bool>(action.synchronization) },
|
||||
{ "documentation", action.documentation },
|
||||
{ "guiPath", action.guiPath },
|
||||
};
|
||||
json.push_back(shortcutJson);
|
||||
}
|
||||
|
||||
using KeyInformation = interaction::KeybindingManager::KeyInformation;
|
||||
|
||||
const std::multimap<KeyWithModifier, KeyInformation>& keyBindings =
|
||||
const std::multimap<KeyWithModifier, std::string>& keyBindings =
|
||||
global::keybindingManager->keyBindings();
|
||||
|
||||
for (const std::pair<const KeyWithModifier, KeyInformation>& keyBinding : keyBindings)
|
||||
{
|
||||
for (const std::pair<const KeyWithModifier, std::string>& keyBinding : keyBindings) {
|
||||
if (!global::actionManager->hasAction(keyBinding.second)) {
|
||||
// We don't warn here as we don't know if the user didn't expect the action
|
||||
// to be there or not. They might have defined a keybind to do multiple things
|
||||
// only one of which is actually defined
|
||||
continue;
|
||||
}
|
||||
|
||||
const KeyWithModifier& k = keyBinding.first;
|
||||
const KeyInformation& info = keyBinding.second;
|
||||
// @TODO (abock, 2021-08-05) Probably this should be rewritten to better account
|
||||
// for the new action mechanism
|
||||
const interaction::Action& action = global::actionManager->action(
|
||||
keyBinding.second
|
||||
);
|
||||
|
||||
nlohmann::json shortcutJson = {
|
||||
{ "key", ghoul::to_string(k.key) },
|
||||
@@ -81,11 +94,7 @@ std::vector<nlohmann::json> ShortcutTopic::shortcutsJson() const {
|
||||
{ "super" , hasKeyModifier(k.modifier, KeyModifier::Super) }
|
||||
}
|
||||
},
|
||||
{ "name", info.name },
|
||||
{ "script", info.command },
|
||||
{ "synchronization", static_cast<bool>(info.synchronization) },
|
||||
{ "documentation", info.documentation },
|
||||
{ "guiPath", info.guiPath },
|
||||
{ "action", action.identifier },
|
||||
};
|
||||
json.push_back(shortcutJson);
|
||||
}
|
||||
@@ -98,12 +107,12 @@ void ShortcutTopic::sendData() const {
|
||||
}
|
||||
|
||||
void ShortcutTopic::handleJson(const nlohmann::json& input) {
|
||||
const std::string& event = input.at(EventKey).get<std::string>();
|
||||
if (event == StartSubscription) {
|
||||
const std::string& event = input.at("event").get<std::string>();
|
||||
if (event == "start_subscription") {
|
||||
// TODO: Subscribe to shortcuts and keybindings
|
||||
// shortcutManager.subscribe(); ...
|
||||
}
|
||||
else if (event == StopSubscription) {
|
||||
else if (event == "stop_subscription") {
|
||||
// TODO: Unsubscribe to shortcuts and keybindings
|
||||
// shortcutManager.unsubscribe(); ...
|
||||
return;
|
||||
|
||||
130
modules/server/src/topics/skybrowsertopic.cpp
Normal file
130
modules/server/src/topics/skybrowsertopic.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 "modules/server/include/topics/skybrowsertopic.h"
|
||||
|
||||
#include <modules/server/include/connection.h>
|
||||
#include <modules/server/servermodule.h>
|
||||
#include <modules/skybrowser/skybrowsermodule.h>
|
||||
#include <modules/skybrowser/include/targetbrowserpair.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/properties/property.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr std::string_view SubscribeEvent = "start_subscription";
|
||||
constexpr std::string_view UnsubscribeEvent = "stop_subscription";
|
||||
} // namespace
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
namespace openspace {
|
||||
|
||||
SkyBrowserTopic::SkyBrowserTopic()
|
||||
: _lastUpdateTime(std::chrono::system_clock::now())
|
||||
{
|
||||
ServerModule* module = global::moduleEngine->module<ServerModule>();
|
||||
if (module) {
|
||||
_skyBrowserUpdateTime = std::chrono::milliseconds(module->skyBrowserUpdateTime());
|
||||
}
|
||||
}
|
||||
|
||||
SkyBrowserTopic::~SkyBrowserTopic() {
|
||||
if (_targetDataCallbackHandle != UnsetOnChangeHandle) {
|
||||
ServerModule* module = global::moduleEngine->module<ServerModule>();
|
||||
if (module) {
|
||||
module->removePreSyncCallback(_targetDataCallbackHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SkyBrowserTopic::isDone() const {
|
||||
return _isDone;
|
||||
}
|
||||
|
||||
void SkyBrowserTopic::handleJson(const nlohmann::json& json) {
|
||||
std::string event = json.at("event").get<std::string>();
|
||||
if (event == UnsubscribeEvent) {
|
||||
_isDone = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event != SubscribeEvent) {
|
||||
_isDone = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ServerModule* module = global::moduleEngine->module<ServerModule>();
|
||||
_targetDataCallbackHandle = module->addPreSyncCallback(
|
||||
[this]() {
|
||||
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
|
||||
if (now - _lastUpdateTime > _skyBrowserUpdateTime) {
|
||||
sendBrowserData();
|
||||
_lastUpdateTime = std::chrono::system_clock::now();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SkyBrowserTopic::sendBrowserData() {
|
||||
using namespace openspace;
|
||||
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
ghoul::Dictionary data;
|
||||
|
||||
// Set general data
|
||||
data.setValue("selectedBrowserId", module->selectedBrowserId());
|
||||
data.setValue("cameraInSolarSystem", module->isCameraInSolarSystem());
|
||||
|
||||
// Pass data for all the browsers and the corresponding targets
|
||||
if (module->isCameraInSolarSystem()) {
|
||||
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->pairs();
|
||||
ghoul::Dictionary targets;
|
||||
for (const std::unique_ptr<TargetBrowserPair>& pair : pairs) {
|
||||
std::string id = pair->browserId();
|
||||
ghoul::Dictionary target = pair->dataAsDictionary();
|
||||
targets.setValue(id, target);
|
||||
}
|
||||
data.setValue("browsers", targets);
|
||||
}
|
||||
|
||||
std::string jsonString = ghoul::formatJson(data);
|
||||
|
||||
// Only send message if data actually changed
|
||||
if (jsonString != _lastUpdateJsonString) {
|
||||
json jsonData = json::parse(jsonString.begin(), jsonString.end());
|
||||
_connection->sendJson(wrappedPayload(jsonData));
|
||||
}
|
||||
|
||||
// @TODO (2022-04-28, emmbr) The message is still sent very often; every time the
|
||||
// camera moves or the time is changes, because this changes the "roll" parameter
|
||||
// of the browser. This is the update that occurs most often. Maybe it could be
|
||||
// separated into it's own topic?
|
||||
|
||||
_lastUpdateJsonString = jsonString;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -33,12 +33,10 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "SubscriptionTopic";
|
||||
constexpr const char* PropertyKey = "property";
|
||||
constexpr const char* EventKey = "event";
|
||||
constexpr std::string_view _loggerCat = "SubscriptionTopic";
|
||||
|
||||
constexpr const char* StartSubscription = "start_subscription";
|
||||
constexpr const char* StopSubscription = "stop_subscription";
|
||||
constexpr std::string_view StartSubscription = "start_subscription";
|
||||
constexpr std::string_view StopSubscription = "stop_subscription";
|
||||
} // namespace
|
||||
|
||||
using nlohmann::json;
|
||||
@@ -68,10 +66,10 @@ void SubscriptionTopic::resetCallbacks() {
|
||||
}
|
||||
|
||||
void SubscriptionTopic::handleJson(const nlohmann::json& json) {
|
||||
const std::string& event = json.at(EventKey).get<std::string>();
|
||||
const std::string& event = json.at("event").get<std::string>();
|
||||
|
||||
if (event == StartSubscription) {
|
||||
std::string key = json.at(PropertyKey).get<std::string>();
|
||||
std::string key = json.at("property").get<std::string>();
|
||||
|
||||
_prop = property(key);
|
||||
resetCallbacks();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -32,10 +32,9 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* EventKey = "event";
|
||||
constexpr const char* SubscribeEvent = "start_subscription";
|
||||
constexpr const char* UnsubscribeEvent = "stop_subscription";
|
||||
constexpr const std::chrono::milliseconds TimeUpdateInterval(50);
|
||||
constexpr std::string_view SubscribeEvent = "start_subscription";
|
||||
constexpr std::string_view UnsubscribeEvent = "stop_subscription";
|
||||
constexpr std::chrono::milliseconds TimeUpdateInterval(50);
|
||||
} // namespace
|
||||
|
||||
using nlohmann::json;
|
||||
@@ -65,7 +64,7 @@ bool TimeTopic::isDone() const {
|
||||
}
|
||||
|
||||
void TimeTopic::handleJson(const nlohmann::json& json) {
|
||||
std::string event = json.at(EventKey).get<std::string>();
|
||||
std::string event = json.at("event").get<std::string>();
|
||||
if (event == UnsubscribeEvent) {
|
||||
_isDone = true;
|
||||
return;
|
||||
@@ -134,7 +133,7 @@ const json TimeTopic::getNextPrevDeltaTimeStepJson() {
|
||||
}
|
||||
|
||||
void TimeTopic::sendCurrentTime() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const json timeJson = {
|
||||
{ "time", global::timeManager->time().ISO8601() }
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -30,17 +30,13 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
Topic::~Topic() {
|
||||
_connection = nullptr;
|
||||
}
|
||||
|
||||
void Topic::initialize(Connection* connection, size_t topicId) {
|
||||
_connection = connection;
|
||||
void Topic::initialize(std::shared_ptr<Connection> connection, size_t topicId) {
|
||||
_connection = std::move(connection);
|
||||
_topicId = topicId;
|
||||
}
|
||||
|
||||
nlohmann::json Topic::wrappedPayload(const nlohmann::json& payload) const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// TODO: add message time
|
||||
nlohmann::json j = {
|
||||
@@ -51,7 +47,7 @@ nlohmann::json Topic::wrappedPayload(const nlohmann::json& payload) const {
|
||||
}
|
||||
|
||||
nlohmann::json Topic::wrappedError(std::string message, int code) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
nlohmann::json j = {
|
||||
{ "topic", _topicId },
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -32,16 +32,14 @@
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* PropertyKey = "property";
|
||||
//constexpr const char* ValueKey = "value";
|
||||
constexpr const char* _loggerCat = "TriggerPropertyTopic";
|
||||
constexpr std::string_view _loggerCat = "TriggerPropertyTopic";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
void TriggerPropertyTopic::handleJson(const nlohmann::json& json) {
|
||||
try {
|
||||
const std::string& propertyKey = json.at(PropertyKey).get<std::string>();
|
||||
const std::string& propertyKey = json.at("property").get<std::string>();
|
||||
global::scriptEngine->queueScript(
|
||||
fmt::format(
|
||||
"openspace.setPropertyValueSingle(\"{}\", nil)", propertyKey
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 *
|
||||
|
||||
Reference in New Issue
Block a user