mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-27 14:39:20 -06:00
Merge branch 'develop' of github.com:OpenSpace/OpenSpace into pr/kameleonvolume
Conflicts: src/engine/openspaceengine.cpp
This commit is contained in:
@@ -40,13 +40,10 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/engine/wrapper/sgctwindowwrapper.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/engine/wrapper/windowwrapper.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/controller.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/deviceidentifier.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/interactionhandler.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/interactionmode.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/interactionhandler_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/keyboardcontroller.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/luaconsole.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/luaconsole_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/mission/mission.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/mission/missionmanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/mission/missionmanager_lua.inl
|
||||
@@ -179,10 +176,8 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/engine/wrapper/sgctwindowwrapper.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/engine/wrapper/windowwrapper.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/controller.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/deviceidentifier.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/interactionhandler.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/interactionmode.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/keyboardcontroller.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/luaconsole.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/mission/mission.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/mission/missionmanager.h
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
|
||||
#include <openspace/documentation/documentationengine.h>
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
#include <openspace/engine/logfactory.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/wrapper/windowwrapper.h>
|
||||
#include <openspace/interaction/interactionhandler.h>
|
||||
#include <openspace/interaction/luaconsole.h>
|
||||
#include <openspace/mission/mission.h>
|
||||
#include <openspace/mission/missionmanager.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
@@ -51,6 +51,7 @@ namespace openspace {
|
||||
|
||||
void registerCoreClasses(documentation::DocumentationEngine& engine) {
|
||||
engine.addDocumentation(ConfigurationManager::Documentation());
|
||||
engine.addDocumentation(LogFactoryDocumentation());
|
||||
engine.addDocumentation(Mission::Documentation());
|
||||
engine.addDocumentation(Renderable::Documentation());
|
||||
engine.addDocumentation(Rotation::Documentation());
|
||||
@@ -69,7 +70,6 @@ void registerCoreClasses(scripting::ScriptEngine& engine) {
|
||||
engine.addLibrary(Scene::luaLibrary());
|
||||
engine.addLibrary(Time::luaLibrary());
|
||||
engine.addLibrary(interaction::InteractionHandler::luaLibrary());
|
||||
engine.addLibrary(LuaConsole::luaLibrary());
|
||||
engine.addLibrary(ParallelConnection::luaLibrary());
|
||||
engine.addLibrary(ModuleEngine::luaLibrary());
|
||||
engine.addLibrary(scripting::ScriptScheduler::luaLibrary());
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <streambuf>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
@@ -225,25 +225,25 @@ TestResult ReferencingVerifier::operator()(const ghoul::Dictionary& dictionary,
|
||||
[this](const Documentation& doc) { return doc.id == identifier; }
|
||||
);
|
||||
|
||||
if (it == documentations.end()) {
|
||||
return { false, { { key, TestResult::Offense::Reason::UnknownIdentifier } } };
|
||||
ghoul_assert(
|
||||
it != documentations.end(),
|
||||
"Did not find referencing identifier '" + identifier + "'"
|
||||
);
|
||||
|
||||
ghoul::Dictionary d = dictionary.value<ghoul::Dictionary>(key);
|
||||
TestResult res = testSpecification(*it, d);
|
||||
|
||||
// Add the 'key' as a prefix to make the offender a fully qualified identifer
|
||||
for (TestResult::Offense& s : res.offenses) {
|
||||
s.offender = key + "." + s.offender;
|
||||
}
|
||||
else {
|
||||
ghoul::Dictionary d = dictionary.value<ghoul::Dictionary>(key);
|
||||
TestResult res = testSpecification(*it, d);
|
||||
|
||||
// Add the 'key' as a prefix to make the offender a fully qualified identifer
|
||||
for (TestResult::Offense& s : res.offenses) {
|
||||
s.offender = key + "." + s.offender;
|
||||
}
|
||||
|
||||
// Add the 'key' as a prefix to make the warning a fully qualified identifer
|
||||
for (TestResult::Warning& w : res.warnings) {
|
||||
w.offender = key + "." + w.offender;
|
||||
}
|
||||
|
||||
return res;
|
||||
// Add the 'key' as a prefix to make the warning a fully qualified identifer
|
||||
for (TestResult::Warning& w : res.warnings) {
|
||||
w.offender = key + "." + w.offender;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
else {
|
||||
return res;
|
||||
|
||||
@@ -113,31 +113,8 @@ documentation::Documentation ConfigurationManager::Documentation() {
|
||||
new TableVerifier({
|
||||
{
|
||||
"*",
|
||||
new TableVerifier({
|
||||
{
|
||||
ConfigurationManager::PartType,
|
||||
new StringInListVerifier({
|
||||
// List from logfactory.cpp::createLog
|
||||
"text", "html"
|
||||
}),
|
||||
"The type of the new log to be generated."
|
||||
},
|
||||
{
|
||||
ConfigurationManager::PartFile,
|
||||
new StringVerifier,
|
||||
"The filename to which the log will be written."
|
||||
},
|
||||
{
|
||||
ConfigurationManager::PartAppend,
|
||||
new BoolVerifier,
|
||||
"Determines whether the file will be cleared at "
|
||||
"startup or if the contents will be appended to "
|
||||
"previous runs.",
|
||||
Optional::Yes
|
||||
}
|
||||
}),
|
||||
"Additional log files",
|
||||
Optional::Yes
|
||||
new ReferencingVerifier("core_logfactory"),
|
||||
"Additional log files"
|
||||
}
|
||||
}),
|
||||
"Per default, log messages are written to the console, the "
|
||||
|
||||
@@ -162,7 +162,10 @@ std::shared_ptr<DownloadManager::FileFuture> DownloadManager::downloadFile(
|
||||
std::shared_ptr<FileFuture> future = std::make_shared<FileFuture>(file.filename());
|
||||
errno = 0;
|
||||
FILE* fp = fopen(file.path().c_str(), "wb"); // write binary
|
||||
ghoul_assert(fp != nullptr, "Could not open/create file:\n" << file.path().c_str() << " \nerrno: " << errno);
|
||||
ghoul_assert(
|
||||
fp != nullptr,
|
||||
"Could not open/create file:\n" + file.path() + " \nerrno: " + std::to_string(errno)
|
||||
);
|
||||
|
||||
//LDEBUG("Start downloading file: '" << url << "' into file '" << file.path() << "'");
|
||||
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
|
||||
#include <openspace/engine/logfactory.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
@@ -51,37 +54,105 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation LogFactoryDocumentation() {
|
||||
using namespace documentation;
|
||||
|
||||
return {
|
||||
"LogFactory",
|
||||
"core_logfactory",
|
||||
{
|
||||
{
|
||||
keyType,
|
||||
new StringInListVerifier({
|
||||
// List from createLog
|
||||
valueTextLog, valueHtmlLog
|
||||
}),
|
||||
"The type of the new log to be generated."
|
||||
},
|
||||
{
|
||||
keyFilename,
|
||||
new StringVerifier,
|
||||
"The filename to which the log will be written."
|
||||
},
|
||||
{
|
||||
keyAppend,
|
||||
new BoolVerifier,
|
||||
"Determines whether the file will be cleared at startup or if the "
|
||||
"contents will be appended to previous runs.",
|
||||
Optional::Yes
|
||||
},
|
||||
{
|
||||
keyTimeStamping,
|
||||
new BoolVerifier,
|
||||
"Determines whether the log entires should be stamped with the time at "
|
||||
"which the message was logged.",
|
||||
Optional::Yes
|
||||
},
|
||||
{
|
||||
keyDateStamping,
|
||||
new BoolVerifier,
|
||||
"Determines whether the log entries should be stamped with the date at "
|
||||
"which the message was logged.",
|
||||
Optional::Yes
|
||||
},
|
||||
{
|
||||
keyCategoryStamping,
|
||||
new BoolVerifier,
|
||||
"Determines whether the log entries should be stamped with the "
|
||||
"category that creates the log message.",
|
||||
Optional::Yes
|
||||
},
|
||||
{
|
||||
keyLogLevelStamping,
|
||||
new BoolVerifier,
|
||||
"Determines whether the log entries should be stamped with the log level "
|
||||
"that was used to create the log message.",
|
||||
Optional::Yes
|
||||
}
|
||||
},
|
||||
Exhaustive::Yes
|
||||
};
|
||||
}
|
||||
|
||||
std::unique_ptr<ghoul::logging::Log> createLog(const ghoul::Dictionary& dictionary) {
|
||||
using namespace std::string_literals;
|
||||
std::string type;
|
||||
bool typeSuccess = dictionary.getValue(keyType, type);
|
||||
if (!typeSuccess) {
|
||||
throw ghoul::RuntimeError(
|
||||
"Requested log did not contain key '"s + keyType + "'", "LogFactory"
|
||||
);
|
||||
}
|
||||
|
||||
std::string filename;
|
||||
bool filenameSuccess = dictionary.getValue(keyFilename, filename);
|
||||
if (!filenameSuccess) {
|
||||
throw ghoul::RuntimeError(
|
||||
"Requested log did not contain key '"s + keyFilename + "'", "LogFactory"
|
||||
);
|
||||
}
|
||||
filename = absPath(filename);
|
||||
documentation::testSpecificationAndThrow(
|
||||
LogFactoryDocumentation(),
|
||||
dictionary,
|
||||
"LogFactory"
|
||||
);
|
||||
|
||||
// 'type' and 'filename' are required keys
|
||||
std::string type = dictionary.value<std::string>(keyType);
|
||||
std::string filename = absPath(dictionary.value<std::string>(keyFilename));
|
||||
|
||||
// the rest are optional
|
||||
bool append = true;
|
||||
dictionary.getValue(keyAppend, append);
|
||||
if (dictionary.hasKeyAndValue<bool>(keyAppend)) {
|
||||
dictionary.value<bool>(keyAppend);
|
||||
}
|
||||
bool timeStamp = true;
|
||||
dictionary.getValue(keyTimeStamping, timeStamp);
|
||||
if (dictionary.hasKeyAndValue<bool>(keyTimeStamping)) {
|
||||
dictionary.value<bool>(keyTimeStamping);
|
||||
}
|
||||
bool dateStamp = true;
|
||||
dictionary.getValue(keyDateStamping, dateStamp);
|
||||
if (dictionary.hasKeyAndValue<bool>(keyDateStamping)) {
|
||||
dictionary.value<bool>(keyDateStamping);
|
||||
}
|
||||
bool categoryStamp = true;
|
||||
dictionary.getValue(keyCategoryStamping, categoryStamp);
|
||||
if (dictionary.hasKeyAndValue<bool>(keyCategoryStamping)) {
|
||||
dictionary.value<bool>(keyCategoryStamping);
|
||||
}
|
||||
bool logLevelStamp = true;
|
||||
dictionary.getValue(keyLogLevelStamping, logLevelStamp);
|
||||
if (dictionary.hasKeyAndValue<bool>(keyLogLevelStamping)) {
|
||||
dictionary.value<bool>(keyLogLevelStamping);
|
||||
}
|
||||
std::string logLevel;
|
||||
dictionary.getValue(keyLogLevel, logLevel);
|
||||
if (dictionary.hasKeyAndValue<std::string>(keyLogLevel)) {
|
||||
dictionary.value<std::string>(keyLogLevel);
|
||||
}
|
||||
|
||||
|
||||
using Append = ghoul::logging::TextLog::Append;
|
||||
using TimeStamping = ghoul::logging::Log::TimeStamping;
|
||||
@@ -90,7 +161,6 @@ std::unique_ptr<ghoul::logging::Log> createLog(const ghoul::Dictionary& dictiona
|
||||
using LogLevelStamping = ghoul::logging::Log::LogLevelStamping;
|
||||
|
||||
if (type == valueHtmlLog) {
|
||||
|
||||
std::vector<std::string> cssFiles{absPath(BootstrapPath), absPath(CssPath)};
|
||||
std::vector<std::string> jsFiles{absPath(JsPath)};
|
||||
|
||||
@@ -102,7 +172,8 @@ std::unique_ptr<ghoul::logging::Log> createLog(const ghoul::Dictionary& dictiona
|
||||
dateStamp ? DateStamping::Yes : DateStamping::No,
|
||||
categoryStamp ? CategoryStamping::Yes : CategoryStamping::No,
|
||||
logLevelStamp ? LogLevelStamping::Yes : LogLevelStamping::No,
|
||||
cssFiles, jsFiles
|
||||
cssFiles,
|
||||
jsFiles
|
||||
);
|
||||
}
|
||||
else {
|
||||
@@ -141,11 +212,7 @@ std::unique_ptr<ghoul::logging::Log> createLog(const ghoul::Dictionary& dictiona
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw ghoul::RuntimeError(
|
||||
"Log with type '" + type + "' did not name a valid log", "LogFactory"
|
||||
);
|
||||
}
|
||||
ghoul_assert(false, "Missing case in the documentation for LogFactory");
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
|
||||
#include <openspace/moduleregistration.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
@@ -34,7 +35,7 @@
|
||||
#include "moduleengine_lua.inl"
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "ModuleEngine";
|
||||
const char* _loggerCat = "ModuleEngine";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
@@ -67,7 +68,8 @@ void ModuleEngine::registerModule(std::unique_ptr<OpenSpaceModule> module) {
|
||||
);
|
||||
if (it != _modules.end()) {
|
||||
throw ghoul::RuntimeError(
|
||||
"Module name '" + module->name() + "' was registered before", "ModuleEngine"
|
||||
"Module name '" + module->name() + "' was registered before",
|
||||
"ModuleEngine"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -85,11 +87,8 @@ std::vector<OpenSpaceModule*> ModuleEngine::modules() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
ghoul::systemcapabilities::OpenGLCapabilitiesComponent::Version
|
||||
ModuleEngine::requiredOpenGLVersion() const
|
||||
{
|
||||
using Version = ghoul::systemcapabilities::OpenGLCapabilitiesComponent::Version;
|
||||
Version version = { 0,0 };
|
||||
ghoul::systemcapabilities::Version ModuleEngine::requiredOpenGLVersion() const {
|
||||
ghoul::systemcapabilities::Version version = { 0, 0 };
|
||||
|
||||
for (const auto& m : _modules) {
|
||||
version = std::max(version, m->requiredOpenGLVersion());
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <openspace/openspace.h>
|
||||
|
||||
#include <openspace/documentation/core_registration.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/documentationengine.h>
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
#include <openspace/engine/downloadmanager.h>
|
||||
@@ -37,45 +36,32 @@
|
||||
#include <openspace/engine/syncengine.h>
|
||||
#include <openspace/engine/wrapper/windowwrapper.h>
|
||||
#include <openspace/interaction/interactionhandler.h>
|
||||
#include <openspace/interaction/keyboardcontroller.h>
|
||||
#include <openspace/interaction/luaconsole.h>
|
||||
#include <openspace/mission/missionmanager.h>
|
||||
#include <openspace/network/networkengine.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/scripting/scriptscheduler.h>
|
||||
#include <openspace/scene/translation.h>
|
||||
#include <openspace/scene/rotation.h>
|
||||
#include <openspace/scene/scale.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/translation.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/task.h>
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/syncbuffer.h>
|
||||
#include <openspace/util/transformationmanager.h>
|
||||
|
||||
#include <ghoul/ghoul.h>
|
||||
#include <ghoul/cmdparser/commandlineparser.h>
|
||||
#include <ghoul/cmdparser/singlecommand.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
#include <ghoul/logging/consolelog.h>
|
||||
#include <ghoul/logging/visualstudiooutputlog.h>
|
||||
#include <ghoul/lua/ghoul_lua.h>
|
||||
#include <ghoul/lua/lua_helper.h>
|
||||
#include <ghoul/lua/luastate.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <ghoul/misc/onscopeexit.h>
|
||||
#include <ghoul/systemcapabilities/systemcapabilities>
|
||||
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
|
||||
#if defined(_MSC_VER) && defined(OPENSPACE_ENABLE_VLD)
|
||||
#include <vld.h>
|
||||
@@ -128,7 +114,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName,
|
||||
, _scriptEngine(new scripting::ScriptEngine)
|
||||
, _scriptScheduler(new scripting::ScriptScheduler)
|
||||
, _networkEngine(new NetworkEngine)
|
||||
, _syncEngine(std::make_unique<SyncEngine>(new SyncBuffer(4096)))
|
||||
, _syncEngine(std::make_unique<SyncEngine>(4096))
|
||||
, _commandlineParser(new ghoul::cmdparser::CommandlineParser(
|
||||
programName, ghoul::cmdparser::CommandlineParser::AllowUnknownCommands::Yes
|
||||
))
|
||||
@@ -139,7 +125,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName,
|
||||
, _downloadManager(nullptr)
|
||||
, _parallelConnection(new ParallelConnection)
|
||||
, _windowWrapper(std::move(windowWrapper))
|
||||
, _globalPropertyNamespace(new properties::PropertyOwner)
|
||||
, _globalPropertyNamespace(new properties::PropertyOwner(""))
|
||||
, _runTime(0.0)
|
||||
, _shutdown({false, 0.f, 0.f})
|
||||
, _isFirstRenderingFirstFrame(true)
|
||||
@@ -240,6 +226,8 @@ void OpenSpaceEngine::create(int argc, char** argv,
|
||||
LDEBUG("Creating OpenSpaceEngine");
|
||||
_engine = new OpenSpaceEngine(std::string(argv[0]), std::move(windowWrapper));
|
||||
|
||||
registerCoreClasses(DocEng);
|
||||
|
||||
// Query modules for commandline arguments
|
||||
_engine->gatherCommandlineArguments();
|
||||
|
||||
@@ -346,7 +334,6 @@ void OpenSpaceEngine::create(int argc, char** argv,
|
||||
// Register modules
|
||||
_engine->_moduleEngine->initialize();
|
||||
|
||||
registerCoreClasses(DocEng);
|
||||
// After registering the modules, the documentations for the available classes
|
||||
// can be added as well
|
||||
for (OpenSpaceModule* m : _engine->_moduleEngine->modules()) {
|
||||
@@ -451,9 +438,9 @@ void OpenSpaceEngine::initialize() {
|
||||
SysCap.logCapabilities(verbosity);
|
||||
|
||||
// Check the required OpenGL versions of the registered modules
|
||||
ghoul::systemcapabilities::OpenGLCapabilitiesComponent::Version version =
|
||||
ghoul::systemcapabilities::Version version =
|
||||
_engine->_moduleEngine->requiredOpenGLVersion();
|
||||
LINFO("Required OpenGL version: " << version.toString());
|
||||
LINFO("Required OpenGL version: " << std::to_string(version));
|
||||
|
||||
if (OpenGLCap.openGLVersion() < version) {
|
||||
throw ghoul::RuntimeError(
|
||||
@@ -848,7 +835,7 @@ void OpenSpaceEngine::preSynchronization() {
|
||||
|
||||
bool master = _windowWrapper->isMaster();
|
||||
|
||||
_syncEngine->presync(master);
|
||||
_syncEngine->preSynchronization(SyncEngine::IsMaster(master));
|
||||
if (master) {
|
||||
double dt = _windowWrapper->averageDeltaTime();
|
||||
_timeManager->preSynchronization(dt);
|
||||
@@ -880,7 +867,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() {
|
||||
LTRACE("OpenSpaceEngine::postSynchronizationPreDraw(begin)");
|
||||
|
||||
bool master = _windowWrapper->isMaster();
|
||||
_syncEngine->postsync(master);
|
||||
_syncEngine->postSynchronization(SyncEngine::IsMaster(master));
|
||||
|
||||
if (_shutdown.inShutdown) {
|
||||
if (_shutdown.timer <= 0.f) {
|
||||
@@ -943,8 +930,7 @@ void OpenSpaceEngine::render(const glm::mat4& viewMatrix,
|
||||
bool showGui = _windowWrapper->hasGuiWindow() ? _windowWrapper->isGuiWindow() : true;
|
||||
if (showGui && _windowWrapper->isMaster() && _windowWrapper->isRegularRendering()) {
|
||||
_renderEngine->renderScreenLog();
|
||||
if (_console->isVisible())
|
||||
_console->render();
|
||||
_console->render();
|
||||
}
|
||||
|
||||
if (_shutdown.inShutdown) {
|
||||
@@ -973,25 +959,18 @@ void OpenSpaceEngine::postDraw() {
|
||||
|
||||
void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction action) {
|
||||
for (const auto& func : _moduleCallbacks.keyboard) {
|
||||
bool consumed = func(key, mod, action);
|
||||
const bool consumed = func(key, mod, action);
|
||||
if (consumed) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// @CLEANUP: Remove the commandInputButton and replace with a method just based
|
||||
// on Lua by binding a key to the Lua script toggling the console ---abock
|
||||
if (key == _console->commandInputButton()) {
|
||||
if (action == KeyAction::Press) {
|
||||
_console->toggleMode();
|
||||
}
|
||||
} else if (!_console->isVisible()) {
|
||||
// @CLEANUP: Make the interaction handler return whether a key has been consumed
|
||||
// and then pass it on to the console ---abock
|
||||
_interactionHandler->keyboardCallback(key, mod, action);
|
||||
} else {
|
||||
_console->keyboardCallback(key, mod, action);
|
||||
|
||||
const bool consoleConsumed = _console->keyboardCallback(key, mod, action);
|
||||
if (consoleConsumed) {
|
||||
return;
|
||||
}
|
||||
|
||||
_interactionHandler->keyboardCallback(key, mod, action);
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier) {
|
||||
@@ -1002,9 +981,7 @@ void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier)
|
||||
}
|
||||
}
|
||||
|
||||
if (_console->isVisible()) {
|
||||
_console->charCallback(codepoint, modifier);
|
||||
}
|
||||
_console->charCallback(codepoint, modifier);
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::mouseButtonCallback(MouseButton button, MouseAction action) {
|
||||
|
||||
@@ -40,94 +40,40 @@
|
||||
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "SettingsEngine";
|
||||
const char* _loggerCat = "SettingsEngine";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
SettingsEngine::SettingsEngine()
|
||||
: _eyeSeparation("eyeSeparation", "Eye Separation" , 0.f, 0.f, 10.f)
|
||||
: properties::PropertyOwner("Global Properties")
|
||||
, _eyeSeparation("eyeSeparation", "Eye Separation", 0.f, 0.f, 10.f)
|
||||
, _scenes("scenes", "Scene", properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _busyWaitForDecode("busyWaitForDecode", "Busy Wait for decode", false)
|
||||
, _logSGCTOutOfOrderErrors("logSGCTOutOfOrderErrors", "Log SGCT out-of-order", false)
|
||||
, _useDoubleBuffering("useDoubleBuffering", "Use double buffering", false)
|
||||
, _spiceUseExceptions("enableSpiceExceptions", "Enable Spice Exceptions", false)
|
||||
{
|
||||
setName("Global Properties");
|
||||
|
||||
_spiceUseExceptions.onChange([this]{
|
||||
_spiceUseExceptions.onChange([this] {
|
||||
if (_spiceUseExceptions) {
|
||||
SpiceManager::ref().setExceptionHandling(SpiceManager::UseException::Yes);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SpiceManager::ref().setExceptionHandling(SpiceManager::UseException::No);
|
||||
}
|
||||
});
|
||||
addProperty(_spiceUseExceptions);
|
||||
addProperty(_eyeSeparation);
|
||||
addProperty(_busyWaitForDecode);
|
||||
addProperty(_logSGCTOutOfOrderErrors);
|
||||
addProperty(_useDoubleBuffering);
|
||||
addProperty(_scenes);
|
||||
}
|
||||
|
||||
void SettingsEngine::initialize() {
|
||||
initEyeSeparation();
|
||||
initSceneFiles();
|
||||
initBusyWaitForDecode();
|
||||
initLogSGCTOutOfOrderErrors();
|
||||
initUseDoubleBuffering();
|
||||
}
|
||||
|
||||
void SettingsEngine::setModules(std::vector<OpenSpaceModule*> modules) {
|
||||
for (OpenSpaceModule* m : modules) {
|
||||
addPropertySubOwner(m);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsEngine::initEyeSeparation() {
|
||||
addProperty(_eyeSeparation);
|
||||
|
||||
// Set interaction to change the window's (SGCT's) eye separation
|
||||
_eyeSeparation.onChange(
|
||||
[this]() { OsEng.windowWrapper().setEyeSeparationDistance(_eyeSeparation); });
|
||||
}
|
||||
|
||||
void SettingsEngine::initBusyWaitForDecode() {
|
||||
addProperty(_busyWaitForDecode);
|
||||
_busyWaitForDecode.onChange(
|
||||
[this]() {
|
||||
LINFO((_busyWaitForDecode.value() ? "Busy wait for decode" : "Async decode"));
|
||||
});
|
||||
}
|
||||
|
||||
bool SettingsEngine::busyWaitForDecode() {
|
||||
return _busyWaitForDecode.value();
|
||||
}
|
||||
|
||||
void SettingsEngine::initLogSGCTOutOfOrderErrors() {
|
||||
addProperty(_logSGCTOutOfOrderErrors);
|
||||
_logSGCTOutOfOrderErrors.onChange(
|
||||
[this]() {
|
||||
LINFO("Turn " << (_logSGCTOutOfOrderErrors.value() ? "on" : "off") << " SGCT out of order logging");
|
||||
});
|
||||
}
|
||||
|
||||
bool SettingsEngine::logSGCTOutOfOrderErrors() {
|
||||
return _logSGCTOutOfOrderErrors.value();
|
||||
}
|
||||
|
||||
|
||||
void SettingsEngine::initUseDoubleBuffering() {
|
||||
addProperty(_useDoubleBuffering);
|
||||
_useDoubleBuffering.onChange(
|
||||
[this]() {
|
||||
LINFO("Turn " << (_useDoubleBuffering.value() ? "on" : "off") << " double buffering");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bool SettingsEngine::useDoubleBuffering() {
|
||||
return _useDoubleBuffering.value();
|
||||
}
|
||||
|
||||
void SettingsEngine::initSceneFiles() {
|
||||
addProperty(_scenes);
|
||||
[this]() { OsEng.windowWrapper().setEyeSeparationDistance(_eyeSeparation); }
|
||||
);
|
||||
|
||||
// Load all matching files in the Scene
|
||||
// TODO: match regex with either with new ghoul readFiles or local code
|
||||
@@ -135,18 +81,36 @@ void SettingsEngine::initSceneFiles() {
|
||||
std::vector<std::string> scenes = ghoul::filesystem::Directory(sceneDir).readFiles();
|
||||
for (std::size_t i = 0; i < scenes.size(); ++i) {
|
||||
std::size_t found = scenes[i].find_last_of("/\\");
|
||||
_scenes.addOption(i, scenes[i].substr(found+1));
|
||||
_scenes.addOption(i, scenes[i].substr(found + 1));
|
||||
}
|
||||
|
||||
// Set interaction to change ConfigurationManager and schedule the load
|
||||
_scenes.onChange(
|
||||
[this]() {
|
||||
std::string sceneFile = _scenes.getDescriptionByValue(_scenes);
|
||||
OsEng.configurationManager().setValue(
|
||||
ConfigurationManager::KeyConfigScene, sceneFile);
|
||||
OsEng.renderEngine().scene()->scheduleLoadSceneFile(sceneFile);
|
||||
}
|
||||
std::string sceneFile = _scenes.getDescriptionByValue(_scenes);
|
||||
OsEng.configurationManager().setValue(
|
||||
ConfigurationManager::KeyConfigScene, sceneFile);
|
||||
OsEng.renderEngine().scene()->scheduleLoadSceneFile(sceneFile);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SettingsEngine::setModules(const std::vector<OpenSpaceModule*>& modules) {
|
||||
for (OpenSpaceModule* m : modules) {
|
||||
addPropertySubOwner(m);
|
||||
}
|
||||
}
|
||||
|
||||
bool SettingsEngine::busyWaitForDecode() {
|
||||
return _busyWaitForDecode.value();
|
||||
}
|
||||
|
||||
bool SettingsEngine::logSGCTOutOfOrderErrors() {
|
||||
return _logSGCTOutOfOrderErrors.value();
|
||||
}
|
||||
|
||||
bool SettingsEngine::useDoubleBuffering() {
|
||||
return _useDoubleBuffering.value();
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -23,73 +23,67 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/syncengine.h>
|
||||
|
||||
#include <openspace/util/syncdata.h>
|
||||
#include <openspace/util/syncbuffer.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <ghoul/misc/assert.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "SyncEngine";
|
||||
}
|
||||
|
||||
|
||||
namespace openspace {
|
||||
|
||||
SyncEngine::SyncEngine(SyncBuffer* syncBuffer)
|
||||
: _syncBuffer(syncBuffer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SyncEngine::presync(bool isMaster) {
|
||||
for (const auto& syncable : _syncables) {
|
||||
syncable->presync(isMaster);
|
||||
}
|
||||
}
|
||||
|
||||
// should be called on sgct master
|
||||
void SyncEngine::encodeSyncables() {
|
||||
for (const auto& syncable : _syncables) {
|
||||
syncable->encode(_syncBuffer.get());
|
||||
}
|
||||
_syncBuffer->write();
|
||||
}
|
||||
|
||||
//should be called on sgct slaves
|
||||
void SyncEngine::decodeSyncables() {
|
||||
_syncBuffer->read();
|
||||
for (const auto& syncable : _syncables) {
|
||||
syncable->decode(_syncBuffer.get());
|
||||
}
|
||||
}
|
||||
|
||||
void SyncEngine::postsync(bool isMaster) {
|
||||
for (const auto& syncable : _syncables) {
|
||||
syncable->postsync(isMaster);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SyncEngine::addSyncable(Syncable* syncable) {
|
||||
_syncables.push_back(syncable);
|
||||
}
|
||||
|
||||
void SyncEngine::addSyncables(const std::vector<Syncable*>& syncables) {
|
||||
for (const auto& syncable : syncables) {
|
||||
addSyncable(syncable);
|
||||
}
|
||||
}
|
||||
|
||||
void SyncEngine::removeSyncable(Syncable* syncable) {
|
||||
_syncables.erase(
|
||||
std::remove(_syncables.begin(), _syncables.end(), syncable),
|
||||
_syncables.end()
|
||||
);
|
||||
}
|
||||
|
||||
SyncEngine::SyncEngine(unsigned int syncBufferSize)
|
||||
: _syncBuffer(syncBufferSize)
|
||||
{
|
||||
ghoul_assert(syncBufferSize > 0, "syncBufferSize must be bigger than 0");
|
||||
}
|
||||
|
||||
// should be called on sgct master
|
||||
void SyncEngine::encodeSyncables() {
|
||||
for (Syncable* syncable : _syncables) {
|
||||
syncable->encode(&_syncBuffer);
|
||||
}
|
||||
_syncBuffer.write();
|
||||
}
|
||||
|
||||
//should be called on sgct slaves
|
||||
void SyncEngine::decodeSyncables() {
|
||||
_syncBuffer.read();
|
||||
for (Syncable* syncable : _syncables) {
|
||||
syncable->decode(&_syncBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void SyncEngine::preSynchronization(IsMaster isMaster) {
|
||||
for (Syncable* syncable : _syncables) {
|
||||
syncable->presync(isMaster);
|
||||
}
|
||||
}
|
||||
|
||||
void SyncEngine::postSynchronization(IsMaster isMaster) {
|
||||
for (Syncable* syncable : _syncables) {
|
||||
syncable->postsync(isMaster);
|
||||
}
|
||||
}
|
||||
|
||||
void SyncEngine::addSyncable(Syncable* syncable) {
|
||||
ghoul_assert(syncable, "synable must not be nullptr");
|
||||
|
||||
_syncables.push_back(syncable);
|
||||
}
|
||||
|
||||
void SyncEngine::addSyncables(const std::vector<Syncable*>& syncables) {
|
||||
for (Syncable* syncable : syncables) {
|
||||
ghoul_assert(syncable, "syncables must not contain any nullptr");
|
||||
addSyncable(syncable);
|
||||
}
|
||||
}
|
||||
|
||||
void SyncEngine::removeSyncable(Syncable* syncable) {
|
||||
_syncables.erase(
|
||||
std::remove(_syncables.begin(), _syncables.end(), syncable),
|
||||
_syncables.end()
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
// open space includes
|
||||
#include <openspace/interaction/deviceidentifier.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
|
||||
DeviceIdentifier* DeviceIdentifier::this_ = nullptr;
|
||||
|
||||
DeviceIdentifier::DeviceIdentifier() {
|
||||
|
||||
// scan for devices on init
|
||||
devices_ = 0;
|
||||
for(int i = 0; i < MAXDEVICES; ++i) {
|
||||
inputDevice_[i] = InputDevice::NONE;
|
||||
}
|
||||
}
|
||||
|
||||
DeviceIdentifier::~DeviceIdentifier() {
|
||||
|
||||
// deallocates memory on exit
|
||||
for(int i = 0; i < MAXDEVICES; ++i) {
|
||||
if(inputDevice_[i] != InputDevice::NONE) {
|
||||
delete axesPos_[i];
|
||||
delete buttons_[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceIdentifier::init() {
|
||||
assert( ! this_);
|
||||
this_ = new DeviceIdentifier();
|
||||
}
|
||||
|
||||
void DeviceIdentifier::deinit() {
|
||||
assert(this_);
|
||||
delete this_;
|
||||
this_ = nullptr;
|
||||
}
|
||||
|
||||
DeviceIdentifier& DeviceIdentifier::ref() {
|
||||
assert(this_);
|
||||
return *this_;
|
||||
}
|
||||
|
||||
bool DeviceIdentifier::isInitialized() {
|
||||
return this_ != nullptr;
|
||||
}
|
||||
|
||||
void DeviceIdentifier::scanDevices() {
|
||||
assert(this_);
|
||||
|
||||
// sgct/glfw supports 16 joysticks, scans all of them
|
||||
for (int i = 0; i < MAXDEVICES; ++i)
|
||||
{
|
||||
void* joystickName = NULL;
|
||||
if( joystickName != NULL ) {
|
||||
|
||||
// allocate
|
||||
axesPos_[i] = new float[numberOfAxes_[i]];
|
||||
buttons_[i] = new unsigned char[numberOfButtons_[i]];
|
||||
|
||||
// increment the device count
|
||||
++devices_;
|
||||
|
||||
// identify what device it is
|
||||
if(numberOfAxes_[i] == 6 && numberOfButtons_[i] == 10) {
|
||||
printf("XBOX controller ");
|
||||
inputDevice_[i] = InputDevice::XBOX;
|
||||
} else if(numberOfAxes_[i] == 6 && numberOfButtons_[i] == 4) {
|
||||
printf("SPACENAVIGATOR ");
|
||||
inputDevice_[i] = InputDevice::SPACENAVIGATOR;
|
||||
} else {
|
||||
printf("UNKNOWN device ");
|
||||
inputDevice_[i] = InputDevice::UNKNOWN;
|
||||
}
|
||||
printf("found at position %i, b=%i, a=%i\n", i, numberOfButtons_[i], numberOfAxes_[i]);
|
||||
|
||||
|
||||
} else {
|
||||
inputDevice_[i] = InputDevice::NONE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const int DeviceIdentifier::numberOfDevices() const {
|
||||
assert(this_);
|
||||
return devices_;
|
||||
}
|
||||
|
||||
const InputDevice DeviceIdentifier::type(const int device) const {
|
||||
assert(this_);
|
||||
return inputDevice_[device];
|
||||
}
|
||||
|
||||
void DeviceIdentifier::update() {
|
||||
assert(this_);
|
||||
for(int i = 0; i < devices_; ++i) {
|
||||
update(i);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceIdentifier::update(const int device) {
|
||||
assert(this_);
|
||||
if(inputDevice_[device] != InputDevice::NONE) {
|
||||
}
|
||||
}
|
||||
|
||||
const int DeviceIdentifier::getButtons(const int device, unsigned char **buttons) const {
|
||||
assert(this_);
|
||||
if(inputDevice_[device] != InputDevice::NONE) {
|
||||
if(buttons)
|
||||
*buttons = buttons_[device];
|
||||
return numberOfButtons_[device];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int DeviceIdentifier::getAxes(const int device, float **axespos) const {
|
||||
assert(this_);
|
||||
if(inputDevice_[device] != InputDevice::NONE) {
|
||||
if(axespos)
|
||||
*axespos = axesPos_[device];
|
||||
return numberOfAxes_[device];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DeviceIdentifier::get(const int device, unsigned char **buttons, float **axespos) const {
|
||||
assert(this_);
|
||||
if(inputDevice_[device] != InputDevice::NONE) {
|
||||
*axespos = axesPos_[device];
|
||||
*buttons = buttons_[device];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <openspace/interaction/interactionmode.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/keys.h>
|
||||
|
||||
@@ -50,19 +51,19 @@
|
||||
#include <fstream>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "InteractionHandler";
|
||||
const char* _loggerCat = "InteractionHandler";
|
||||
|
||||
const std::string KeyFocus = "Focus";
|
||||
const std::string KeyPosition = "Position";
|
||||
const std::string KeyRotation = "Rotation";
|
||||
const char* KeyFocus = "Focus";
|
||||
const char* KeyPosition = "Position";
|
||||
const char* KeyRotation = "Rotation";
|
||||
|
||||
const std::string MainTemplateFilename = "${OPENSPACE_DATA}/web/keybindings/main.hbs";
|
||||
const std::string KeybindingTemplateFilename = "${OPENSPACE_DATA}/web/keybindings/keybinding.hbs";
|
||||
const std::string HandlebarsFilename = "${OPENSPACE_DATA}/web/common/handlebars-v4.0.5.js";
|
||||
const std::string JsFilename = "${OPENSPACE_DATA}/web/keybindings/script.js";
|
||||
const std::string BootstrapFilename = "${OPENSPACE_DATA}/web/common/bootstrap.min.css";
|
||||
const std::string CssFilename = "${OPENSPACE_DATA}/web/common/style.css";
|
||||
}
|
||||
const char* MainTemplateFilename = "${OPENSPACE_DATA}/web/keybindings/main.hbs";
|
||||
const char* KeybindingTemplateFilename = "${OPENSPACE_DATA}/web/keybindings/keybinding.hbs";
|
||||
const char* HandlebarsFilename = "${OPENSPACE_DATA}/web/common/handlebars-v4.0.5.js";
|
||||
const char* JsFilename = "${OPENSPACE_DATA}/web/keybindings/script.js";
|
||||
const char* BootstrapFilename = "${OPENSPACE_DATA}/web/common/bootstrap.min.css";
|
||||
const char* CssFilename = "${OPENSPACE_DATA}/web/common/style.css";
|
||||
} // namespace
|
||||
|
||||
#include "interactionhandler_lua.inl"
|
||||
|
||||
@@ -71,15 +72,14 @@ namespace interaction {
|
||||
|
||||
// InteractionHandler
|
||||
InteractionHandler::InteractionHandler()
|
||||
: _origin("origin", "Origin", "")
|
||||
: properties::PropertyOwner("Interaction")
|
||||
, _origin("origin", "Origin", "")
|
||||
, _rotationalFriction("rotationalFriction", "Rotational Friction", true)
|
||||
, _horizontalFriction("horizontalFriction", "Horizontal Friction", true)
|
||||
, _verticalFriction("verticalFriction", "Vertical Friction", true)
|
||||
, _sensitivity("sensitivity", "Sensitivity", 0.5, 0.001, 1)
|
||||
, _rapidness("rapidness", "Rapidness", 1, 0.1, 60)
|
||||
{
|
||||
setName("Interaction");
|
||||
|
||||
_origin.onChange([this]() {
|
||||
SceneGraphNode* node = sceneGraphNode(_origin.value());
|
||||
if (!node) {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/keys.h>
|
||||
|
||||
|
||||
@@ -1,329 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/interaction/keyboardcontroller.h>
|
||||
|
||||
#include <openspace/interaction/interactionhandler.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/lua/ghoul_lua.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "KeyboardController";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
namespace interaction {
|
||||
|
||||
void KeyboardControllerFixed::keyPressed(KeyAction action, Key key, KeyModifier modifier) {
|
||||
// TODO package in script
|
||||
/*
|
||||
const float dt = static_cast<float>( _handler->deltaTime());
|
||||
if(action == KeyAction::Press|| action == KeyAction::Repeat) {
|
||||
const float speed = 2.75;
|
||||
if (key == Key::S) {
|
||||
glm::vec3 euler(speed * dt, 0.0, 0.0);
|
||||
glm::quat rot = glm::quat(euler);
|
||||
_handler->orbitDelta(rot);
|
||||
}
|
||||
if (key == Key::W) {
|
||||
glm::vec3 euler(-speed * dt, 0.0, 0.0);
|
||||
glm::quat rot = glm::quat(euler);
|
||||
_handler->orbitDelta(rot);
|
||||
}
|
||||
if (key == Key::A) {
|
||||
glm::vec3 euler(0.0, -speed * dt, 0.0);
|
||||
glm::quat rot = glm::quat(euler);
|
||||
_handler->orbitDelta(rot);
|
||||
}
|
||||
if (key == Key::D) {
|
||||
glm::vec3 euler(0.0, speed * dt, 0.0);
|
||||
glm::quat rot = glm::quat(euler);
|
||||
_handler->orbitDelta(rot);
|
||||
}
|
||||
if (key == Key::Q) {
|
||||
Time::ref().advanceTime(dt);
|
||||
}
|
||||
if (key == Key::Right) {
|
||||
glm::vec3 euler(0.0, speed * dt, 0.0);
|
||||
glm::quat rot = glm::quat(euler);
|
||||
_handler->rotateDelta(rot);
|
||||
}
|
||||
if (key == Key::Left) {
|
||||
glm::vec3 euler(0.0, -speed * dt, 0.0);
|
||||
glm::quat rot = glm::quat(euler);
|
||||
_handler->rotateDelta(rot);
|
||||
}
|
||||
if (key == Key::Down) {
|
||||
glm::vec3 euler(speed * dt, 0.0, 0.0);
|
||||
glm::quat rot = glm::quat(euler);
|
||||
_handler->rotateDelta(rot);
|
||||
}
|
||||
if (key == Key::Up) {
|
||||
glm::vec3 euler(-speed * dt, 0.0, 0.0);
|
||||
glm::quat rot = glm::quat(euler);
|
||||
_handler->rotateDelta(rot);
|
||||
}
|
||||
if (key == Key::R) {
|
||||
PowerScaledScalar dist(-speed * dt, 0.0);
|
||||
_handler->distanceDelta(dist);
|
||||
}
|
||||
if (key == Key::F) {
|
||||
PowerScaledScalar dist(speed * dt, 0.0);
|
||||
_handler->distanceDelta(dist);
|
||||
}
|
||||
if (key == Key::T) {
|
||||
PowerScaledScalar dist(-speed * pow(10.0f, 11.0f) * dt, 0.0f);
|
||||
_handler->distanceDelta(dist);
|
||||
}
|
||||
//if (key == Keys::G) {
|
||||
// acc += 0.001;
|
||||
// PowerScaledScalar dist(speed * pow(10, 8 * acc) * dt, 0.0);
|
||||
// distanceDelta(dist);
|
||||
//}
|
||||
if (key == Key::Y) {
|
||||
PowerScaledScalar dist(-speed * 100.0f * dt, 6.0f);
|
||||
_handler->distanceDelta(dist);
|
||||
}
|
||||
if (key == Key::H) {
|
||||
PowerScaledScalar dist(speed * 100.0f * dt, 6.0f);
|
||||
_handler->distanceDelta(dist);
|
||||
}
|
||||
|
||||
if (key == Key::KeypadSubtract) {
|
||||
glm::vec2 s = OsEng.renderEngine().camera()->scaling();
|
||||
s[1] -= 0.5;
|
||||
OsEng.renderEngine().camera()->setScaling(s);
|
||||
}
|
||||
if (key == Key::KeypadAdd) {
|
||||
glm::vec2 s = OsEng.renderEngine().camera()->scaling();
|
||||
s[1] += 0.5;
|
||||
OsEng.renderEngine().camera()->setScaling(s);
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if (key == '1') {
|
||||
SceneGraphNode* node = getSceneGraphNode("sun");
|
||||
|
||||
setFocusNode(node);
|
||||
getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 10.0));
|
||||
getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0));
|
||||
}
|
||||
|
||||
if (key == '2') {
|
||||
SceneGraphNode* node = getSceneGraphNode("earth");
|
||||
|
||||
setFocusNode(node);
|
||||
getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 1.0, 8.0));
|
||||
getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0));
|
||||
}
|
||||
|
||||
|
||||
if (key == '3') {
|
||||
SceneGraphNode* node = getSceneGraphNode("moon");
|
||||
|
||||
setFocusNode(node);
|
||||
getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 8.0));
|
||||
getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void KeyboardControllerLua::keyPressed(KeyAction action, Key key, KeyModifier modifier) {
|
||||
lua_State* s = luaL_newstate();
|
||||
luaL_openlibs(s);
|
||||
|
||||
int status = luaL_loadfile(s, absPath("${SCRIPTS}/default_keybinding.lua").c_str());
|
||||
if (status != LUA_OK) {
|
||||
LERROR("Error loading script: '" << lua_tostring(s, -1) << "'");
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_pcall(s, 0, LUA_MULTRET, 0)) {
|
||||
LERROR("Error executing script: " << lua_tostring(s, -1));
|
||||
return;
|
||||
}
|
||||
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
lua_getfield(s, -1, keyToString(key, modifier).c_str());
|
||||
if (!lua_isnil(s, -1))
|
||||
lua_pcall(s, 0, 0, 0);
|
||||
else
|
||||
LINFO("Key not found");
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
LINFO("Keyboard timing: " << std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() << "ns");
|
||||
|
||||
|
||||
}
|
||||
|
||||
std::string KeyboardControllerLua::keyToString(Key key, KeyModifier mod) const {
|
||||
std::string result = "";
|
||||
int intMod = static_cast<int>(mod);
|
||||
if (intMod & static_cast<int>(KeyModifier::Control))
|
||||
result += "CTRL + ";
|
||||
if (intMod & static_cast<int>(KeyModifier::Super))
|
||||
result += "SUPER + ";
|
||||
if (intMod & static_cast<int>(KeyModifier::Alt))
|
||||
result += "ALT + ";
|
||||
if (intMod & static_cast<int>(KeyModifier::Shift))
|
||||
result += "SHIFT + ";
|
||||
|
||||
switch (key) {
|
||||
case Key::Unknown: result += "Unknown"; break;
|
||||
case Key::Space: result += "Space"; break;
|
||||
case Key::Apostrophe: result += "Apostrophe"; break;
|
||||
case Key::Comma: result += "Comma"; break;
|
||||
case Key::Minus: result += "Minus"; break;
|
||||
case Key::Period: result += "Period"; break;
|
||||
case Key::Slash: result += "Slash"; break;
|
||||
case Key::Num0: result += "0"; break;
|
||||
case Key::Num1: result += "1"; break;
|
||||
case Key::Num2: result += "2"; break;
|
||||
case Key::Num3: result += "3"; break;
|
||||
case Key::Num4: result += "4"; break;
|
||||
case Key::Num5: result += "5"; break;
|
||||
case Key::Num6: result += "6"; break;
|
||||
case Key::Num7: result += "7"; break;
|
||||
case Key::Num8: result += "8"; break;
|
||||
case Key::Num9: result += "9"; break;
|
||||
case Key::SemiColon: result += "SemiColon"; break;
|
||||
case Key::Equal: result += "Equal"; break;
|
||||
case Key::A: result += "A"; break;
|
||||
case Key::B: result += "B"; break;
|
||||
case Key::C: result += "C"; break;
|
||||
case Key::D: result += "D"; break;
|
||||
case Key::E: result += "E"; break;
|
||||
case Key::F: result += "F"; break;
|
||||
case Key::G: result += "G"; break;
|
||||
case Key::H: result += "H"; break;
|
||||
case Key::I: result += "I"; break;
|
||||
case Key::J: result += "J"; break;
|
||||
case Key::K: result += "K"; break;
|
||||
case Key::L: result += "L"; break;
|
||||
case Key::M: result += "M"; break;
|
||||
case Key::N: result += "N"; break;
|
||||
case Key::O: result += "O"; break;
|
||||
case Key::P: result += "P"; break;
|
||||
case Key::Q: result += "Q"; break;
|
||||
case Key::R: result += "R"; break;
|
||||
case Key::S: result += "S"; break;
|
||||
case Key::T: result += "T"; break;
|
||||
case Key::U: result += "U"; break;
|
||||
case Key::V: result += "V"; break;
|
||||
case Key::W: result += "W"; break;
|
||||
case Key::X: result += "X"; break;
|
||||
case Key::Y: result += "Y"; break;
|
||||
case Key::Z: result += "Z"; break;
|
||||
case Key::LeftBracket: result += "LeftBracket"; break;
|
||||
case Key::BackSlash: result += "BackSlash"; break;
|
||||
case Key::RightBracket: result += "RightBracket"; break;
|
||||
case Key::GraveAccent: result += "GraveAccent"; break;
|
||||
case Key::World1: result += "World1"; break;
|
||||
case Key::World2: result += "World2"; break;
|
||||
case Key::Escape: result += "Escape"; break;
|
||||
case Key::Enter: result += "Enter"; break;
|
||||
case Key::Tab: result += "Tab"; break;
|
||||
case Key::BackSpace: result += "BackSpace"; break;
|
||||
case Key::Insert: result += "Insert"; break;
|
||||
case Key::Delete: result += "Delete"; break;
|
||||
case Key::Right: result += "Right"; break;
|
||||
case Key::Left: result += "Left"; break;
|
||||
case Key::Down: result += "Down"; break;
|
||||
case Key::Up: result += "Up"; break;
|
||||
case Key::PageUp: result += "PageUp"; break;
|
||||
case Key::PageDown: result += "PageDown"; break;
|
||||
case Key::Home: result += "Home"; break;
|
||||
case Key::End: result += "End"; break;
|
||||
case Key::CapsLock: result += "CapsLock"; break;
|
||||
case Key::ScrollLock: result += "ScrollLock"; break;
|
||||
case Key::NumLock: result += "NumLock"; break;
|
||||
case Key::PrintScreen: result += "PrintScreen"; break;
|
||||
case Key::Pause: result += "Pause"; break;
|
||||
case Key::F1: result += "F1"; break;
|
||||
case Key::F2: result += "F2"; break;
|
||||
case Key::F3: result += "F3"; break;
|
||||
case Key::F4: result += "F4"; break;
|
||||
case Key::F5: result += "F5"; break;
|
||||
case Key::F6: result += "F6"; break;
|
||||
case Key::F7: result += "F7"; break;
|
||||
case Key::F8: result += "F8"; break;
|
||||
case Key::F9: result += "F9"; break;
|
||||
case Key::F10: result += "F10"; break;
|
||||
case Key::F11: result += "F11"; break;
|
||||
case Key::F12: result += "F12"; break;
|
||||
case Key::F13: result += "F13"; break;
|
||||
case Key::F14: result += "F14"; break;
|
||||
case Key::F15: result += "F15"; break;
|
||||
case Key::F16: result += "F16"; break;
|
||||
case Key::F17: result += "F17"; break;
|
||||
case Key::F18: result += "F18"; break;
|
||||
case Key::F19: result += "F19"; break;
|
||||
case Key::F20: result += "F20"; break;
|
||||
case Key::F21: result += "F21"; break;
|
||||
case Key::F22: result += "F22"; break;
|
||||
case Key::F23: result += "F23"; break;
|
||||
case Key::F24: result += "F24"; break;
|
||||
case Key::F25: result += "F25"; break;
|
||||
case Key::Keypad0: result += "Keypad0"; break;
|
||||
case Key::Keypad1: result += "Keypad1"; break;
|
||||
case Key::Keypad2: result += "Keypad2"; break;
|
||||
case Key::Keypad3: result += "Keypad3"; break;
|
||||
case Key::Keypad4: result += "Keypad4"; break;
|
||||
case Key::Keypad5: result += "Keypad5"; break;
|
||||
case Key::Keypad6: result += "Keypad6"; break;
|
||||
case Key::Keypad7: result += "Keypad7"; break;
|
||||
case Key::Keypad8: result += "Keypad8"; break;
|
||||
case Key::Keypad9: result += "Keypad9"; break;
|
||||
case Key::KeypadDecimal: result += "KeypadDecimal"; break;
|
||||
case Key::KeypadDivide: result += "KeypadDivide"; break;
|
||||
case Key::KeypadMultiply: result += "KeypadMultiply"; break;
|
||||
case Key::KeypadSubtract: result += "KeypadSubtract"; break;
|
||||
case Key::KeypadAdd: result += "KeypadAdd"; break;
|
||||
case Key::KeypadEnter: result += "KeypadEnter"; break;
|
||||
case Key::LeftShift: result += "LeftShift"; break;
|
||||
case Key::LeftControl: result += "LeftControl"; break;
|
||||
case Key::LeftAlt: result += "LeftAlt"; break;
|
||||
case Key::LeftSuper: result += "LeftSuper"; break;
|
||||
case Key::RightShift: result += "RightShift"; break;
|
||||
case Key::RightControl: result += "RightControl"; break;
|
||||
case Key::RightAlt: result += "RightAlt"; break;
|
||||
case Key::RightSuper: result += "RightSuper"; break;
|
||||
case Key::Menu: result += "Menu"; break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace interaction
|
||||
} // namespace openspace
|
||||
@@ -24,280 +24,350 @@
|
||||
|
||||
#include <openspace/interaction/luaconsole.h>
|
||||
|
||||
#include <openspace/network/parallelconnection.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/wrapper/windowwrapper.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/clipboard.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/font/font.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
#include <ghoul/misc/clipboard.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "LuaConsole";
|
||||
const std::string historyFile = "ConsoleHistory";
|
||||
const char* HistoryFile = "ConsoleHistory";
|
||||
|
||||
const int NoAutoComplete = -1;
|
||||
}
|
||||
|
||||
#include "luaconsole_lua.inl"
|
||||
const openspace::Key CommandInputButton = openspace::Key::GraveAccent;
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
LuaConsole::LuaConsole()
|
||||
: _inputPosition(0)
|
||||
, _activeCommand(0)
|
||||
, _filename("")
|
||||
, _autoCompleteInfo({NoAutoComplete, false, ""})
|
||||
, _isVisible(false)
|
||||
LuaConsole::LuaConsole()
|
||||
: properties::PropertyOwner("LuaConsole")
|
||||
, _isVisible("isVisible", "Is Visible", false)
|
||||
, _remoteScripting(true)
|
||||
, _inputPosition(0)
|
||||
, _activeCommand(0)
|
||||
, _autoCompleteInfo({NoAutoComplete, false, ""})
|
||||
{
|
||||
// _commands.push_back("");
|
||||
// _activeCommand = _commands.size() - 1;
|
||||
_isVisible.onChange([this](){
|
||||
if (_isVisible) {
|
||||
_remoteScripting = false;
|
||||
} else {
|
||||
_remoteScripting = OsEng.parallelConnection().isHost();
|
||||
}
|
||||
});
|
||||
addProperty(_isVisible);
|
||||
}
|
||||
|
||||
void LuaConsole::initialize() {
|
||||
_filename = FileSys.cacheManager()->cachedFilename(
|
||||
historyFile,
|
||||
std::string filename = FileSys.cacheManager()->cachedFilename(
|
||||
HistoryFile,
|
||||
"",
|
||||
ghoul::filesystem::CacheManager::Persistent::Yes
|
||||
);
|
||||
|
||||
std::ifstream file(_filename, std::ios::binary | std::ios::in);
|
||||
if (file.good()) {
|
||||
int64_t nCommands;
|
||||
file.read(reinterpret_cast<char*>(&nCommands), sizeof(int64_t));
|
||||
std::ifstream file;
|
||||
file.exceptions(~std::ofstream::goodbit);
|
||||
file.open(filename, std::ios::binary | std::ios::in);
|
||||
|
||||
std::vector<char> tmp;
|
||||
for (int64_t i = 0; i < nCommands; ++i) {
|
||||
int64_t length;
|
||||
file.read(reinterpret_cast<char*>(&length), sizeof(int64_t));
|
||||
tmp.resize(length + 1);
|
||||
file.read(tmp.data(), length);
|
||||
tmp[length] = '\0';
|
||||
_commandsHistory.emplace_back(std::string(tmp.begin(), tmp.end()));
|
||||
}
|
||||
file.close();
|
||||
_commands = _commandsHistory;
|
||||
// Read the number of commands from the history
|
||||
int64_t nCommands;
|
||||
file.read(reinterpret_cast<char*>(&nCommands), sizeof(int64_t));
|
||||
|
||||
for (int64_t i = 0; i < nCommands; ++i) {
|
||||
int64_t length;
|
||||
file.read(reinterpret_cast<char*>(&length), sizeof(int64_t));
|
||||
|
||||
std::vector<char> tmp(length + 1);
|
||||
file.read(tmp.data(), length);
|
||||
tmp[length] = '\0';
|
||||
_commandsHistory.emplace_back(std::string(tmp.begin(), tmp.end()));
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
_commands = _commandsHistory;
|
||||
_commands.push_back("");
|
||||
_activeCommand = _commands.size() - 1;
|
||||
|
||||
OsEng.parallelConnection().connectionEvent()->subscribe("luaConsole",
|
||||
"statusChanged", [this]() {
|
||||
ParallelConnection::Status status = OsEng.parallelConnection().status();
|
||||
parallelConnectionChanged(status);
|
||||
});
|
||||
|
||||
OsEng.parallelConnection().connectionEvent()->subscribe(
|
||||
"luaConsole",
|
||||
"statusChanged",
|
||||
[this]() {
|
||||
ParallelConnection::Status status = OsEng.parallelConnection().status();
|
||||
parallelConnectionChanged(status);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void LuaConsole::deinitialize() {
|
||||
std::ofstream file(_filename, std::ios::binary | std::ios::out);
|
||||
if (file.good()) {
|
||||
int64_t nCommands = _commandsHistory.size();
|
||||
file.write(reinterpret_cast<const char*>(&nCommands), sizeof(int64_t));
|
||||
for (const std::string& s : _commandsHistory) {
|
||||
int64_t length = s.length();
|
||||
file.write(reinterpret_cast<const char*>(&length), sizeof(int64_t));
|
||||
file.write(s.c_str(), length);
|
||||
}
|
||||
std::string filename = FileSys.cacheManager()->cachedFilename(
|
||||
HistoryFile,
|
||||
"",
|
||||
ghoul::filesystem::CacheManager::Persistent::Yes
|
||||
);
|
||||
|
||||
std::ofstream file;
|
||||
file.exceptions(~std::ofstream::goodbit);
|
||||
file.open(filename, std::ios::binary | std::ios::in);
|
||||
|
||||
int64_t nCommands = _commandsHistory.size();
|
||||
file.write(reinterpret_cast<const char*>(&nCommands), sizeof(int64_t));
|
||||
|
||||
for (const std::string& s : _commandsHistory) {
|
||||
int64_t length = s.length();
|
||||
file.write(reinterpret_cast<const char*>(&length), sizeof(int64_t));
|
||||
// We don't write the \0 at the end on purpose
|
||||
file.write(s.c_str(), length);
|
||||
}
|
||||
|
||||
OsEng.parallelConnection().connectionEvent()->unsubscribe("luaConsole");
|
||||
}
|
||||
|
||||
void LuaConsole::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) {
|
||||
if (action == KeyAction::Press || action == KeyAction::Repeat) {
|
||||
const bool modifierControl = (modifier == KeyModifier::Control);
|
||||
const bool modifierShift = (modifier == KeyModifier::Shift);
|
||||
bool LuaConsole::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) {
|
||||
if (action != KeyAction::Press && action != KeyAction::Repeat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Paste from clipboard
|
||||
if (modifierControl && (key == Key::V))
|
||||
addToCommand(ghoul::clipboardText());
|
||||
if (key == CommandInputButton) {
|
||||
// Button left of 1 and above TAB
|
||||
// How to deal with different keyboard languages? ---abock
|
||||
_isVisible = !_isVisible;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copy to clipboard
|
||||
if (modifierControl && (key == Key::C))
|
||||
ghoul::setClipboardText(_commands.at(_activeCommand));
|
||||
if (!_isVisible) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Go to the previous character
|
||||
if ((key == Key::Left) && (_inputPosition > 0))
|
||||
const bool modifierControl = (modifier == KeyModifier::Control);
|
||||
const bool modifierShift = (modifier == KeyModifier::Shift);
|
||||
|
||||
// Paste from clipboard
|
||||
if (modifierControl && (key == Key::V)) {
|
||||
addToCommand(ghoul::clipboardText());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copy to clipboard
|
||||
if (modifierControl && (key == Key::C)) {
|
||||
ghoul::setClipboardText(_commands.at(_activeCommand));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Go to the previous character
|
||||
if ((key == Key::Left) && (_inputPosition > 0)) {
|
||||
--_inputPosition;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Go to the next character
|
||||
if (key == Key::Right) {
|
||||
//&& _inputPosition < _commands.at(_activeCommand).length())
|
||||
//++_inputPosition;
|
||||
_inputPosition = std::min(
|
||||
_inputPosition + 1,
|
||||
_commands.at(_activeCommand).length()
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Go to previous command
|
||||
if (key == Key::Up) {
|
||||
if (_activeCommand > 0) {
|
||||
--_activeCommand;
|
||||
}
|
||||
_inputPosition = _commands.at(_activeCommand).length();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Go to next command (the last is empty)
|
||||
if (key == Key::Down) {
|
||||
if (_activeCommand < _commands.size() - 1) {
|
||||
++_activeCommand;
|
||||
}
|
||||
_inputPosition = _commands.at(_activeCommand).length();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Remove character before _inputPosition
|
||||
if (key == Key::BackSpace) {
|
||||
if (_inputPosition > 0) {
|
||||
_commands.at(_activeCommand).erase(_inputPosition - 1, 1);
|
||||
--_inputPosition;
|
||||
|
||||
// Go to the next character
|
||||
if ((key == Key::Right) && _inputPosition < _commands.at(_activeCommand).length())
|
||||
++_inputPosition;
|
||||
|
||||
// Go to previous command
|
||||
if (key == Key::Up) {
|
||||
if (_activeCommand > 0)
|
||||
--_activeCommand;
|
||||
_inputPosition = _commands.at(_activeCommand).length();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Go to next command (the last is empty)
|
||||
if (key == Key::Down) {
|
||||
if (_activeCommand < _commands.size() - 1)
|
||||
++_activeCommand;
|
||||
_inputPosition = _commands.at(_activeCommand).length();
|
||||
}
|
||||
|
||||
// Remove character before _inputPosition
|
||||
if (key == Key::BackSpace) {
|
||||
if (_inputPosition > 0) {
|
||||
_commands.at(_activeCommand).erase(_inputPosition - 1, 1);
|
||||
--_inputPosition;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove character after _inputPosition
|
||||
if (key == Key::Delete) {
|
||||
if (_inputPosition <= _commands.at(_activeCommand).size())
|
||||
_commands.at(_activeCommand).erase(_inputPosition, 1);
|
||||
// Remove character after _inputPosition
|
||||
if (key == Key::Delete) {
|
||||
if (_inputPosition <= _commands.at(_activeCommand).size()) {
|
||||
_commands.at(_activeCommand).erase(_inputPosition, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Go to the beginning of command string
|
||||
if (key == Key::Home)
|
||||
_inputPosition = 0;
|
||||
// Go to the beginning of command string
|
||||
if (key == Key::Home) {
|
||||
_inputPosition = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Go to the end of command string
|
||||
if (key == Key::End)
|
||||
_inputPosition = _commands.at(_activeCommand).size();
|
||||
// Go to the end of command string
|
||||
if (key == Key::End) {
|
||||
_inputPosition = _commands.at(_activeCommand).size();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == Key::Enter) {
|
||||
// SHIFT+ENTER == new line
|
||||
if (modifierShift)
|
||||
addToCommand("\n");
|
||||
// ENTER == run lua script
|
||||
else {
|
||||
std::string cmd = _commands.at(_activeCommand);
|
||||
if (cmd != "") {
|
||||
OsEng.scriptEngine().queueScript(cmd,
|
||||
_remoteScripting ? scripting::ScriptEngine::RemoteScripting::Yes : scripting::ScriptEngine::RemoteScripting::No);
|
||||
if (key == Key::Enter) {
|
||||
// SHIFT+ENTER == new line
|
||||
if (modifierShift) {
|
||||
addToCommand("\n");
|
||||
}
|
||||
// ENTER == run lua script
|
||||
else {
|
||||
std::string cmd = _commands.at(_activeCommand);
|
||||
if (cmd != "") {
|
||||
using RemoteScripting = scripting::ScriptEngine::RemoteScripting;
|
||||
OsEng.scriptEngine().queueScript(
|
||||
cmd,
|
||||
_remoteScripting ? RemoteScripting::Yes : RemoteScripting::No
|
||||
);
|
||||
|
||||
// Only add the current command to the history if it hasn't been
|
||||
// executed before. We don't want two of the same commands in a row
|
||||
if (_commandsHistory.empty() || (cmd != _commandsHistory.back()))
|
||||
_commandsHistory.push_back(_commands.at(_activeCommand));
|
||||
// Only add the current command to the history if it hasn't been
|
||||
// executed before. We don't want two of the same commands in a row
|
||||
if (_commandsHistory.empty() || (cmd != _commandsHistory.back())) {
|
||||
_commandsHistory.push_back(_commands.at(_activeCommand));
|
||||
}
|
||||
|
||||
// Some clean up after the execution of the command
|
||||
_commands = _commandsHistory;
|
||||
_commands.push_back("");
|
||||
_activeCommand = _commands.size() - 1;
|
||||
_inputPosition = 0;
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
// Some clean up after the execution of the command
|
||||
_commands = _commandsHistory;
|
||||
_commands.push_back("");
|
||||
_activeCommand = _commands.size() - 1;
|
||||
_inputPosition = 0;
|
||||
_isVisible = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == Key::Tab) {
|
||||
// We get a list of all the available commands and initially find the first
|
||||
// command that starts with how much we typed sofar. We store the index so
|
||||
// that in subsequent "tab" presses, we will discard previous commands. This
|
||||
// implements the 'hop-over' behavior. As soon as another key is pressed,
|
||||
// everything is set back to normal
|
||||
|
||||
// If the shift key is pressed, we decrement the current index so that we will
|
||||
// find the value before the one that was previously found
|
||||
if (_autoCompleteInfo.lastIndex != NoAutoComplete && modifierShift) {
|
||||
_autoCompleteInfo.lastIndex -= 2;
|
||||
}
|
||||
std::vector<std::string> allCommands = OsEng.scriptEngine().allLuaFunctions();
|
||||
std::sort(allCommands.begin(), allCommands.end());
|
||||
|
||||
std::string currentCommand = _commands.at(_activeCommand);
|
||||
|
||||
// Check if it is the first time the tab has been pressed. If so, we need to
|
||||
// store the already entered command so that we can later start the search
|
||||
// from there. We will overwrite the 'currentCommand' thus making the storage
|
||||
// necessary
|
||||
if (!_autoCompleteInfo.hasInitialValue) {
|
||||
_autoCompleteInfo.initialValue = currentCommand;
|
||||
_autoCompleteInfo.hasInitialValue = true;
|
||||
}
|
||||
|
||||
if (key == Key::Tab) {
|
||||
// We get a list of all the available commands and initially find the first
|
||||
// command that starts with how much we typed sofar. We store the index so
|
||||
// that in subsequent "tab" presses, we will discard previous commands. This
|
||||
// implements the 'hop-over' behavior. As soon as another key is pressed,
|
||||
// everything is set back to normal
|
||||
for (int i = 0; i < static_cast<int>(allCommands.size()); ++i) {
|
||||
const std::string& command = allCommands[i];
|
||||
|
||||
// If the shift key is pressed, we decrement the current index so that we will
|
||||
// find the value before the one that was previously found
|
||||
if (_autoCompleteInfo.lastIndex != NoAutoComplete && modifierShift)
|
||||
_autoCompleteInfo.lastIndex -= 2;
|
||||
std::vector<std::string> allCommands = OsEng.scriptEngine().allLuaFunctions();
|
||||
std::sort(allCommands.begin(), allCommands.end());
|
||||
// Check if the command has enough length (we don't want crashes here)
|
||||
// Then check if the iterator-command's start is equal to what we want
|
||||
// then check if we need to skip the first found values as the user has
|
||||
// pressed TAB repeatedly
|
||||
size_t fullLength = _autoCompleteInfo.initialValue.length();
|
||||
bool correctLength = command.length() >= fullLength;
|
||||
|
||||
std::string currentCommand = _commands.at(_activeCommand);
|
||||
|
||||
// Check if it is the first time the tab has been pressed. If so, we need to
|
||||
// store the already entered command so that we can later start the search
|
||||
// from there. We will overwrite the 'currentCommand' thus making the storage
|
||||
// necessary
|
||||
if (!_autoCompleteInfo.hasInitialValue) {
|
||||
_autoCompleteInfo.initialValue = currentCommand;
|
||||
_autoCompleteInfo.hasInitialValue = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < static_cast<int>(allCommands.size()); ++i) {
|
||||
const std::string& command = allCommands[i];
|
||||
|
||||
// Check if the command has enough length (we don't want crashes here)
|
||||
// Then check if the iterator-command's start is equal to what we want
|
||||
// then check if we need to skip the first found values as the user has
|
||||
// pressed TAB repeatedly
|
||||
size_t fullLength = _autoCompleteInfo.initialValue.length();
|
||||
bool correctLength = command.length() >= fullLength;
|
||||
|
||||
std::string commandLowerCase;
|
||||
std::transform(
|
||||
command.begin(), command.end(),
|
||||
std::back_inserter(commandLowerCase),
|
||||
::tolower
|
||||
);
|
||||
std::string commandLowerCase;
|
||||
std::transform(
|
||||
command.begin(), command.end(),
|
||||
std::back_inserter(commandLowerCase),
|
||||
::tolower
|
||||
);
|
||||
|
||||
std::string initialValueLowerCase;
|
||||
std::transform(
|
||||
_autoCompleteInfo.initialValue.begin(),
|
||||
_autoCompleteInfo.initialValue.end(),
|
||||
std::back_inserter(initialValueLowerCase),
|
||||
::tolower
|
||||
);
|
||||
std::string initialValueLowerCase;
|
||||
std::transform(
|
||||
_autoCompleteInfo.initialValue.begin(),
|
||||
_autoCompleteInfo.initialValue.end(),
|
||||
std::back_inserter(initialValueLowerCase),
|
||||
::tolower
|
||||
);
|
||||
|
||||
bool correctCommand =
|
||||
commandLowerCase.substr(0, fullLength) == initialValueLowerCase;
|
||||
bool correctCommand =
|
||||
commandLowerCase.substr(0, fullLength) == initialValueLowerCase;
|
||||
|
||||
if (correctLength && correctCommand && (i > _autoCompleteInfo.lastIndex)){
|
||||
// We found our index, so store it
|
||||
_autoCompleteInfo.lastIndex = i;
|
||||
if (correctLength && correctCommand && (i > _autoCompleteInfo.lastIndex)){
|
||||
// We found our index, so store it
|
||||
_autoCompleteInfo.lastIndex = i;
|
||||
|
||||
// We only want to auto-complete until the next separator "."
|
||||
size_t pos = command.find('.', fullLength);
|
||||
if (pos == std::string::npos) {
|
||||
// If we don't find a separator, we autocomplete until the end
|
||||
// Set the found command as active command
|
||||
_commands.at(_activeCommand) = command + "();";
|
||||
// Set the cursor position to be between the brackets
|
||||
_inputPosition = _commands.at(_activeCommand).size() - 2;
|
||||
// We only want to auto-complete until the next separator "."
|
||||
size_t pos = command.find('.', fullLength);
|
||||
if (pos == std::string::npos) {
|
||||
// If we don't find a separator, we autocomplete until the end
|
||||
// Set the found command as active command
|
||||
_commands.at(_activeCommand) = command + "();";
|
||||
// Set the cursor position to be between the brackets
|
||||
_inputPosition = _commands.at(_activeCommand).size() - 2;
|
||||
}
|
||||
else {
|
||||
// If we find a separator, we autocomplete until and including the
|
||||
// separator unless the autocompletion would be the same that we
|
||||
// already have (the case if there are multiple commands in the
|
||||
// same group
|
||||
std::string subCommand = command.substr(0, pos + 1);
|
||||
if (subCommand == _commands.at(_activeCommand)) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// If we find a separator, we autocomplete until and including the
|
||||
// separator unless the autocompletion would be the same that we
|
||||
// already have (the case if there are multiple commands in the
|
||||
// same group
|
||||
std::string subCommand = command.substr(0, pos + 1);
|
||||
if (subCommand == _commands.at(_activeCommand))
|
||||
continue;
|
||||
else {
|
||||
_commands.at(_activeCommand) = command.substr(0, pos + 1);
|
||||
_inputPosition = _commands.at(_activeCommand).length();
|
||||
// We only want to remove the autocomplete info if we just
|
||||
// entered the 'default' openspace namespace
|
||||
if (command.substr(0, pos + 1) == "openspace.")
|
||||
_autoCompleteInfo = { NoAutoComplete, false, "" };
|
||||
_commands.at(_activeCommand) = command.substr(0, pos + 1);
|
||||
_inputPosition = _commands.at(_activeCommand).length();
|
||||
// We only want to remove the autocomplete info if we just
|
||||
// entered the 'default' openspace namespace
|
||||
if (command.substr(0, pos + 1) == "openspace.") {
|
||||
_autoCompleteInfo = { NoAutoComplete, false, "" };
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If any other key is pressed, we want to remove our previous findings
|
||||
// The special case for Shift is necessary as we want to allow Shift+TAB
|
||||
if (!modifierShift)
|
||||
_autoCompleteInfo = { NoAutoComplete, false, ""};
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// If any other key is pressed, we want to remove our previous findings
|
||||
// The special case for Shift is necessary as we want to allow Shift+TAB
|
||||
if (!modifierShift) {
|
||||
_autoCompleteInfo = { NoAutoComplete, false, "" };
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LuaConsole::charCallback(unsigned int codepoint, KeyModifier modifier) {
|
||||
if (codepoint == static_cast<unsigned int>(commandInputButton()))
|
||||
if (!_isVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (codepoint == static_cast<unsigned int>(CommandInputButton)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
const bool modifierControl = (modifier == KeyModifier::Control);
|
||||
@@ -308,50 +378,84 @@ void LuaConsole::charCallback(unsigned int codepoint, KeyModifier modifier) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
addToCommand(UnicodeToUTF8(codepoint));
|
||||
|
||||
// Disallow all non ASCII characters for now
|
||||
if (codepoint > 0x7f) {
|
||||
return;
|
||||
}
|
||||
|
||||
addToCommand(std::string(1, codepoint));
|
||||
}
|
||||
|
||||
void LuaConsole::render() {
|
||||
const float font_size = 10.0f;
|
||||
|
||||
int ySize = OsEng.renderEngine().fontResolution().y;
|
||||
//int ySize = OsEng.windowWrapper().currentWindowSize().y;
|
||||
//int ySize = OsEng.windowWrapper().viewportPixelCoordinates().w;
|
||||
const float FontSize = 10.0f;
|
||||
|
||||
float startY = static_cast<float>(ySize) - 2.0f * font_size;
|
||||
startY = startY - font_size * 15.0f * 2.0f;
|
||||
if (!_isVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int ySize = OsEng.renderEngine().fontResolution().y;
|
||||
|
||||
const float startY =
|
||||
static_cast<float>(ySize) - 2.0f * FontSize - FontSize * 15.0f * 2.0f;;
|
||||
|
||||
const glm::vec4 red(1, 0, 0, 1);
|
||||
const glm::vec4 lightBlue(0.4, 0.4, 1, 1);
|
||||
const glm::vec4 green(0, 1, 0, 1);
|
||||
const glm::vec4 white(1, 1, 1, 1);
|
||||
std::shared_ptr<ghoul::fontrendering::Font> font = OsEng.fontManager().font("Mono", font_size);
|
||||
std::shared_ptr<ghoul::fontrendering::Font> font = OsEng.fontManager().font(
|
||||
"Mono", FontSize
|
||||
);
|
||||
|
||||
using ghoul::fontrendering::RenderFont;
|
||||
|
||||
if (_remoteScripting) {
|
||||
int nClients = OsEng.parallelConnection().nConnections() - 1;
|
||||
if (nClients == 1) {
|
||||
RenderFont(*font, glm::vec2(15.f, startY + 20.0f), red, "Broadcasting script to 1 client");
|
||||
RenderFont(
|
||||
*font,
|
||||
glm::vec2(15.f, startY + 20.0f),
|
||||
red,
|
||||
"Broadcasting script to 1 client"
|
||||
);
|
||||
} else {
|
||||
RenderFont(*font, glm::vec2(15.f, startY + 20.0f), red, ("Broadcasting script to " + std::to_string(nClients) + " clients").c_str());
|
||||
RenderFont(
|
||||
*font,
|
||||
glm::vec2(15.f, startY + 20.0f),
|
||||
red,
|
||||
("Broadcasting script to " + std::to_string(nClients) + " clients").c_str()
|
||||
);
|
||||
}
|
||||
RenderFont(*font, glm::vec2(15.f, startY), red, "$");
|
||||
}
|
||||
else {
|
||||
if (OsEng.parallelConnection().isHost()) {
|
||||
RenderFont(*font, glm::vec2(15.f, startY + 20.0f), lightBlue, "Local script execution");
|
||||
RenderFont(
|
||||
*font,
|
||||
glm::vec2(15.f, startY + 20.0f),
|
||||
lightBlue,
|
||||
"Local script execution"
|
||||
);
|
||||
}
|
||||
RenderFont(*font, glm::vec2(15.f, startY), lightBlue, "$");
|
||||
}
|
||||
RenderFont(*font, glm::vec2(15.f + font_size, startY), white, "%s", _commands.at(_activeCommand).c_str());
|
||||
RenderFont(
|
||||
*font,
|
||||
glm::vec2(15.f + FontSize, startY),
|
||||
white,
|
||||
"%s",
|
||||
_commands.at(_activeCommand).c_str()
|
||||
);
|
||||
|
||||
size_t n = std::count(_commands.at(_activeCommand).begin(), _commands.at(_activeCommand).begin() + _inputPosition, '\n');
|
||||
const size_t n = std::count(
|
||||
_commands.at(_activeCommand).begin(),
|
||||
_commands.at(_activeCommand).begin() + _inputPosition,
|
||||
'\n'
|
||||
);
|
||||
size_t p = _commands.at(_activeCommand).find_last_of('\n', _inputPosition);
|
||||
size_t linepos = _inputPosition;
|
||||
|
||||
if (n>0) {
|
||||
if (n > 0) {
|
||||
if (p == _inputPosition) {
|
||||
p = _commands.at(_activeCommand).find_last_of('\n', _inputPosition - 1);
|
||||
if (p != std::string::npos) {
|
||||
@@ -361,107 +465,30 @@ void LuaConsole::render() {
|
||||
linepos = _inputPosition - 1;
|
||||
}
|
||||
}
|
||||
else{
|
||||
else {
|
||||
linepos -= p + 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "%" << linepos + 1 << "s";
|
||||
RenderFont(*font, glm::vec2(15.f + font_size * 0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f), green, ss.str().c_str(), "^");
|
||||
|
||||
// sgct_text::print(font, 15.0f + font_size*0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f, green, ss.str().c_str(), "^");
|
||||
}
|
||||
|
||||
Key LuaConsole::commandInputButton() {
|
||||
// Button left of 1 and above TAB
|
||||
// How to deal with different keyboard languages? ---abock
|
||||
return Key::GraveAccent;
|
||||
RenderFont(
|
||||
*font,
|
||||
glm::vec2(15.f + FontSize * 0.5f, startY - (FontSize) * (n + 1) * 3.0f / 2.0f),
|
||||
green,
|
||||
ss.str().c_str(),
|
||||
"^"
|
||||
);
|
||||
}
|
||||
|
||||
void LuaConsole::addToCommand(std::string c) {
|
||||
size_t length = c.length();
|
||||
_commands.at(_activeCommand).insert(_inputPosition, c);
|
||||
const size_t length = c.length();
|
||||
_commands.at(_activeCommand).insert(_inputPosition, std::move(c));
|
||||
_inputPosition += length;
|
||||
}
|
||||
|
||||
std::string LuaConsole::UnicodeToUTF8(unsigned int codepoint) {
|
||||
std::string out;
|
||||
|
||||
if (codepoint <= 0x7f)
|
||||
out.append(1, static_cast<char>(codepoint));
|
||||
else if (codepoint <= 0x7ff)
|
||||
{
|
||||
out.append(1, static_cast<char>(0xc0 | ((codepoint >> 6) & 0x1f)));
|
||||
out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));
|
||||
}
|
||||
else if (codepoint <= 0xffff)
|
||||
{
|
||||
out.append(1, static_cast<char>(0xe0 | ((codepoint >> 12) & 0x0f)));
|
||||
out.append(1, static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f)));
|
||||
out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.append(1, static_cast<char>(0xf0 | ((codepoint >> 18) & 0x07)));
|
||||
out.append(1, static_cast<char>(0x80 | ((codepoint >> 12) & 0x3f)));
|
||||
out.append(1, static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f)));
|
||||
out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool LuaConsole::isVisible() const {
|
||||
return _isVisible;
|
||||
}
|
||||
|
||||
void LuaConsole::setVisible(bool visible) {
|
||||
_isVisible = visible;
|
||||
}
|
||||
|
||||
void LuaConsole::toggleMode() {
|
||||
if (_isVisible) {
|
||||
if (_remoteScripting) {
|
||||
_remoteScripting = false;
|
||||
} else {
|
||||
_isVisible = false;
|
||||
}
|
||||
} else {
|
||||
_remoteScripting = OsEng.parallelConnection().isHost();
|
||||
_isVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LuaConsole::parallelConnectionChanged(const ParallelConnection::Status& status) {
|
||||
_remoteScripting = status == ParallelConnection::Status::Host;
|
||||
_remoteScripting = (status == ParallelConnection::Status::Host);
|
||||
}
|
||||
|
||||
|
||||
scripting::LuaLibrary LuaConsole::luaLibrary() {
|
||||
return {
|
||||
"console",
|
||||
{
|
||||
{
|
||||
"show",
|
||||
&luascriptfunctions::show,
|
||||
"",
|
||||
"Shows the console"
|
||||
},
|
||||
{
|
||||
"hide",
|
||||
&luascriptfunctions::hide,
|
||||
"",
|
||||
"Hides the console"
|
||||
},
|
||||
{
|
||||
"toggle",
|
||||
&luascriptfunctions::toggle,
|
||||
"",
|
||||
"Toggles the console"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
namespace openspace {
|
||||
|
||||
namespace luascriptfunctions {
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* show():
|
||||
* Shows the console
|
||||
*/
|
||||
int show(lua_State* L) {
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 0)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
|
||||
|
||||
OsEng.console().setVisible(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* hide():
|
||||
* Hides the console
|
||||
*/
|
||||
int hide(lua_State* L) {
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 0)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
|
||||
|
||||
OsEng.console().setVisible(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* toggle():
|
||||
* Toggles the console
|
||||
*/
|
||||
int toggle(lua_State* L) {
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 0)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
|
||||
|
||||
OsEng.console().toggleMode();
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace luascriptfunctions
|
||||
|
||||
} // namespace openspace
|
||||
@@ -32,24 +32,24 @@ namespace openspace {
|
||||
namespace properties {
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "Property";
|
||||
const std::string MetaDataKeyGuiName = "guiName";
|
||||
const std::string MetaDataKeyGroup = "Group";
|
||||
const std::string MetaDataKeyVisibility = "Visibility";
|
||||
const std::string MetaDataKeyReadOnly = "isReadOnly";
|
||||
const char* _loggerCat = "Property";
|
||||
const char* MetaDataKeyGuiName = "guiName";
|
||||
const char* MetaDataKeyGroup = "Group";
|
||||
const char* MetaDataKeyVisibility = "Visibility";
|
||||
const char* MetaDataKeyReadOnly = "isReadOnly";
|
||||
|
||||
const std::string _metaDataKeyViewPrefix = "view.";
|
||||
const char* _metaDataKeyViewPrefix = "view.";
|
||||
}
|
||||
|
||||
const std::string Property::ViewOptions::Color = "color";
|
||||
const std::string Property::ViewOptions::LightPosition = "lightPosition";
|
||||
const std::string Property::ViewOptions::PowerScaledCoordinate = "powerScaledCoordinate";
|
||||
const std::string Property::ViewOptions::PowerScaledScalar = "powerScaledScalar";
|
||||
const char* Property::ViewOptions::Color = "color";
|
||||
const char* Property::ViewOptions::LightPosition = "lightPosition";
|
||||
const char* Property::ViewOptions::PowerScaledCoordinate = "powerScaledCoordinate";
|
||||
const char* Property::ViewOptions::PowerScaledScalar = "powerScaledScalar";
|
||||
|
||||
const std::string Property::IdentifierKey = "Identifier";
|
||||
const std::string Property::NameKey = "Name";
|
||||
const std::string Property::TypeKey = "Type";
|
||||
const std::string Property::MetaDataKey = "MetaData";
|
||||
const char* Property::IdentifierKey = "Identifier";
|
||||
const char* Property::NameKey = "Name";
|
||||
const char* Property::TypeKey = "Type";
|
||||
const char* Property::MetaDataKey = "MetaData";
|
||||
|
||||
Property::Property(std::string identifier, std::string guiName, Visibility visibility)
|
||||
: _owner(nullptr)
|
||||
@@ -181,7 +181,7 @@ void Property::notifyListener() {
|
||||
|
||||
std::string Property::generateBaseDescription() const {
|
||||
return
|
||||
TypeKey + " = \"" + className() + "\", " +
|
||||
std::string(TypeKey) + " = \"" + className() + "\", " +
|
||||
IdentifierKey + " = \"" + fullyQualifiedIdentifier() + "\", " +
|
||||
NameKey + " = \"" + guiName() + "\", " +
|
||||
generateMetaDataDescription() + ", " +
|
||||
@@ -201,7 +201,7 @@ std::string Property::generateMetaDataDescription() const {
|
||||
std::string vis = VisibilityConverter.at(visibility);
|
||||
|
||||
return
|
||||
MetaDataKey + " = {" +
|
||||
std::string(MetaDataKey) + " = {" +
|
||||
MetaDataKeyGroup + " = '" + groupIdentifier() + "'," +
|
||||
MetaDataKeyVisibility + " = " + vis + "," +
|
||||
MetaDataKeyReadOnly +" = " + (isReadOnly ? "true" : "false") + "}";
|
||||
|
||||
@@ -24,33 +24,33 @@
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/properties/property.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
namespace openspace {
|
||||
namespace properties {
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "PropertyOwner";
|
||||
const char* _loggerCat = "PropertyOwner";
|
||||
|
||||
bool propertyLess(Property* lhs, Property* rhs)
|
||||
{
|
||||
return lhs->identifier() < rhs->identifier();
|
||||
}
|
||||
bool propertyLess(Property* lhs, Property* rhs)
|
||||
{
|
||||
return lhs->identifier() < rhs->identifier();
|
||||
}
|
||||
|
||||
bool subOwnerLess(PropertyOwner* lhs, PropertyOwner* rhs) {
|
||||
return lhs->name() < rhs->name();
|
||||
}
|
||||
bool subOwnerLess(PropertyOwner* lhs, PropertyOwner* rhs) {
|
||||
return lhs->name() < rhs->name();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
||||
PropertyOwner::PropertyOwner()
|
||||
: _name("")
|
||||
PropertyOwner::PropertyOwner(std::string name)
|
||||
: _name(std::move(name))
|
||||
, _owner(nullptr)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
PropertyOwner::~PropertyOwner() {
|
||||
_properties.clear();
|
||||
@@ -73,14 +73,20 @@ std::vector<Property*> PropertyOwner::propertiesRecursive() const {
|
||||
}
|
||||
|
||||
Property* PropertyOwner::property(const std::string& id) const {
|
||||
assert(std::is_sorted(_properties.begin(), _properties.end(), propertyLess));
|
||||
ghoul_assert(
|
||||
std::is_sorted(_properties.begin(), _properties.end(), propertyLess),
|
||||
"Property list must be sorted"
|
||||
);
|
||||
|
||||
// As the _properties list is sorted, just finding the lower bound is sufficient
|
||||
std::vector<Property*>::const_iterator it
|
||||
= std::lower_bound(_properties.begin(), _properties.end(), id,
|
||||
[](Property* prop, const std::string& str) {
|
||||
return prop->identifier() < str;
|
||||
});
|
||||
std::vector<Property*>::const_iterator it = std::lower_bound(
|
||||
_properties.begin(),
|
||||
_properties.end(),
|
||||
id,
|
||||
[](Property* prop, const std::string& str) {
|
||||
return prop->identifier() < str;
|
||||
}
|
||||
);
|
||||
|
||||
if (it == _properties.end() || (*it)->identifier() != id) {
|
||||
// if we do not own the searched property, it must consist of a concatenated
|
||||
@@ -118,19 +124,27 @@ std::vector<PropertyOwner*> PropertyOwner::propertySubOwners() const {
|
||||
}
|
||||
|
||||
PropertyOwner* PropertyOwner::propertySubOwner(const std::string& name) const {
|
||||
assert(std::is_sorted(_subOwners.begin(), _subOwners.end(), subOwnerLess));
|
||||
ghoul_assert(
|
||||
std::is_sorted(_subOwners.begin(), _subOwners.end(), subOwnerLess),
|
||||
"List of subowners must be sorted"
|
||||
);
|
||||
|
||||
// As the _subOwners list is sorted, getting the lower bound is sufficient
|
||||
std::vector<PropertyOwner*>::const_iterator it
|
||||
= std::lower_bound(_subOwners.begin(), _subOwners.end(), name,
|
||||
[](PropertyOwner* owner, const std::string& str) {
|
||||
return owner->name() < str;
|
||||
});
|
||||
std::vector<PropertyOwner*>::const_iterator it = std::lower_bound(
|
||||
_subOwners.begin(),
|
||||
_subOwners.end(),
|
||||
name,
|
||||
[](PropertyOwner* owner, const std::string& str) {
|
||||
return owner->name() < str;
|
||||
}
|
||||
);
|
||||
|
||||
if (it == _subOwners.end() || (*it)->name() != name)
|
||||
if (it == _subOwners.end() || (*it)->name() != name) {
|
||||
return nullptr;
|
||||
else
|
||||
}
|
||||
else {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
|
||||
bool PropertyOwner::hasPropertySubOwner(const std::string& name) const {
|
||||
@@ -143,17 +157,24 @@ void PropertyOwner::setPropertyGroupName(std::string groupID, std::string name)
|
||||
|
||||
std::string PropertyOwner::propertyGroupName(const std::string& groupID) const {
|
||||
auto it = _groupNames.find(groupID);
|
||||
if (it == _groupNames.end())
|
||||
if (it == _groupNames.end()) {
|
||||
return groupID;
|
||||
else
|
||||
}
|
||||
else {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyOwner::addProperty(Property* prop)
|
||||
{
|
||||
assert(prop != nullptr);
|
||||
assert(std::is_sorted(_properties.begin(), _properties.end(), propertyLess));
|
||||
assert(std::is_sorted(_subOwners.begin(), _subOwners.end(), subOwnerLess));
|
||||
void PropertyOwner::addProperty(Property* prop) {
|
||||
ghoul_assert(prop != nullptr, "prop must not be nullptr");
|
||||
ghoul_assert(
|
||||
std::is_sorted(_properties.begin(), _properties.end(), propertyLess),
|
||||
"Property list must be sorted"
|
||||
);
|
||||
ghoul_assert(
|
||||
std::is_sorted(_subOwners.begin(), _subOwners.end(), subOwnerLess),
|
||||
"Subowner list must be sorted"
|
||||
);
|
||||
|
||||
if (prop->identifier().empty()) {
|
||||
LERROR("No property identifier specified");
|
||||
@@ -162,23 +183,25 @@ void PropertyOwner::addProperty(Property* prop)
|
||||
|
||||
// See if we can find the identifier of the property to add in the properties list
|
||||
// The _properties list is sorted, so getting the lower bound is sufficient
|
||||
std::vector<Property*>::iterator it
|
||||
= std::lower_bound(_properties.begin(), _properties.end(), prop->identifier(),
|
||||
[](Property* prop, const std::string& str) {
|
||||
return prop->identifier() < str;
|
||||
});
|
||||
std::vector<Property*>::iterator it = std::lower_bound(
|
||||
_properties.begin(),
|
||||
_properties.end(),
|
||||
prop->identifier(),
|
||||
[](Property* prop, const std::string& str) {
|
||||
return prop->identifier() < str;
|
||||
}
|
||||
);
|
||||
|
||||
// If we found the property identifier, we need to bail out
|
||||
if (it != _properties.end() && (*it)->identifier() == prop->identifier()) {
|
||||
LERROR("Property identifier '" << prop->identifier()
|
||||
<< "' already present in PropertyOwner '"
|
||||
<< name() << "'");
|
||||
LERROR("Property identifier '" << prop->identifier() <<
|
||||
"' already present in PropertyOwner '" << name() << "'");
|
||||
return;
|
||||
} else {
|
||||
// Otherwise we still have to look if there is a PropertyOwner with the same name
|
||||
const bool hasOwner = hasPropertySubOwner(prop->identifier());
|
||||
if (hasOwner) {
|
||||
LERROR("Property identifier '" << prop->identifier() << "' already names a"
|
||||
LERROR("Property identifier '" << prop->identifier() << "' already names a "
|
||||
<< "registed PropertyOwner");
|
||||
return;
|
||||
}
|
||||
@@ -195,26 +218,30 @@ void PropertyOwner::addProperty(Property& prop) {
|
||||
}
|
||||
|
||||
void PropertyOwner::addPropertySubOwner(openspace::properties::PropertyOwner* owner) {
|
||||
assert(owner != nullptr);
|
||||
assert(std::is_sorted(_properties.begin(), _properties.end(), propertyLess));
|
||||
assert(std::is_sorted(_subOwners.begin(), _subOwners.end(), subOwnerLess));
|
||||
ghoul_assert(owner != nullptr, "owner must not be nullptr");
|
||||
ghoul_assert(
|
||||
std::is_sorted(_properties.begin(), _properties.end(), propertyLess),
|
||||
"Property list must be sorted"
|
||||
);
|
||||
ghoul_assert(
|
||||
std::is_sorted(_subOwners.begin(), _subOwners.end(), subOwnerLess),
|
||||
"Subowner list must be sorted"
|
||||
);
|
||||
|
||||
if (owner->name().empty()) {
|
||||
LERROR("PropertyOwner did not have a name");
|
||||
return;
|
||||
}
|
||||
ghoul_assert(!owner->name().empty(), "PropertyOwner must have a name");
|
||||
|
||||
// See if we can find the name of the propertyowner to add using the lower bound
|
||||
std::vector<PropertyOwner*>::iterator it
|
||||
= std::lower_bound(_subOwners.begin(), _subOwners.end(), owner->name(),
|
||||
[](PropertyOwner* owner, const std::string& str) {
|
||||
return owner->name() < str;
|
||||
});
|
||||
std::vector<PropertyOwner*>::iterator it = std::lower_bound(
|
||||
_subOwners.begin(), _subOwners.end(), owner->name(),
|
||||
[](PropertyOwner* owner, const std::string& str) {
|
||||
return owner->name() < str;
|
||||
}
|
||||
);
|
||||
|
||||
// If we found the propertyowner's name, we need to bail out
|
||||
if (it != _subOwners.end() && (*it)->name() == owner->name()) {
|
||||
LERROR("PropertyOwner '" << owner->name()
|
||||
<< "' already present in PropertyOwner '" << name() << "'");
|
||||
LERROR("PropertyOwner '" << owner->name() <<
|
||||
"' already present in PropertyOwner '" << name() << "'");
|
||||
return;
|
||||
} else {
|
||||
// We still need to check if the PropertyOwners name is used in a Property
|
||||
@@ -230,7 +257,6 @@ void PropertyOwner::addPropertySubOwner(openspace::properties::PropertyOwner* ow
|
||||
owner->setPropertyOwner(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PropertyOwner::addPropertySubOwner(openspace::properties::PropertyOwner& owner) {
|
||||
@@ -238,22 +264,26 @@ void PropertyOwner::addPropertySubOwner(openspace::properties::PropertyOwner& ow
|
||||
}
|
||||
|
||||
void PropertyOwner::removeProperty(Property* prop) {
|
||||
assert(prop != nullptr);
|
||||
ghoul_assert(prop != nullptr, "prop must not be nullptr");
|
||||
|
||||
// See if we can find the identifier of the property to add in the properties list
|
||||
std::vector<Property*>::iterator it
|
||||
= std::lower_bound(_properties.begin(), _properties.end(), prop->identifier(),
|
||||
[](Property* prop, const std::string& str) {
|
||||
return prop->identifier() < str;
|
||||
});
|
||||
std::vector<Property*>::iterator it = std::lower_bound(
|
||||
_properties.begin(),
|
||||
_properties.end(),
|
||||
prop->identifier(),
|
||||
[](Property* prop, const std::string& str) {
|
||||
return prop->identifier() < str;
|
||||
}
|
||||
);
|
||||
|
||||
// If we found the property identifier, we can delete it
|
||||
if (it != _properties.end() && (*it)->identifier() == prop->identifier()) {
|
||||
(*it)->setPropertyOwner(nullptr);
|
||||
_properties.erase(it);
|
||||
} else
|
||||
LERROR("Property with identifier '" << prop->identifier()
|
||||
<< "' not found for removal.");
|
||||
} else {
|
||||
LERROR("Property with identifier '" << prop->identifier() <<
|
||||
"' not found for removal.");
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyOwner::removeProperty(Property& prop) {
|
||||
@@ -261,21 +291,25 @@ void PropertyOwner::removeProperty(Property& prop) {
|
||||
}
|
||||
|
||||
void PropertyOwner::removePropertySubOwner(openspace::properties::PropertyOwner* owner) {
|
||||
assert(owner != nullptr);
|
||||
ghoul_assert(owner != nullptr, "owner must not be nullptr");
|
||||
|
||||
// See if we can find the name of the propertyowner to add
|
||||
std::vector<PropertyOwner*>::iterator it
|
||||
= std::lower_bound(_subOwners.begin(), _subOwners.end(), owner->name(),
|
||||
[](PropertyOwner* owner, const std::string& str) {
|
||||
return owner->name() < str;
|
||||
});
|
||||
std::vector<PropertyOwner*>::iterator it = std::lower_bound(
|
||||
_subOwners.begin(),
|
||||
_subOwners.end(),
|
||||
owner->name(),
|
||||
[](PropertyOwner* owner, const std::string& str) {
|
||||
return owner->name() < str;
|
||||
}
|
||||
);
|
||||
|
||||
// If we found the propertyowner, we can delete it
|
||||
if (it != _subOwners.end() && (*it)->name() == owner->name()) {
|
||||
_subOwners.erase(it);
|
||||
} else
|
||||
LERROR("PropertyOwner with name '" << owner->name()
|
||||
<< "' not found for removal.");
|
||||
} else {
|
||||
LERROR("PropertyOwner with name '" << owner->name() <<
|
||||
"' not found for removal.");
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyOwner::removePropertySubOwner(openspace::properties::PropertyOwner& owner) {
|
||||
|
||||
@@ -88,7 +88,8 @@ std::unique_ptr<Renderable> Renderable::createFromDictionary(
|
||||
}
|
||||
|
||||
Renderable::Renderable()
|
||||
: _enabled("enabled", "Is Enabled", true)
|
||||
: properties::PropertyOwner("renderable")
|
||||
, _enabled("enabled", "Is Enabled", true)
|
||||
, _renderBin(RenderBin::Opaque)
|
||||
, _startTime("")
|
||||
, _endTime("")
|
||||
@@ -96,17 +97,16 @@ Renderable::Renderable()
|
||||
{}
|
||||
|
||||
Renderable::Renderable(const ghoul::Dictionary& dictionary)
|
||||
: _enabled("enabled", "Is Enabled", true)
|
||||
: properties::PropertyOwner("renderable")
|
||||
, _enabled("enabled", "Is Enabled", true)
|
||||
, _renderBin(RenderBin::Opaque)
|
||||
, _startTime("")
|
||||
, _endTime("")
|
||||
, _hasTimeInterval(false)
|
||||
{
|
||||
setName("renderable");
|
||||
|
||||
ghoul_assert(
|
||||
dictionary.hasKeyAndValue<std::string>(SceneGraphNode::KeyName),
|
||||
"SceneGraphNode must specify '" << SceneGraphNode::KeyName << "'"
|
||||
std::string("SceneGraphNode must specify '") + SceneGraphNode::KeyName + "'"
|
||||
);
|
||||
|
||||
dictionary.getValue(keyStart, _startTime);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
#include <openspace/rendering/renderer.h>
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/screenlog.h>
|
||||
@@ -91,7 +92,8 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
RenderEngine::RenderEngine()
|
||||
: _mainCamera(nullptr)
|
||||
: properties::PropertyOwner("RenderEngine")
|
||||
, _mainCamera(nullptr)
|
||||
, _raycasterManager(nullptr)
|
||||
, _performanceMeasurements("performanceMeasurements", "Performance Measurements")
|
||||
, _frametimeType(
|
||||
@@ -118,8 +120,6 @@ RenderEngine::RenderEngine()
|
||||
, _fadeDirection(0)
|
||||
, _frameNumber(0)
|
||||
{
|
||||
setName("RenderEngine");
|
||||
|
||||
_performanceMeasurements.onChange([this](){
|
||||
if (_performanceMeasurements) {
|
||||
if (!_performanceManager) {
|
||||
@@ -185,7 +185,7 @@ void RenderEngine::initialize() {
|
||||
if (confManager.hasKeyAndValue<std::string>(KeyRenderingMethod)) {
|
||||
renderingMethod = confManager.value<std::string>(KeyRenderingMethod);
|
||||
} else {
|
||||
using Version = ghoul::systemcapabilities::OpenGLCapabilitiesComponent::Version;
|
||||
using Version = ghoul::systemcapabilities::Version;
|
||||
|
||||
// The default rendering method has a requirement of OpenGL 4.3, so if we are
|
||||
// below that, we will fall back to frame buffer operation
|
||||
@@ -555,7 +555,9 @@ void RenderEngine::postDraw() {
|
||||
}
|
||||
|
||||
if (_performanceManager) {
|
||||
_performanceManager->storeScenePerformanceMeasurements(scene()->allSceneGraphNodes());
|
||||
_performanceManager->storeScenePerformanceMeasurements(
|
||||
scene()->allSceneGraphNodes()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1098,6 +1100,8 @@ void RenderEngine::renderInformation() {
|
||||
penPosition.y -= _fontInfo->height();
|
||||
}
|
||||
catch (...) {
|
||||
// @CLEANUP: This is bad as it will discard all exceptions
|
||||
// without telling us about it! ---abock
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,8 @@ std::unique_ptr<ScreenSpaceRenderable> ScreenSpaceRenderable::createFromDictiona
|
||||
}
|
||||
|
||||
ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary)
|
||||
: _enabled("enabled", "Is Enabled", true)
|
||||
: properties::PropertyOwner("")
|
||||
, _enabled("enabled", "Is Enabled", true)
|
||||
, _useFlatScreen("flatScreen", "Flat Screen", true)
|
||||
, _euclideanPosition(
|
||||
"euclideanPosition",
|
||||
@@ -130,14 +131,15 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary
|
||||
addProperty(_alpha);
|
||||
addProperty(_delete);
|
||||
|
||||
|
||||
dictionary.getValue(KeyFlatScreen, _useFlatScreen);
|
||||
useEuclideanCoordinates(_useFlatScreen);
|
||||
|
||||
if (_useFlatScreen)
|
||||
if (_useFlatScreen) {
|
||||
dictionary.getValue(KeyPosition, _euclideanPosition);
|
||||
else
|
||||
}
|
||||
else {
|
||||
dictionary.getValue(KeyPosition, _sphericalPosition);
|
||||
}
|
||||
|
||||
|
||||
dictionary.getValue(KeyScale, _scale);
|
||||
|
||||
@@ -72,11 +72,13 @@ std::unique_ptr<Rotation> Rotation::createFromDictionary(const ghoul::Dictionary
|
||||
return result;
|
||||
}
|
||||
|
||||
Rotation::Rotation() {
|
||||
setName("Rotation");
|
||||
}
|
||||
Rotation::Rotation()
|
||||
: properties::PropertyOwner("Rotation")
|
||||
{}
|
||||
|
||||
Rotation::Rotation(const ghoul::Dictionary& dictionary) {}
|
||||
Rotation::Rotation(const ghoul::Dictionary& dictionary)
|
||||
: properties::PropertyOwner("Rotation")
|
||||
{}
|
||||
|
||||
Rotation::~Rotation() {}
|
||||
|
||||
|
||||
@@ -76,6 +76,10 @@ std::unique_ptr<Scale> Scale::createFromDictionary(const ghoul::Dictionary& dict
|
||||
return result;
|
||||
}
|
||||
|
||||
Scale::Scale()
|
||||
: properties::PropertyOwner("Scale")
|
||||
{}
|
||||
|
||||
Scale::~Scale() {}
|
||||
|
||||
bool Scale::initialize() {
|
||||
|
||||
@@ -113,6 +113,7 @@ bool SceneGraph::loadFromFile(const std::string& sceneDescription) {
|
||||
);
|
||||
}
|
||||
catch (...) {
|
||||
// @CLEANUP: This is bad to just catch all exceptions! ---abock
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +145,8 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di
|
||||
}
|
||||
|
||||
SceneGraphNode::SceneGraphNode()
|
||||
: _parent(nullptr)
|
||||
: properties::PropertyOwner("")
|
||||
, _parent(nullptr)
|
||||
, _transform {
|
||||
std::make_unique<StaticTranslation>(),
|
||||
std::make_unique<StaticRotation>(),
|
||||
|
||||
@@ -80,6 +80,10 @@ std::unique_ptr<Translation> Translation::createFromDictionary(
|
||||
return result;
|
||||
}
|
||||
|
||||
Translation::Translation()
|
||||
: properties::PropertyOwner("Translation")
|
||||
{}
|
||||
|
||||
Translation::~Translation() {}
|
||||
|
||||
bool Translation::initialize() {
|
||||
|
||||
@@ -111,7 +111,7 @@ int hasOpenGLVersion(lua_State* L) {
|
||||
int major = std::stoi(v[0]);
|
||||
int minor = std::stoi(v[1]);
|
||||
int release = v.size() == 3 ? std::stoi(v[2]) : 0;
|
||||
OpenGLCapabilitiesComponent::Version version = { major, minor, release };
|
||||
Version version = { major, minor, release };
|
||||
|
||||
bool supported = OpenGLCap.openGLVersion() >= version;
|
||||
|
||||
@@ -121,7 +121,7 @@ int hasOpenGLVersion(lua_State* L) {
|
||||
}
|
||||
|
||||
int openGLVersion(lua_State* L) {
|
||||
lua_pushstring(L, OpenGLCap.openGLVersion().toString().c_str());
|
||||
lua_pushstring(L, std::to_string(OpenGLCap.openGLVersion()).c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,15 +30,16 @@
|
||||
|
||||
#include <iterator>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
const std::string MainTemplateFilename = "${OPENSPACE_DATA}/web/factories/main.hbs";
|
||||
const std::string FactoryTemplateFilename = "${OPENSPACE_DATA}/web/factories/factory.hbs";
|
||||
const std::string HandlebarsFilename = "${OPENSPACE_DATA}/web/common/handlebars-v4.0.5.js";
|
||||
const std::string JsFilename = "${OPENSPACE_DATA}/web/factories/script.js";
|
||||
const std::string BootstrapFilename = "${OPENSPACE_DATA}/web/common/bootstrap.min.css";
|
||||
const std::string CssFilename = "${OPENSPACE_DATA}/web/common/style.css";
|
||||
}
|
||||
const char* MainTemplateFilename = "${OPENSPACE_DATA}/web/factories/main.hbs";
|
||||
const char* FactoryTemplateFilename = "${OPENSPACE_DATA}/web/factories/factory.hbs";
|
||||
const char* HandlebarsFilename = "${OPENSPACE_DATA}/web/common/handlebars-v4.0.5.js";
|
||||
const char* JsFilename = "${OPENSPACE_DATA}/web/factories/script.js";
|
||||
const char* BootstrapFilename = "${OPENSPACE_DATA}/web/common/bootstrap.min.css";
|
||||
const char* CssFilename = "${OPENSPACE_DATA}/web/common/style.css";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ KeyModifier operator|(KeyModifier lhs, KeyModifier rhs) {
|
||||
return static_cast<KeyModifier>(
|
||||
static_cast<std::underlying_type_t<KeyModifier>>(lhs) |
|
||||
static_cast<std::underlying_type_t<KeyModifier>>(rhs)
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
KeyModifier operator|=(KeyModifier& lhs, KeyModifier rhs) {
|
||||
@@ -82,8 +82,9 @@ KeyWithModifier stringToKey(std::string str) {
|
||||
// default is unknown
|
||||
Key k = Key::Unknown;
|
||||
auto it = KeyMapping.find(tokens.back());
|
||||
if (it != KeyMapping.end())
|
||||
if (it != KeyMapping.end()) {
|
||||
k = it->second;
|
||||
}
|
||||
|
||||
|
||||
KeyModifier m = KeyModifier::NoModifier;
|
||||
@@ -92,10 +93,12 @@ KeyWithModifier stringToKey(std::string str) {
|
||||
tokens.end() - 1,
|
||||
[&m](const std::string& s) {
|
||||
auto it = KeyModifierMapping.find(s);
|
||||
if (it != KeyModifierMapping.end())
|
||||
if (it != KeyModifierMapping.end()) {
|
||||
m |= it->second;
|
||||
else
|
||||
}
|
||||
else {
|
||||
LERROR("Unknown modifier key '" << s << "'");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -103,10 +106,12 @@ KeyWithModifier stringToKey(std::string str) {
|
||||
}
|
||||
|
||||
bool operator<(const KeyWithModifier& lhs, const KeyWithModifier& rhs) {
|
||||
if (lhs.modifier == rhs.modifier)
|
||||
if (lhs.modifier == rhs.modifier) {
|
||||
return lhs.key < rhs.key;
|
||||
else
|
||||
}
|
||||
else {
|
||||
return lhs.modifier < rhs.modifier;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -115,8 +120,9 @@ namespace std {
|
||||
|
||||
std::string to_string(openspace::Key key) {
|
||||
for (const auto& p : openspace::KeyMapping) {
|
||||
if (p.second == key)
|
||||
if (p.second == key) {
|
||||
return p.first;
|
||||
}
|
||||
}
|
||||
ghoul_assert(false, "Missing key in KeyMapping");
|
||||
}
|
||||
@@ -124,8 +130,9 @@ std::string to_string(openspace::Key key) {
|
||||
std::string to_string(openspace::KeyModifier mod) {
|
||||
using namespace openspace;
|
||||
|
||||
if (mod == KeyModifier::NoModifier)
|
||||
if (mod == KeyModifier::NoModifier) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string result;
|
||||
for (const auto& p : KeyModifierMapping) {
|
||||
@@ -139,10 +146,12 @@ std::string to_string(openspace::KeyModifier mod) {
|
||||
}
|
||||
|
||||
std::string to_string(openspace::KeyWithModifier key) {
|
||||
if (key.modifier == openspace::KeyModifier::NoModifier)
|
||||
if (key.modifier == openspace::KeyModifier::NoModifier) {
|
||||
return to_string(key.key);
|
||||
else
|
||||
}
|
||||
else {
|
||||
return to_string(key.modifier) + "+" + to_string(key.key);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
@@ -38,11 +38,9 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
OpenSpaceModule::OpenSpaceModule(std::string name) {
|
||||
ghoul_assert(!name.empty(), "Name must not be empty");
|
||||
|
||||
setName(std::move(name));
|
||||
}
|
||||
OpenSpaceModule::OpenSpaceModule(std::string name)
|
||||
: properties::PropertyOwner(std::move(name))
|
||||
{}
|
||||
|
||||
void OpenSpaceModule::initialize() {
|
||||
std::string upperName = name();
|
||||
@@ -73,9 +71,7 @@ scripting::LuaLibrary OpenSpaceModule::luaLibrary() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
ghoul::systemcapabilities::OpenGLCapabilitiesComponent::Version
|
||||
OpenSpaceModule::requiredOpenGLVersion() const
|
||||
{
|
||||
ghoul::systemcapabilities::Version OpenSpaceModule::requiredOpenGLVersion() const {
|
||||
return { 3, 3 };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user