From 2fce4717438e6c7277668a5e89d0c49a3222bb5d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 14 Dec 2015 10:50:38 -0800 Subject: [PATCH] Started cleanup of module structure --- apps/OpenSpace/main.cpp | 55 +++---- ext/ghoul | 2 +- .../openspace/engine/configurationmanager.h | 15 +- include/openspace/engine/downloadmanager.h | 36 +++-- include/openspace/engine/logfactory.h | 6 +- include/openspace/engine/moduleengine.h | 23 +-- include/openspace/engine/openspaceengine.h | 17 +-- include/openspace/util/openspacemodule.h | 14 +- modules/base/basemodule.cpp | 8 +- modules/base/basemodule.h | 4 +- modules/fieldlines/fieldlinesmodule.cpp | 8 +- modules/fieldlines/fieldlinesmodule.h | 4 +- modules/kameleon/kameleonmodule.cpp | 8 -- modules/kameleon/kameleonmodule.h | 1 - modules/newhorizons/newhorizonsmodule.cpp | 8 +- modules/newhorizons/newhorizonsmodule.h | 4 +- modules/onscreengui/onscreenguimodule.cpp | 7 - modules/onscreengui/onscreenguimodule.h | 1 - modules/volume/volumemodule.cpp | 8 +- modules/volume/volumemodule.h | 4 +- src/engine/configurationmanager.cpp | 135 +++++++++++------- src/engine/downloadmanager.cpp | 114 +++++++-------- src/engine/moduleengine.cpp | 49 +++---- src/engine/openspaceengine.cpp | 52 ++----- src/util/openspacemodule.cpp | 17 ++- 25 files changed, 298 insertions(+), 302 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index e5a268c0cc..770d60edfc 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -26,14 +26,14 @@ #include #include #include -#include -#include +#include +#include #include + #include sgct::Engine* _sgctEngine; -// function pointer declarations void mainInitFunc(); void mainPreSyncFunc(); void mainPostSyncPreDrawFunc(); @@ -49,12 +49,13 @@ void mainDecodeFun(); void mainExternalControlCallback(const char * receivedChars, int size); void mainLogCallback(const char* msg); -std::pair supportedOpenGLVersion () { +std::pair supportedOpenGLVersion() { glfwInit(); - //On OS X we need to explicitly set the version and specify that we are using CORE profile - //to be able to use glGetIntegerv(GL_MAJOR_VERSION, &major) and glGetIntegerv(GL_MINOR_VERSION, &minor) - //explicitly setting to OGL 3.3 CORE works since all Mac's now support at least 3.3 + // On OS X we need to explicitly set the version and specify that we are using CORE + // profile to be able to use glGetIntegerv(GL_MAJOR_VERSION, &major) and + // glGetIntegerv(GL_MINOR_VERSION, &minor) explicitly setting to OGL 3.3 CORE works + // since all Mac's now support at least 3.3 #ifdef __APPLE__ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); @@ -75,8 +76,6 @@ std::pair supportedOpenGLVersion () { return { major, minor }; } -#include - namespace { const std::string _loggerCat = "main"; } @@ -88,7 +87,7 @@ int main(int argc, char** argv) { std::vector sgctArguments; const bool success = openspace::OpenSpaceEngine::create( argc, argv, - new openspace::SGCTWindowWrapper, + std::make_unique(), sgctArguments ); if (!success) @@ -147,10 +146,10 @@ int main(int argc, char** argv) { { { 4, 4 }, sgct::Engine::RunMode::OpenGL_4_4_Core_Profile }, { { 4, 5 }, sgct::Engine::RunMode::OpenGL_4_5_Core_Profile } }; - if (versionMapping.find(glVersion) == versionMapping.end()) { - LFATAL("Requested OpenGL version " << glVersion.first << "." << glVersion.second << " not supported"); - return EXIT_FAILURE; - } + ghoul_assert( + versionMapping.find(glVersion) != versionMapping.end(), + "Unknown OpenGL version. Missing statement in version mapping map" + ); sgct::Engine::RunMode rm = versionMapping[glVersion]; const bool initSuccess = _sgctEngine->init(rm); @@ -173,7 +172,7 @@ int main(int argc, char** argv) { LDEBUG("Destroying OpenSpaceEngine"); openspace::OpenSpaceEngine::destroy(); - // Clean up (de-allocate) + // Clean up (deallocate) LDEBUG("Destroying SGCT Engine"); delete _sgctEngine; @@ -191,8 +190,6 @@ void mainInitFunc() { if (!success) { LFATAL("Initializing OpenSpaceEngine failed"); - std::cout << "Press any key to continue..."; - std::cin.ignore(100); exit(EXIT_FAILURE); } @@ -248,16 +245,22 @@ void mainExternalControlCallback(const char* receivedChars, int size) { } void mainKeyboardCallback(int key, int, int action, int mods) { - if (OsEng.isMaster()) - OsEng.keyboardCallback(openspace::Key(key), - openspace::KeyModifier(mods), - openspace::KeyAction(action)); + if (OsEng.isMaster()) { + OsEng.keyboardCallback( + openspace::Key(key), + openspace::KeyModifier(mods), + openspace::KeyAction(action) + ); + } } void mainMouseButtonCallback(int key, int action) { - if (OsEng.isMaster()) - OsEng.mouseButtonCallback(openspace::MouseButton(key), - openspace::MouseAction(action)); + if (OsEng.isMaster()) { + OsEng.mouseButtonCallback( + openspace::MouseButton(key), + openspace::MouseAction(action) + ); + } } void mainMousePosCallback(double x, double y) { @@ -283,9 +286,9 @@ void mainDecodeFun() { OsEng.decode(); } -void mainLogCallback(const char* msg){ +void mainLogCallback(const char* msg) { std::string message = msg; - if (message == ".") + if (message.empty() || message == ".") // We don't want the empty '.' message that SGCT sends while it is waiting for // connections from other network nodes return; diff --git a/ext/ghoul b/ext/ghoul index 212f1efd5d..ff01cac350 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 212f1efd5d9ecd1e84937a01ee9f04a0e10b8a58 +Subproject commit ff01cac35077a6fe298f8b691466ee9cb704200b diff --git a/include/openspace/engine/configurationmanager.h b/include/openspace/engine/configurationmanager.h index c87c9183ab..46ce99a67f 100644 --- a/include/openspace/engine/configurationmanager.h +++ b/include/openspace/engine/configurationmanager.h @@ -29,11 +29,20 @@ namespace openspace { +/** + * The ConfigurationManager takes care of loading the major configuration file + * openspace.cfg and making it available to the rest of the application. The + * exposed keys in the ghoul::Dictionary are declared in this class as static constants. + * The findConfiguration method walks the filesystem from a provided starting point until + * it found the requested file or throws a ghoul::RuntimeError if it could not find the + * file. The loadFromFile method then loads the file into a ghoul::Dictionary format. + */ class ConfigurationManager : public ghoul::Dictionary { public: + /// The key that stores the subdirectory containing all predefined path tokens static const std::string KeyPaths; + /// static const std::string KeyCache; - static const std::string KeyCachePath; static const std::string KeyFonts; static const std::string KeyConfigSgct; static const std::string KeyLuaDocumentationType; @@ -53,7 +62,9 @@ public: static const std::string KeyDisableMasterRendering; static const std::string KeyDownloadRequestURL; - bool loadFromFile(const std::string& filename); + static std::string findConfiguration(const std::string& filename); + + void loadFromFile(const std::string& filename); private: bool checkCompleteness() const; diff --git a/include/openspace/engine/downloadmanager.h b/include/openspace/engine/downloadmanager.h index 1cb8a9d751..5825f3c8b9 100644 --- a/include/openspace/engine/downloadmanager.h +++ b/include/openspace/engine/downloadmanager.h @@ -26,12 +26,14 @@ #define __DOWNLOADMANAGER_H__ #include + #include #include -#include #include +#include #include +#include namespace openspace { @@ -58,42 +60,38 @@ public: bool abortDownload; }; - typedef std::function DownloadProgressCallback; - typedef std::function DownloadFinishedCallback; - typedef std::function&)> AsyncDownloadFinishedCallback; + using DownloadProgressCallback = std::function; + using DownloadFinishedCallback = std::function; + using AsyncDownloadFinishedCallback = + std::function&)>; - DownloadManager(std::string requestURL, int applicationVersion); + DownloadManager(std::string requestURL, int applicationVersion, + bool useMultithreadedDownload = true); // callers responsibility to delete // callbacks happen on a different thread - FileFuture* downloadFile( - const std::string& url, - const ghoul::filesystem::File& file, + FileFuture* downloadFile(const std::string& url, const ghoul::filesystem::File& file, bool overrideFile = true, DownloadFinishedCallback finishedCallback = DownloadFinishedCallback(), DownloadProgressCallback progressCallback = DownloadProgressCallback() ); - std::vector downloadRequestFiles( - const std::string& identifier, - const ghoul::filesystem::Directory& destination, - int version, + std::vector downloadRequestFiles(const std::string& identifier, + const ghoul::filesystem::Directory& destination, int version, bool overrideFiles = true, DownloadFinishedCallback finishedCallback = DownloadFinishedCallback(), DownloadProgressCallback progressCallback = DownloadProgressCallback() ); - void downloadRequestFilesAsync( - const std::string& identifier, - const ghoul::filesystem::Directory& destination, - int version, - bool overrideFiles, - AsyncDownloadFinishedCallback callback + void downloadRequestFilesAsync(const std::string& identifier, + const ghoul::filesystem::Directory& destination, int version, + bool overrideFiles, AsyncDownloadFinishedCallback callback ); private: - std::string _requestURL; + std::vector _requestURL; int _applicationVersion; + bool _useMultithreadedDownload; }; #define DlManager (openspace::DownloadManager::ref()) diff --git a/include/openspace/engine/logfactory.h b/include/openspace/engine/logfactory.h index 2af0fde8df..3df5af6d45 100644 --- a/include/openspace/engine/logfactory.h +++ b/include/openspace/engine/logfactory.h @@ -28,10 +28,8 @@ #include namespace ghoul { - class Dictionary; - namespace logging { - class Log; - } +class Dictionary; +namespace logging { class Log; } } namespace openspace { diff --git a/include/openspace/engine/moduleengine.h b/include/openspace/engine/moduleengine.h index 2ad6954846..1fefc57ef6 100644 --- a/include/openspace/engine/moduleengine.h +++ b/include/openspace/engine/moduleengine.h @@ -25,26 +25,33 @@ #ifndef __MODULEENGINE_H__ #define __MODULEENGINE_H__ +#include + +#include #include namespace openspace { -class OpenSpaceModule; - +/** + * The ModuleEngine is the central repository for registering and accessing + * OpenSpaceModule for the current application run. By create%ing the ModuleEngine, the + * default set of OpenSpaceModule%s as generated by CMake in the + * moduleregistration.h file is automatically registered and created. + */ class ModuleEngine { public: - bool create(); - bool destroy(); + void create(); + void destroy(); bool initialize(); bool deinitialize(); - void registerModules(std::vector modules); - void registerModule(OpenSpaceModule* module); - const std::vector modules() const; + void registerModules(std::vector> modules); + void registerModule(std::unique_ptr module); + std::vector modules() const; protected: - std::vector _modules; + std::vector> _modules; }; diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 7879b20cd9..ac044533b5 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -59,17 +59,17 @@ namespace properties { class PropertyOwner; } class OpenSpaceEngine { public: - static bool create(int argc, char** argv, std::unique_ptr windowWrapper, std::vector& sgctArguments); + static bool create(int argc, char** argv, + std::unique_ptr windowWrapper, + std::vector& sgctArguments); static void destroy(); + static bool isInitialized(); static OpenSpaceEngine& ref(); - static bool isInitialized(); - bool initialize(); bool isMaster(); void setMaster(bool master); double runTime(); void setRunTime(double t); - static bool findConfiguration(std::string& filename); // Guaranteed to return a valid pointer ConfigurationManager& configurationManager(); @@ -86,6 +86,7 @@ public: gui::GUI& gui(); // SGCT callbacks + bool initialize(); bool initializeGL(); void preSynchronization(); void postSynchronizationPreDraw(); @@ -116,8 +117,8 @@ private: void runScripts(const ghoul::Dictionary& scripts); void runStartupScripts(); void configureLogging(); - - + + // Components std::unique_ptr _configurationManager; std::unique_ptr _interactionHandler; std::unique_ptr _renderEngine; @@ -131,13 +132,13 @@ private: std::unique_ptr _windowWrapper; std::unique_ptr _fontManager; + // Others std::unique_ptr _globalPropertyNamespace; + std::unique_ptr _syncBuffer; bool _isMaster; double _runTime; - std::unique_ptr _syncBuffer; - static OpenSpaceEngine* _engine; }; diff --git a/include/openspace/util/openspacemodule.h b/include/openspace/util/openspacemodule.h index 3a4ade1eaa..5677e46b65 100644 --- a/include/openspace/util/openspacemodule.h +++ b/include/openspace/util/openspacemodule.h @@ -34,15 +34,21 @@ public: OpenSpaceModule(std::string name); virtual ~OpenSpaceModule() = default; - virtual bool create(); - virtual bool destroy(); + void create(); + void destroy(); - virtual bool initialize(); - virtual bool deinitialize(); + bool initialize(); + bool deinitialize(); std::string name() const; protected: + virtual void internalCreate(); + virtual void internalDestroy(); + + virtual void internalInitialize(); + virtual void internalDeinitialize(); + std::string modulePath() const; const std::string _name; diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index 8280208f98..e6b2ddcd2a 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -55,11 +55,7 @@ BaseModule::BaseModule() : OpenSpaceModule("Base") {} -bool BaseModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - +void BaseModule::internalCreate() { FactoryManager::ref().addFactory(new ghoul::TemplateFactory); FactoryManager::ref().addFactory(new ghoul::TemplateFactory); @@ -89,8 +85,6 @@ bool BaseModule::create() { auto fModelGeometry = FactoryManager::ref().factory(); ghoul_assert(fModelGeometry, "Model geometry factory was not created"); fModelGeometry->registerClass("WavefrontGeometry"); - - return true; } } // namespace openspace diff --git a/modules/base/basemodule.h b/modules/base/basemodule.h index 597e6cf2af..1feaf32c99 100644 --- a/modules/base/basemodule.h +++ b/modules/base/basemodule.h @@ -32,7 +32,9 @@ namespace openspace { class BaseModule : public OpenSpaceModule { public: BaseModule(); - bool create() override; + +protected: + void internalCreate() override; }; } // namespace openspace diff --git a/modules/fieldlines/fieldlinesmodule.cpp b/modules/fieldlines/fieldlinesmodule.cpp index 4fcba99081..b0be3c52a3 100644 --- a/modules/fieldlines/fieldlinesmodule.cpp +++ b/modules/fieldlines/fieldlinesmodule.cpp @@ -37,17 +37,11 @@ FieldlinesModule::FieldlinesModule() : OpenSpaceModule("Fieldlines") {} -bool FieldlinesModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - +void FieldlinesModule::internalCreate() { auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "No renderable factory existed"); fRenderable->registerClass("RenderableFieldlines"); - - return true; } } // namespace openspace diff --git a/modules/fieldlines/fieldlinesmodule.h b/modules/fieldlines/fieldlinesmodule.h index 8edc1d6705..50deb9984d 100644 --- a/modules/fieldlines/fieldlinesmodule.h +++ b/modules/fieldlines/fieldlinesmodule.h @@ -32,7 +32,9 @@ namespace openspace { class FieldlinesModule : public OpenSpaceModule { public: FieldlinesModule(); - bool create() override; + +protected: + void internalCreate() override; }; } // namespace openspace diff --git a/modules/kameleon/kameleonmodule.cpp b/modules/kameleon/kameleonmodule.cpp index 1000b27184..244d86e513 100644 --- a/modules/kameleon/kameleonmodule.cpp +++ b/modules/kameleon/kameleonmodule.cpp @@ -30,12 +30,4 @@ KameleonModule::KameleonModule() : OpenSpaceModule("Kameleon") {} -bool KameleonModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - - return true; -} - } // namespace openspace diff --git a/modules/kameleon/kameleonmodule.h b/modules/kameleon/kameleonmodule.h index b99b5d3f77..979aba5dd9 100644 --- a/modules/kameleon/kameleonmodule.h +++ b/modules/kameleon/kameleonmodule.h @@ -32,7 +32,6 @@ namespace openspace { class KameleonModule : public OpenSpaceModule { public: KameleonModule(); - bool create() override; }; } // namespace openspace diff --git a/modules/newhorizons/newhorizonsmodule.cpp b/modules/newhorizons/newhorizonsmodule.cpp index 9d5b3967a4..f5b30cc86e 100644 --- a/modules/newhorizons/newhorizonsmodule.cpp +++ b/modules/newhorizons/newhorizonsmodule.cpp @@ -50,11 +50,7 @@ NewHorizonsModule::NewHorizonsModule() : OpenSpaceModule("NewHorizons") {} -bool NewHorizonsModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - +void NewHorizonsModule::internalCreate() { ImageSequencer2::initialize(); FactoryManager::ref().addFactory(new ghoul::TemplateFactory); @@ -76,8 +72,6 @@ bool NewHorizonsModule::create() { auto fDecoder = FactoryManager::ref().factory(); fDecoder->registerClass("Instrument"); fDecoder->registerClass("Target"); - - return true; } } // namespace openspace diff --git a/modules/newhorizons/newhorizonsmodule.h b/modules/newhorizons/newhorizonsmodule.h index 6ca4b49cda..f721f743b1 100644 --- a/modules/newhorizons/newhorizonsmodule.h +++ b/modules/newhorizons/newhorizonsmodule.h @@ -32,7 +32,9 @@ namespace openspace { class NewHorizonsModule : public OpenSpaceModule { public: NewHorizonsModule(); - bool create() override; + +protected: + void internalCreate() override; }; } // namespace openspace diff --git a/modules/onscreengui/onscreenguimodule.cpp b/modules/onscreengui/onscreenguimodule.cpp index 8518eef832..f34467f2bc 100644 --- a/modules/onscreengui/onscreenguimodule.cpp +++ b/modules/onscreengui/onscreenguimodule.cpp @@ -30,11 +30,4 @@ OnScreenGUIModule::OnScreenGUIModule() : OpenSpaceModule("OnScreenGUI") {} -bool OnScreenGUIModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - return true; -} - } // namespace openspace diff --git a/modules/onscreengui/onscreenguimodule.h b/modules/onscreengui/onscreenguimodule.h index affd7bb9d5..7ea96650b2 100644 --- a/modules/onscreengui/onscreenguimodule.h +++ b/modules/onscreengui/onscreenguimodule.h @@ -32,7 +32,6 @@ namespace openspace { class OnScreenGUIModule : public OpenSpaceModule { public: OnScreenGUIModule(); - bool create() override; }; } // namespace openspace diff --git a/modules/volume/volumemodule.cpp b/modules/volume/volumemodule.cpp index 274e408f6f..f2ff8b6b43 100644 --- a/modules/volume/volumemodule.cpp +++ b/modules/volume/volumemodule.cpp @@ -37,17 +37,11 @@ VolumeModule::VolumeModule() : OpenSpaceModule("Volume") {} -bool VolumeModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - +void VolumeModule::internalCreate() { auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "No renderable factory existed"); fRenderable->registerClass("RenderableVolumeGL"); - - return true; } } // namespace openspace diff --git a/modules/volume/volumemodule.h b/modules/volume/volumemodule.h index 1e57079063..415056c1e5 100644 --- a/modules/volume/volumemodule.h +++ b/modules/volume/volumemodule.h @@ -32,7 +32,9 @@ namespace openspace { class VolumeModule : public OpenSpaceModule { public: VolumeModule(); - bool create() override; + +protected: + void internalCreate() override; }; } // namespace openspace diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index b6fb131298..fe8c24987c 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -27,86 +27,109 @@ #include #include +#include #include #include -namespace { - const std::string _loggerCat = "ConfigurationManager"; +using std::string; - const std::string _keyBasePath = "BASE_PATH"; +namespace { + const string _configurationFile = "openspace.cfg"; + const string _keyBasePath = "BASE_PATH"; } namespace openspace { -const std::string ConfigurationManager::KeyPaths = "Paths"; -const std::string ConfigurationManager::KeyCache = "CACHE"; -const std::string ConfigurationManager::KeyCachePath = KeyPaths + "." + KeyCache; -const std::string ConfigurationManager::KeyFonts = "Fonts"; -const std::string ConfigurationManager::KeyConfigSgct = "SGCTConfig"; -const std::string ConfigurationManager::KeyLuaDocumentationType = "LuaDocumentationFile.Type"; -const std::string ConfigurationManager::KeyLuaDocumentationFile = "LuaDocumentationFile.File"; -const std::string ConfigurationManager::KeyPropertyDocumentationType = "PropertyDocumentationFile.Type"; -const std::string ConfigurationManager::KeyPropertyDocumentationFile = "PropertyDocumentationFile.File"; -const std::string ConfigurationManager::KeyConfigScene = "Scene"; -const std::string ConfigurationManager::KeyEnableGui = "EnableGUI"; -const std::string ConfigurationManager::KeyStartupScript = "StartupScripts"; -const std::string ConfigurationManager::KeySettingsScript = "SettingsScripts"; -const std::string ConfigurationManager::KeySpiceTimeKernel = "SpiceKernel.Time"; -const std::string ConfigurationManager::KeySpiceLeapsecondKernel = "SpiceKernel.LeapSecond"; -const std::string ConfigurationManager::KeyLogLevel = "Logging.LogLevel"; -const std::string ConfigurationManager::KeyLogImmediateFlush = "Logging.ImmediateFlush"; -const std::string ConfigurationManager::KeyLogs = "Logging.Logs"; -const std::string ConfigurationManager::KeyCapabilitiesVerbosity = "Logging.CapabilitiesVerbosity"; -const std::string ConfigurationManager::KeyDisableMasterRendering = "DisableRenderingOnMaster"; -const std::string ConfigurationManager::KeyDownloadRequestURL = "DownloadRequestURL"; +const string ConfigurationManager::KeyPaths = "Paths"; +const string ConfigurationManager::KeyCache = "CACHE"; +const string ConfigurationManager::KeyFonts = "Fonts"; +const string ConfigurationManager::KeyConfigSgct = "SGCTConfig"; +const string ConfigurationManager::KeyLuaDocumentationType = "LuaDocumentationFile.Type"; +const string ConfigurationManager::KeyLuaDocumentationFile = "LuaDocumentationFile.File"; +const string ConfigurationManager::KeyPropertyDocumentationType = + "PropertyDocumentationFile.Type"; +const string ConfigurationManager::KeyPropertyDocumentationFile = + "PropertyDocumentationFile.File"; +const string ConfigurationManager::KeyConfigScene = "Scene"; +const string ConfigurationManager::KeyEnableGui = "EnableGUI"; +const string ConfigurationManager::KeyStartupScript = "StartupScripts"; +const string ConfigurationManager::KeySettingsScript = "SettingsScripts"; +const string ConfigurationManager::KeySpiceTimeKernel = "SpiceKernel.Time"; +const string ConfigurationManager::KeySpiceLeapsecondKernel = "SpiceKernel.LeapSecond"; +const string ConfigurationManager::KeyLogLevel = "Logging.LogLevel"; +const string ConfigurationManager::KeyLogImmediateFlush = "Logging.ImmediateFlush"; +const string ConfigurationManager::KeyLogs = "Logging.Logs"; +const string ConfigurationManager::KeyCapabilitiesVerbosity = + "Logging.CapabilitiesVerbosity"; +const string ConfigurationManager::KeyDisableMasterRendering = "DisableRenderingOnMaster"; +const string ConfigurationManager::KeyDownloadRequestURL = "DownloadRequestURL"; -bool ConfigurationManager::loadFromFile(const std::string& filename) { +string ConfigurationManager::findConfiguration(const string& filename) { + using ghoul::filesystem::Directory; + + Directory directory = FileSys.currentDirectory(); + std::string configurationName = _configurationFile; + + while (true) { + std::string&& fullPath = FileSys.pathByAppendingComponent(directory, + configurationName); + bool exists = FileSys.fileExists(fullPath); + if (exists) + return fullPath; + + Directory nextDirectory = directory.parentDirectory(true); + + if (directory.path() == nextDirectory.path()) { + // We have reached the root of the file system and did not find the file + throw ghoul::RuntimeError( + "Could not find configuration file '" + filename + "'", + "ConfigurationManager" + ); + } + directory = nextDirectory; + } +} + +void ConfigurationManager::loadFromFile(const string& filename) { using ghoul::filesystem::FileSystem; - if (!FileSys.fileExists(filename)) { - LERROR("Could not find file '" << filename << "'"); - return false; - } + + if (!FileSys.fileExists(filename)) + throw ghoul::FileNotFoundError(filename, "ConfigurationManager"); // ${BASE_PATH} - std::string&& basePathToken = FileSystem::TokenOpeningBraces + _keyBasePath + string basePathToken = FileSystem::TokenOpeningBraces + _keyBasePath + FileSystem::TokenClosingBraces; // Retrieving the directory in which the configuration file lies - std::string absolutePath = FileSys.absolutePath(filename); - std::string basePath = ghoul::filesystem::File(absolutePath).directoryName(); + string absolutePath = FileSys.absolutePath(filename); + string basePath = ghoul::filesystem::File(absolutePath).directoryName(); FileSys.registerPathToken(basePathToken, basePath); // Loading the configuration file into ourselves - try { - ghoul::lua::loadDictionaryFromFile(filename, *this); - } - catch (...) { - LERROR("Loading dictionary from file failed"); - return false; - } + ghoul::lua::loadDictionaryFromFile(filename, *this); // Register all the paths - ghoul::Dictionary dictionary; - const bool success = getValue(KeyPaths, dictionary); - if (!success) { - LERROR("Configuration does not contain the key '" << KeyPaths << "'"); - return false; - } +// const bool hasPath = hasKeyAndValue(KeyPaths); +// if (!hasPath) { +// throw ghoul::RuntimeError( +// "Configuration does not contain the key '" + KeyPaths + "'", +// "ConfifgurationManager" +// ); +// } + ghoul::Dictionary dictionary = value(KeyPaths); std::vector pathKeys = dictionary.keys(); for (std::string key : pathKeys) { std::string p; if (dictionary.getValue(key, p)) { - std::string fullKey - = FileSystem::TokenOpeningBraces + key - + FileSystem::TokenClosingBraces; - LDEBUG("Registering path " << fullKey << ": " << p); + std::string fullKey = + FileSystem::TokenOpeningBraces + key + FileSystem::TokenClosingBraces; + LDEBUGC("ConfigurationManager", "Registering path " << fullKey << ": " << p); bool override = (basePathToken == fullKey); - if (override) - LINFO("Overriding base path with '" << p << "'"); + LINFOC("ConfigurationManager", "Overriding base path with '" << p << "'"); FileSys.registerPathToken(std::move(fullKey), std::move(p), override); } } @@ -125,7 +148,7 @@ bool ConfigurationManager::loadFromFile(const std::string& filename) { bool ConfigurationManager::checkCompleteness() const { std::vector requiredTokens = { KeyPaths, - KeyCachePath, + KeyPaths + "." + KeyCache, KeyFonts, KeyConfigSgct }; @@ -134,8 +157,12 @@ bool ConfigurationManager::checkCompleteness() const { for (const std::string& token : requiredTokens) { bool success = hasKey(token); - if (!success) - LFATAL("Configuration file did not contain required key '" << token << "'"); + if (!success) { + LFATALC( + "ConfigurationManager", + "Configuration file did not contain required key '" << token << "'" + ); + } totalSuccess &= success; } diff --git a/src/engine/downloadmanager.cpp b/src/engine/downloadmanager.cpp index 884831dbdd..7b038a11b1 100644 --- a/src/engine/downloadmanager.cpp +++ b/src/engine/downloadmanager.cpp @@ -62,9 +62,8 @@ namespace { } - int xferinfo(void* p, - curl_off_t dltotal, curl_off_t dlnow, - curl_off_t ultotal, curl_off_t ulnow) + int xferinfo(void* p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, + curl_off_t ulnow) { if (dltotal == 0) return 0; @@ -121,43 +120,39 @@ DownloadManager::FileFuture::FileFuture(std::string file) , abortDownload(false) {} -DownloadManager::DownloadManager(std::string requestURL, int applicationVersion) - : _requestURL(std::move(requestURL)) - , _applicationVersion(std::move(applicationVersion)) +DownloadManager::DownloadManager(std::string requestURL, int applicationVersion, + bool useMultithreadedDownload) + : _applicationVersion(std::move(applicationVersion)) + , _useMultithreadedDownload(useMultithreadedDownload) { curl_global_init(CURL_GLOBAL_ALL); + + _requestURL.push_back(std::move(requestURL)); + // TODO: Check if URL is accessible ---abock // TODO: Allow for multiple requestURLs } DownloadManager::FileFuture* DownloadManager::downloadFile( - const std::string& url, - const ghoul::filesystem::File& file, - bool overrideFile, - DownloadFinishedCallback finishedCallback, - DownloadProgressCallback progressCallback) + const std::string& url, const ghoul::filesystem::File& file, bool overrideFile, + DownloadFinishedCallback finishedCallback, DownloadProgressCallback progressCallback) { if (!overrideFile && FileSys.fileExists(file)) return nullptr; - FileFuture* future = new FileFuture( - file.filename() - ); + FileFuture* future = new FileFuture(file.filename()); FILE* fp = fopen(file.path().c_str(), "wb"); - LDEBUG("Starting download for file: '" << url << - "' into file '" << file.path() << "'"); + LDEBUG("Start downloading file: '" << url << "' into file '" << file.path() << "'"); -#ifdef USE_MULTITHREADED_DOWNLOAD - std::thread t = std::thread([url, finishedCallback, progressCallback, future, fp]() { -#endif + auto downloadFunction = [url, finishedCallback, progressCallback, future, fp]() { CURL* curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeData); - + ProgressInformation p = { future, std::chrono::system_clock::now(), @@ -166,49 +161,51 @@ DownloadManager::FileFuture* DownloadManager::downloadFile( curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo); curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &p); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); - + CURLcode res = curl_easy_perform(curl); curl_easy_cleanup(curl); fclose(fp); - + if (res == CURLE_OK) future->isFinished = true; else future->errorMessage = curl_easy_strerror(res); - + if (finishedCallback) finishedCallback(*future); } -#ifdef USE_MULTITHREADED_DOWNLOAD - }); - + }; + + if (_useMultithreadedDownload) { + std::thread t = std::thread(downloadFunction); + #ifdef WIN32 - std::thread::native_handle_type h = t.native_handle(); - SetPriorityClass(h, IDLE_PRIORITY_CLASS); - SetThreadPriority(h, THREAD_PRIORITY_LOWEST); + std::thread::native_handle_type h = t.native_handle(); + SetPriorityClass(h, IDLE_PRIORITY_CLASS); + SetThreadPriority(h, THREAD_PRIORITY_LOWEST); #else - // TODO: Implement thread priority ---abock + // TODO: Implement thread priority ---abock #endif - - t.detach(); -#endif // USE_MULTITHREADED_DOWNLOAD - + + t.detach(); + } + else { + downloadFunction(); + } + return future; } std::vector DownloadManager::downloadRequestFiles( - const std::string& identifier, - const ghoul::filesystem::Directory& destination, - int version, - bool overrideFiles, - DownloadFinishedCallback finishedCallback, + const std::string& identifier, const ghoul::filesystem::Directory& destination, + int version, bool overrideFiles, DownloadFinishedCallback finishedCallback, DownloadProgressCallback progressCallback) { std::vector futures; FileSys.createDirectory(destination, true); // TODO: Check s ---abock // TODO: Escaping is necessary ---abock - const std::string fullRequest =_requestURL + "?" + + const std::string fullRequest =_requestURL.back() + "?" + RequestIdentifier + "=" + identifier + "&" + RequestFileVersion + "=" + std::to_string(version) + "&" + RequestApplicationVersion + "=" + std::to_string(_applicationVersion); @@ -259,37 +256,36 @@ std::vector DownloadManager::downloadRequestFiles( return futures; } -void DownloadManager::downloadRequestFilesAsync( - const std::string& identifier, - const ghoul::filesystem::Directory& destination, - int version, - bool overrideFiles, +void DownloadManager::downloadRequestFilesAsync(const std::string& identifier, + const ghoul::filesystem::Directory& destination, int version, bool overrideFiles, AsyncDownloadFinishedCallback callback) { -#ifdef USE_MULTITHREADED_DOWNLOAD - std::thread t = std::thread([this, identifier, destination, version, overrideFiles, callback](){ -#endif + auto downloadFunction = [this, identifier, destination, version, overrideFiles, callback](){ std::vector f = downloadRequestFiles( identifier, destination, version, overrideFiles ); - + callback(f); -#ifdef USE_MULTITHREADED_DOWNLOAD - }); - + }; + + if (_useMultithreadedDownload) { + std::thread t = std::thread(downloadFunction); + #ifdef WIN32 - std::thread::native_handle_type h = t.native_handle(); - SetPriorityClass(h, IDLE_PRIORITY_CLASS); - SetThreadPriority(h, THREAD_PRIORITY_LOWEST); + std::thread::native_handle_type h = t.native_handle(); + SetPriorityClass(h, IDLE_PRIORITY_CLASS); + SetThreadPriority(h, THREAD_PRIORITY_LOWEST); #else - // TODO: Implement thread priority ---abock + // TODO: Implement thread priority ---abock #endif - - t.detach(); -#endif // USE_MULTITHREADED_DOWNLOAD + + t.detach(); + } + else + downloadFunction(); } } // namespace openspace diff --git a/src/engine/moduleengine.cpp b/src/engine/moduleengine.cpp index d6888df8f9..520b7385e0 100644 --- a/src/engine/moduleengine.cpp +++ b/src/engine/moduleengine.cpp @@ -36,40 +36,30 @@ namespace { namespace openspace { -bool ModuleEngine::create() { +void ModuleEngine::create() { LDEBUG("Creating modules"); - registerModules(AllModules); + for (OpenSpaceModule* m : AllModules) + registerModule(std::unique_ptr(m)); - for (OpenSpaceModule* m : _modules) { - bool success = m->create(); - if (!success) { - LERROR("Could not initialize module '" << m->name() << "'"); - return false; - } - } + for (auto& m : _modules) + m->create(); LDEBUG("Finished creating modules"); return true; } -bool ModuleEngine::destroy() { +void ModuleEngine::destroy() { LDEBUG("Destroying modules"); - for (OpenSpaceModule* m : _modules) { - bool success = m->destroy(); - if (!success) { - LERROR("Could not deinitialize module '" << m->name() << "'"); - return false; - } - delete m; - } + for (auto& m : _modules) + m->destroy(); + _modules.clear(); LDEBUG("Finished destroying modules"); - return true; } bool ModuleEngine::initialize() { LDEBUG("Initializing modules"); - for (OpenSpaceModule* m : _modules) { + for (auto& m : _modules) { bool success = m->initialize(); if (!success) { LERROR("Could not initialize module '" << m->name() << "'"); @@ -83,7 +73,7 @@ bool ModuleEngine::initialize() { bool ModuleEngine::deinitialize() { LDEBUG("Deinitializing modules"); - for (OpenSpaceModule* m : _modules) { + for (auto& m : _modules) { bool success = m->deinitialize(); if (!success) { LERROR("Could not deinitialize module '" << m->name() << "'"); @@ -94,16 +84,23 @@ bool ModuleEngine::deinitialize() { return true; } -void ModuleEngine::registerModules(std::vector modules) { - _modules.insert(_modules.end(), modules.begin(), modules.end()); +void ModuleEngine::registerModules(std::vector> modules) { + _modules.insert( + _modules.end(), + std::make_move_iterator(modules.begin()), + std::make_move_iterator(modules.end()) + ); } -void ModuleEngine::registerModule(OpenSpaceModule* module) { +void ModuleEngine::registerModule(std::unique_ptr module) { _modules.push_back(std::move(module)); } -const std::vector ModuleEngine::modules() const { - return _modules; +std::vector ModuleEngine::modules() const { + std::vector result; + for (auto& m : _modules) + result.push_back(m.get()); + return result; } } // namespace openspace diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index b6e0e49533..18065662b7 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -77,7 +77,6 @@ using namespace ghoul::cmdparser; namespace { const std::string _loggerCat = "OpenSpaceEngine"; - const std::string _configurationFile = "openspace.cfg"; const std::string _sgctDefaultConfigFile = "${SGCT}/single.xml"; const std::string _defaultCacheLocation = "${BASE_PATH}/cache"; @@ -199,24 +198,27 @@ bool OpenSpaceEngine::create(int argc, char** argv, std::string configurationFilePath = commandlineArgumentPlaceholders.configurationName; if (configurationFilePath.empty()) { LDEBUG("Finding configuration"); - const bool findConfigurationSuccess = - OpenSpaceEngine::findConfiguration(configurationFilePath); - if (!findConfigurationSuccess) { - LFATAL("Could not find OpenSpace configuration file!"); - return false; - } + try { + configurationFilePath = + ConfigurationManager::findConfiguration(configurationFilePath); + } + catch (const ghoul::RuntimeError& e) { + LFATALC(e.component, e.message); + } } configurationFilePath = absPath(configurationFilePath); LINFO("Configuration Path: '" << configurationFilePath << "'"); // Loading configuration from disk LDEBUG("Loading configuration from disk"); - const bool configLoadSuccess = _engine->configurationManager().loadFromFile( - configurationFilePath); - if (!configLoadSuccess) { - LFATAL("Loading of configuration file '" << configurationFilePath << "' failed"); - return false; - } + try { + _engine->configurationManager().loadFromFile(configurationFilePath); + } + catch (const ghoul::RuntimeError& e) { + LFATAL("Loading of configuration file '" << configurationFilePath << "' failed"); + LFATALC(e.component, e.message); + return false; + } // Initialize the requested logs from the configuration file _engine->configureLogging(); @@ -427,30 +429,6 @@ bool OpenSpaceEngine::gatherCommandlineArguments() { return true; } -bool OpenSpaceEngine::findConfiguration(std::string& filename) { - using ghoul::filesystem::Directory; - - Directory directory = FileSys.currentDirectory(); - std::string configurationName = _configurationFile; - - while (true) { - std::string&& fullPath = FileSys.pathByAppendingComponent(directory, - configurationName); - bool exists = FileSys.fileExists(fullPath); - if (exists) { - filename = fullPath; - return true; - } - - Directory nextDirectory = directory.parentDirectory(true); - - if (directory.path() == nextDirectory.path()) - // We have reached the root of the file system and did not find the file - return false; - directory = nextDirectory; - } -} - bool OpenSpaceEngine::loadSpiceKernels() { // Load time kernel std::string timeKernel; diff --git a/src/util/openspacemodule.cpp b/src/util/openspacemodule.cpp index 35a3dee439..c95375e449 100644 --- a/src/util/openspacemodule.cpp +++ b/src/util/openspacemodule.cpp @@ -43,7 +43,7 @@ OpenSpaceModule::OpenSpaceModule(std::string name) ghoul_assert(!_name.empty(), "Empty module name is not allowed"); } -bool OpenSpaceModule::create() { +void OpenSpaceModule::create() { std::string moduleNameUpper = name(); std::transform(moduleNameUpper.begin(), moduleNameUpper.end(), moduleNameUpper.begin(), toupper); std::string moduleToken = @@ -55,11 +55,12 @@ bool OpenSpaceModule::create() { std::string path = modulePath(); LDEBUG("Registering module path: " << moduleToken << ": " << path); FileSys.registerPathToken(moduleToken, path); - return true; + + internalCreate(); } -bool OpenSpaceModule::destroy() { - return true; +void OpenSpaceModule::destroy() { + internalDestroy(); } std::string OpenSpaceModule::name() const { @@ -81,12 +82,18 @@ std::string OpenSpaceModule::modulePath() const { } bool OpenSpaceModule::initialize() { + internalInitialize(); return true; } bool OpenSpaceModule::deinitialize() { + internalDeinitialize(); return true; } - + +void OpenSpaceModule::internalCreate() {} +void OpenSpaceModule::internalDestroy() {} +void OpenSpaceModule::internalInitialize() {} +void OpenSpaceModule::internalDeinitialize() {} } // namespace openspace