mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-12 14:29:42 -05:00
Feature/configuration codegen (#1544)
Convert configuration document over to codegen
This commit is contained in:
committed by
Alexander Bock
parent
48e2f35aa1
commit
0d82e1848f
+7
-12
@@ -1105,22 +1105,17 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
LINFO(fmt::format("Configuration Path: '{}'", configurationFilePath));
|
||||
|
||||
// Register the base path as the directory where the configuration file lives
|
||||
std::string base = ghoul::filesystem::File(configurationFilePath).directoryName();
|
||||
constexpr const char* BasePathToken = "${BASE}";
|
||||
FileSys.registerPathToken(BasePathToken, base);
|
||||
|
||||
// Loading configuration from disk
|
||||
LDEBUG("Loading configuration from disk");
|
||||
*global::configuration = configuration::loadConfigurationFromFile(
|
||||
configurationFilePath
|
||||
configurationFilePath,
|
||||
commandlineArguments.configurationOverride
|
||||
);
|
||||
// If the user requested a commandline-based configuration script that should
|
||||
// overwrite some of the values, this is the time to do it
|
||||
if (!commandlineArguments.configurationOverride.empty()) {
|
||||
LDEBUG("Executing Lua script passed through the commandline:");
|
||||
LDEBUG(commandlineArguments.configurationOverride);
|
||||
ghoul::lua::runScript(
|
||||
global::configuration->state,
|
||||
commandlineArguments.configurationOverride
|
||||
);
|
||||
parseLuaState(*global::configuration);
|
||||
}
|
||||
|
||||
// Determining SGCT configuration file
|
||||
LDEBUG("SGCT Configuration file: " + global::configuration->windowConfiguration);
|
||||
|
||||
@@ -43,7 +43,6 @@ struct Configuration {
|
||||
Configuration& operator=(Configuration&&) = default;
|
||||
|
||||
std::string windowConfiguration = "${CONFIG}/single.xml";
|
||||
std::string sgctConfigNameInitialized;
|
||||
std::string asset;
|
||||
std::string profile;
|
||||
std::vector<std::string> readOnlyProfiles;
|
||||
@@ -93,7 +92,6 @@ struct Configuration {
|
||||
glm::dvec3 screenSpaceRotation = glm::dvec3(0.0);
|
||||
glm::dvec3 masterRotation = glm::dvec3(0.0);
|
||||
bool isConsoleDisabled = false;
|
||||
bool usingProfile = false;
|
||||
bool bypassLauncher = false;
|
||||
|
||||
std::map<std::string, ghoul::Dictionary> moduleConfigurations;
|
||||
@@ -123,6 +121,9 @@ struct Configuration {
|
||||
};
|
||||
HTTPProxy httpProxy;
|
||||
|
||||
// Values not read from the openspace.cfg file
|
||||
bool usingProfile = false;
|
||||
std::string sgctConfigNameInitialized;
|
||||
|
||||
static documentation::Documentation Documentation;
|
||||
ghoul::lua::LuaState state;
|
||||
@@ -130,9 +131,8 @@ struct Configuration {
|
||||
|
||||
std::string findConfiguration(const std::string& filename = "openspace.cfg");
|
||||
|
||||
Configuration loadConfigurationFromFile(const std::string& filename);
|
||||
|
||||
void parseLuaState(Configuration& configuration);
|
||||
Configuration loadConfigurationFromFile(const std::string& filename,
|
||||
const std::string& overrideScript);
|
||||
|
||||
} // namespace openspace::configuration
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/documentation/documentationgenerator.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/documentation/verifier.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/engine/configuration.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/engine/configuration_doc.inl
|
||||
${OPENSPACE_BASE_DIR}/src/engine/downloadmanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/engine/globals.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/engine/globalscallbacks.cpp
|
||||
|
||||
+539
-281
@@ -27,287 +27,304 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/lua/ghoul_lua.h>
|
||||
#include <ghoul/lua/lua_helper.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <optional>
|
||||
|
||||
namespace {
|
||||
constexpr const char* BasePathToken = "${BASE}";
|
||||
// We can't use ${SCRIPTS} here as that hasn't been defined by this point
|
||||
constexpr const char* InitialConfigHelper =
|
||||
"${BASE}/scripts/configuration_helper.lua";
|
||||
|
||||
// Variable names for the openspace.cfg file
|
||||
// These are also used in the _doc include file
|
||||
constexpr const char* KeySGCTConfig = "SGCTConfig";
|
||||
constexpr const char* KeyAsset = "Asset";
|
||||
constexpr const char* KeyProfile = "Profile";
|
||||
constexpr const char* KeyGlobalCustomizationScripts = "GlobalCustomizationScripts";
|
||||
constexpr const char* KeyPaths = "Paths";
|
||||
constexpr const char* KeyFonts = "Fonts";
|
||||
constexpr const char* KeyLogging = "Logging";
|
||||
constexpr const char* KeyLogDir = "LogDir";
|
||||
constexpr const char* KeyPerformancePrefix = "PerformancePrefix";
|
||||
constexpr const char* KeyLogLevel = "LogLevel";
|
||||
constexpr const char* KeyImmediateFlush = "ImmediateFlush";
|
||||
constexpr const char* KeyLogs = "Logs";
|
||||
constexpr const char* KeyCapabilitiesVerbosity = "CapabilitiesVerbosity";
|
||||
constexpr const char* KeyDocumentationPath = "Path";
|
||||
constexpr const char* KeyDocumentation = "Documentation";
|
||||
constexpr const char* KeyScriptLog = "ScriptLog";
|
||||
constexpr const char* KeyShutdownCountdown = "ShutdownCountdown";
|
||||
constexpr const char* KeyPerSceneCache = "PerSceneCache";
|
||||
constexpr const char* KeyOnScreenTextScaling = "OnScreenTextScaling";
|
||||
constexpr const char* KeyRenderingMethod = "RenderingMethod";
|
||||
constexpr const char* KeyDisableRenderingOnMaster = "DisableRenderingOnMaster";
|
||||
constexpr const char* KeyGlobalRotation = "GlobalRotation";
|
||||
constexpr const char* KeyScreenSpaceRotation = "ScreenSpaceRotation";
|
||||
constexpr const char* KeyMasterRotation = "MasterRotation";
|
||||
constexpr const char* KeyDisableInGameConsole = "DisableInGameConsole";
|
||||
constexpr const char* KeyScreenshotUseDate = "ScreenshotUseDate";
|
||||
constexpr const char* KeyHttpProxy = "HttpProxy";
|
||||
constexpr const char* KeyAddress = "Address";
|
||||
constexpr const char* KeyPort = "Port";
|
||||
constexpr const char* KeyAuthentication = "Authentication";
|
||||
constexpr const char* KeyUser = "User";
|
||||
constexpr const char* KeyPassword = "Password";
|
||||
constexpr const char* KeyOpenGLDebugContext = "OpenGLDebugContext";
|
||||
constexpr const char* KeyActivate = "Activate";
|
||||
constexpr const char* KeySynchronous = "Synchronous";
|
||||
constexpr const char* KeyFilterIdentifier = "FilterIdentifier";
|
||||
constexpr const char* KeyIdentifier = "Identifier";
|
||||
constexpr const char* KeySource = "Source";
|
||||
constexpr const char* KeyType = "Type";
|
||||
constexpr const char* KeyFilterSeverity = "FilterSeverity";
|
||||
constexpr const char* KeyCheckOpenGLState = "CheckOpenGLState";
|
||||
constexpr const char* KeyLogEachOpenGLCall = "LogEachOpenGLCall";
|
||||
constexpr const char* KeyVersionCheckUrl = "VersionCheckUrl";
|
||||
constexpr const char* KeyUseMultithreadedInitialization =
|
||||
"UseMultithreadedInitialization";
|
||||
constexpr const char* KeyLoadingScreen = "LoadingScreen";
|
||||
constexpr const char* KeyShowMessage = "ShowMessage";
|
||||
constexpr const char* KeyShowNodeNames = "ShowNodeNames";
|
||||
constexpr const char* KeyShowProgressbar = "ShowProgressbar";
|
||||
constexpr const char* KeyModuleConfigurations = "ModuleConfigurations";
|
||||
struct [[codegen::Dictionary(Configuration)]] Parameters {
|
||||
// The SGCT configuration file that determines the window and view frustum
|
||||
// settings that are being used when OpenSpace is started
|
||||
std::optional<std::string> windowConfiguration [[codegen::key("SGCTConfig")]];
|
||||
|
||||
constexpr const char* KeySgctConfigNameInitialized = "sgctconfiginitializeString";
|
||||
constexpr const char* KeyReadOnlyProfiles = "ReadOnlyProfiles";
|
||||
constexpr const char* KeyBypassLauncher = "BypassLauncher";
|
||||
// The scene description that is used to populate the application after startup.
|
||||
// The scene determines which objects are loaded, the startup time and other
|
||||
// scene-specific settings. More information is provided in the Scene
|
||||
// documentation. If the 'Asset' and the 'Profile' values are specified, the asset
|
||||
// is silently ignored
|
||||
std::optional<std::string> asset;
|
||||
|
||||
template <typename T>
|
||||
void getValue(ghoul::lua::LuaState& L, const char* name, T& value) {
|
||||
using namespace openspace::configuration;
|
||||
// The profile that should be loaded at the startup. The profile determines which
|
||||
// assets are loaded, the startup time, keyboard shortcuts, and other settings.
|
||||
std::optional<std::string> profile;
|
||||
|
||||
auto it = std::find_if(
|
||||
Configuration::Documentation.entries.begin(),
|
||||
Configuration::Documentation.entries.end(),
|
||||
[name](const openspace::documentation::DocumentationEntry& e) {
|
||||
return e.key == name;
|
||||
}
|
||||
);
|
||||
// This value names a list of scripts that get executed after initialization of
|
||||
// any scene. These scripts can be used for user-specific customization, such as a
|
||||
// global rebinding of keys from the default
|
||||
std::optional<std::vector<std::string>> globalCustomizationScripts;
|
||||
|
||||
bool isOptional =
|
||||
it != Configuration::Documentation.entries.end()
|
||||
? it->optional :
|
||||
true;
|
||||
// A list of paths that are automatically registered with the file system. If a
|
||||
// key X is used in the table, it is then useable by referencing ${X} in all other
|
||||
// configuration files or scripts
|
||||
std::map<std::string, std::string> paths;
|
||||
|
||||
lua_getglobal(L, name);
|
||||
if (isOptional && lua_isnil(L, -1)) {
|
||||
return;
|
||||
}
|
||||
// A list of all fonts that will automatically be loaded on startup. Each
|
||||
// key-value pair contained in the table will become the name and the file for a
|
||||
// font
|
||||
std::optional<std::map<std::string, std::string>> fonts;
|
||||
|
||||
if (!isOptional && lua_isnil(L, -1)) {
|
||||
openspace::documentation::TestResult testResult = {
|
||||
false,
|
||||
{ {
|
||||
name,
|
||||
openspace::documentation::TestResult::Offense::Reason::MissingKey
|
||||
}},
|
||||
{}
|
||||
struct Logging {
|
||||
// List from logmanager.cpp::levelFromString
|
||||
enum class Level {
|
||||
Trace,
|
||||
Debug,
|
||||
Info,
|
||||
Warning,
|
||||
Error,
|
||||
Fatal,
|
||||
None
|
||||
};
|
||||
throw openspace::documentation::SpecificationError(
|
||||
std::move(testResult),
|
||||
"Configuration"
|
||||
);
|
||||
}
|
||||
// The severity of log messages that will be displayed. Only messages of the
|
||||
// selected level or higher will be displayed. All levels below will be
|
||||
// silently discarded. The order of severities is:
|
||||
// Debug < Info < Warning < Error < Fatal < None.
|
||||
std::optional<Level> logLevel;
|
||||
|
||||
if constexpr (std::is_same_v<T, glm::dvec3>) {
|
||||
ghoul::Dictionary d = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
glm::dvec3 res;
|
||||
res.x = d.value<double>("1");
|
||||
res.y = d.value<double>("2");
|
||||
res.z = d.value<double>("3");
|
||||
value = res;
|
||||
}
|
||||
// NOLINTNEXTLINE
|
||||
else if constexpr (std::is_same_v<T, std::vector<std::string>>) {
|
||||
ghoul::Dictionary d = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
// Determines whether error messages will be displayed immediately or if it is
|
||||
// acceptable to have a short delay, but being more performant. If the delay
|
||||
// is allowed ('true'), messages might get lost if the application crashes
|
||||
// shortly after a message was logged
|
||||
std::optional<bool> immediateFlush;
|
||||
|
||||
std::vector<std::string> res;
|
||||
for (size_t i = 1; i <= d.size(); ++i) {
|
||||
res.push_back(d.value<std::string>(std::to_string(i)));
|
||||
}
|
||||
value = std::move(res);
|
||||
}
|
||||
// NOLINTNEXTLINE
|
||||
else if constexpr (std::is_same_v<T, std::map<std::string, std::string>>) {
|
||||
ghoul::Dictionary d = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
// Per default, log messages are written to the console, the onscreen text,
|
||||
// and (if available) the Visual Studio output window. This table can define
|
||||
// other logging methods that will be used additionally
|
||||
std::optional<std::vector<ghoul::Dictionary>> logs
|
||||
[[codegen::reference("core_logfactory")]];
|
||||
|
||||
std::map<std::string, std::string> res;
|
||||
std::vector<std::string_view> keys = d.keys();
|
||||
for (size_t i = 0; i < d.size(); ++i) {
|
||||
std::string_view key = keys[i];
|
||||
std::string v = d.value<std::string>(key);
|
||||
res[std::string(key)] = std::move(v);
|
||||
}
|
||||
value = std::move(res);
|
||||
}
|
||||
// NOLINTNEXTLINE
|
||||
else if constexpr (std::is_same_v<T, std::map<std::string, ghoul::Dictionary>>) {
|
||||
ghoul::Dictionary d = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
// List from OpenspaceEngine::initialize
|
||||
enum class Verbosity {
|
||||
None,
|
||||
Minimal,
|
||||
Default,
|
||||
Full
|
||||
};
|
||||
// At startup, a list of system capabilities is created and logged. This value
|
||||
// determines how verbose this listing should be
|
||||
std::optional<Verbosity> capabilitiesVerbosity;
|
||||
};
|
||||
// Configurations for the logging of messages that are generated throughout the
|
||||
// code and are useful for debugging potential errors or other information
|
||||
std::optional<Logging> logging;
|
||||
|
||||
std::map<std::string, ghoul::Dictionary> res;
|
||||
std::vector<std::string_view> keys = d.keys();
|
||||
for (size_t i = 0; i < d.size(); ++i) {
|
||||
std::string_view key = keys[i];
|
||||
ghoul::Dictionary v = d.value<ghoul::Dictionary>(key);
|
||||
res[std::string(key)] = std::move(v);
|
||||
}
|
||||
value = std::move(res);
|
||||
}
|
||||
// NOLINTNEXTLINE
|
||||
else if constexpr (std::is_same_v<T, Configuration::Logging>) {
|
||||
Configuration::Logging& v = static_cast<Configuration::Logging&>(value);
|
||||
ghoul::Dictionary d = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
// The file that will be created on startup containing the log of all Lua scripts
|
||||
// that are executed in the last session. Any existing file (including the results
|
||||
// from previous runs) will be silently overwritten
|
||||
std::optional<std::string> scriptLog;
|
||||
|
||||
if (d.hasValue<std::string>(KeyLogLevel)) {
|
||||
v.level = d.value<std::string>(KeyLogLevel);
|
||||
}
|
||||
if (d.hasValue<bool>(KeyImmediateFlush)) {
|
||||
v.forceImmediateFlush = d.value<bool>(KeyImmediateFlush);
|
||||
}
|
||||
if (d.hasValue<std::string>(KeyCapabilitiesVerbosity)) {
|
||||
v.capabilitiesVerbosity = d.value<std::string>(KeyCapabilitiesVerbosity);
|
||||
}
|
||||
struct Documentation {
|
||||
// The path where the documentation files will be stored
|
||||
std::optional<std::string> path;
|
||||
};
|
||||
// Right now only contains the path where the documentation is written to
|
||||
std::optional<Documentation> documentation;
|
||||
|
||||
if (d.hasValue<ghoul::Dictionary>(KeyLogs)) {
|
||||
ghoul::Dictionary l = d.value<ghoul::Dictionary>(KeyLogs);
|
||||
std::vector<ghoul::Dictionary> res;
|
||||
for (size_t i = 1; i <= l.size(); ++i) {
|
||||
res.push_back(l.value<ghoul::Dictionary>(std::to_string(i)));
|
||||
}
|
||||
v.logs = res;
|
||||
}
|
||||
}
|
||||
// NOLINTNEXTLINE
|
||||
else if constexpr (std::is_same_v<T, Configuration::DocumentationInfo>) {
|
||||
Configuration::DocumentationInfo& v =
|
||||
static_cast<Configuration::DocumentationInfo&>(value);
|
||||
ghoul::Dictionary d = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
if (d.hasValue<std::string>(KeyDocumentationPath)) {
|
||||
v.path = d.value<std::string>(KeyDocumentationPath);
|
||||
}
|
||||
}
|
||||
// NOLINTNEXTLINE
|
||||
else if constexpr (std::is_same_v<T, Configuration::LoadingScreen>) {
|
||||
Configuration::LoadingScreen& v =
|
||||
static_cast<Configuration::LoadingScreen&>(value);
|
||||
ghoul::Dictionary d = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
if (d.hasValue<bool>(KeyShowMessage)) {
|
||||
v.isShowingMessages = d.value<bool>(KeyShowMessage);
|
||||
}
|
||||
if (d.hasValue<bool>(KeyShowNodeNames)) {
|
||||
v.isShowingNodeNames = d.value<bool>(KeyShowNodeNames);
|
||||
}
|
||||
if (d.hasValue<bool>(KeyShowProgressbar)) {
|
||||
v.isShowingProgressbar = d.value<bool>(KeyShowProgressbar);
|
||||
}
|
||||
}
|
||||
// NOLINTNEXTLINE
|
||||
else if constexpr (std::is_same_v<T, Configuration::OpenGLDebugContext>) {
|
||||
Configuration::OpenGLDebugContext& v =
|
||||
static_cast<Configuration::OpenGLDebugContext&>(value);
|
||||
ghoul::Dictionary d = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
// The countdown that the application will wait between pressing ESC and actually
|
||||
// shutting down. If ESC is pressed again in this time, the shutdown is aborted
|
||||
std::optional<float> shutdownCountdown [[codegen::greater(0.0)]];
|
||||
|
||||
if (d.hasValue<bool>(KeyActivate)) {
|
||||
v.isActive = d.value<bool>(KeyActivate);
|
||||
}
|
||||
if (d.hasValue<bool>(KeySynchronous)) {
|
||||
v.isSynchronous = d.value<bool>(KeySynchronous);
|
||||
}
|
||||
// If this is set to 'true', the name of the scene will be appended to the cache
|
||||
// directory, thus not reusing the same directory. This is useful in cases where
|
||||
// the same instance of OpenSpace is run with multiple scenes, but the caches
|
||||
// should be retained. This value defaults to 'false'
|
||||
std::optional<bool> perSceneCache;
|
||||
|
||||
if (d.hasValue<ghoul::Dictionary>(KeyFilterIdentifier)) {
|
||||
ghoul::Dictionary f = d.value<ghoul::Dictionary>(KeyFilterIdentifier);
|
||||
enum class Scaling {
|
||||
Window [[codegen::key("window")]],
|
||||
Framebuffer [[codegen::key("framebuffer")]]
|
||||
};
|
||||
// The method for scaling the onscreen text in the window. As the resolution of
|
||||
// the rendering can be different from the size of the window, the onscreen text
|
||||
// can either be scaled according to the window size ('window'), or the rendering
|
||||
// resolution ('framebuffer'). This value defaults to 'window'
|
||||
std::optional<Scaling> onScreenTextScaling;
|
||||
|
||||
std::vector<Configuration::OpenGLDebugContext::IdentifierFilter> res;
|
||||
for (size_t i = 1; i <= f.size(); ++i) {
|
||||
Configuration::OpenGLDebugContext::IdentifierFilter filter;
|
||||
ghoul::Dictionary fi = f.value<ghoul::Dictionary>(std::to_string(i));
|
||||
// List from RenderEngine::setRendererFromString
|
||||
enum class RenderingMethod {
|
||||
Framebuffer,
|
||||
ABuffer
|
||||
};
|
||||
// The renderer that is use after startup. The renderer 'ABuffer' requires support
|
||||
// for at least OpenGL 4.3
|
||||
std::optional<RenderingMethod> renderingMethod;
|
||||
|
||||
if (fi.hasValue<double>(KeyIdentifier)) {
|
||||
filter.identifier = static_cast<unsigned int>(
|
||||
fi.value<double>(KeyIdentifier)
|
||||
);
|
||||
}
|
||||
if (fi.hasValue<std::string>(KeySource)) {
|
||||
filter.source = fi.value<std::string>(KeySource);
|
||||
}
|
||||
if (fi.hasValue<std::string>(KeyType)) {
|
||||
filter.type = fi.value<std::string>(KeyType);
|
||||
}
|
||||
// Toggles whether the master in a multi-application setup should be rendering or
|
||||
// just managing the state of the network. This is desired in cases where the
|
||||
// master computer does not have the resources to render a scene
|
||||
std::optional<bool> disableRenderingOnMaster;
|
||||
|
||||
auto fff = filter;
|
||||
const auto ffg = filter;
|
||||
// Applies a global view rotation. Use this to rotate the position of the focus
|
||||
// node away from the default location on the screen. This setting persists even
|
||||
// when a new focus node is selected. Defined using roll, pitch, yaw in radians
|
||||
std::optional<glm::dvec3> globalRotation;
|
||||
|
||||
res.push_back(std::move(filter));
|
||||
}
|
||||
// Applies a view rotation for only the master node, defined using roll, pitch yaw
|
||||
// in radians. This can be used to compensate the master view direction for tilted
|
||||
// display systems in clustered immersive environments
|
||||
std::optional<glm::dvec3> masterRotation;
|
||||
|
||||
v.identifierFilters = res;
|
||||
}
|
||||
// Applies a global rotation for all screenspace renderables. Defined using roll,
|
||||
// pitch, yaw in radians
|
||||
std::optional<glm::dvec3> screenSpaceRotation;
|
||||
|
||||
if (d.hasValue<ghoul::Dictionary>(KeyFilterSeverity)) {
|
||||
ghoul::Dictionary f = d.value<ghoul::Dictionary>(KeyFilterSeverity);
|
||||
// If this value is set to 'true' the ingame console is disabled, locking the
|
||||
// system down against random access
|
||||
std::optional<bool> disableInGameConsole;
|
||||
|
||||
std::vector<std::string> res;
|
||||
for (size_t i = 1; i <= f.size(); ++i) {
|
||||
res.push_back(f.value<std::string>(std::to_string(i)));
|
||||
}
|
||||
v.severityFilters = res;
|
||||
}
|
||||
}
|
||||
// NOLINTNEXTLINE
|
||||
else if constexpr (std::is_same_v<T, Configuration::HTTPProxy>) {
|
||||
Configuration::HTTPProxy& v = static_cast<Configuration::HTTPProxy&>(value);
|
||||
ghoul::Dictionary d = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
// Toggles whether screenshots generated by OpenSpace contain the date when the
|
||||
// concrete OpenSpace instance was started. This value is enabled by default, but
|
||||
// it is advised to disable this value if rendering sessions of individual frames
|
||||
// pass beyond local midnight
|
||||
std::optional<bool> screenshotUseDate;
|
||||
|
||||
if (d.hasValue<bool>(KeyActivate)) {
|
||||
v.usingHttpProxy = d.value<bool>(KeyActivate);
|
||||
}
|
||||
if (d.hasValue<std::string>(KeyAddress)) {
|
||||
v.address = d.value<std::string>(KeyAddress);
|
||||
}
|
||||
if (d.hasValue<double>(KeyPort)) {
|
||||
v.port = static_cast<unsigned int>(d.value<double>(KeyPort));
|
||||
}
|
||||
if (d.hasValue<std::string>(KeyAuthentication)) {
|
||||
v.authentication = d.value<std::string>(KeyAuthentication);
|
||||
}
|
||||
if (d.hasValue<std::string>(KeyUser)) {
|
||||
v.user = d.value<std::string>(KeyUser);
|
||||
}
|
||||
if (d.hasValue<std::string>(KeyPassword)) {
|
||||
v.password = d.value<std::string>(KeyPassword);
|
||||
}
|
||||
}
|
||||
else {
|
||||
value = ghoul::lua::value<T>(L);
|
||||
}
|
||||
}
|
||||
struct HttpProxy {
|
||||
// Determines whether the proxy is being used
|
||||
std::optional<bool> activate;
|
||||
|
||||
// The address of the http proxy
|
||||
std::string address;
|
||||
|
||||
// The port of the http proxy
|
||||
int port [[codegen::inrange(0, 65536)]];
|
||||
|
||||
enum class Authentication {
|
||||
Basic [[codegen::key("basic")]],
|
||||
Ntlm [[codegen::key("ntlm")]],
|
||||
Digest [[codegen::key("digest")]],
|
||||
Any [[codegen::key("any")]]
|
||||
};
|
||||
// The authentication method of the http proxy
|
||||
std::optional<Authentication> authentication;
|
||||
|
||||
// The user of the http proxy
|
||||
std::optional<std::string> user;
|
||||
|
||||
// The password of the http proxy
|
||||
std::optional<std::string> password;
|
||||
};
|
||||
// This defines the use for a proxy when fetching data over http. No proxy will be
|
||||
// used if this is left out
|
||||
std::optional<HttpProxy> httpProxy;
|
||||
|
||||
struct OpenGLDebugContext {
|
||||
// Determines whether the OpenGL context should be a debug context
|
||||
bool activate;
|
||||
|
||||
// Determines whether the OpenGL debug callbacks are performed synchronously.
|
||||
// If set to 'true' the callbacks are in the same thread as the context and in
|
||||
// the scope of the OpenGL function that triggered the message. The default
|
||||
// value is 'true'
|
||||
std::optional<bool> synchronous;
|
||||
|
||||
// Individual OpenGL debug message identifiers
|
||||
struct Filter {
|
||||
// The identifier that is to be filtered
|
||||
int identifier;
|
||||
|
||||
// Taken from ghoul::debugcontext.cpp
|
||||
enum class Source {
|
||||
API,
|
||||
WindowSystem [[codegen::key("Window System")]],
|
||||
ShaderCompiler [[codegen::key("Shader Compiler")]],
|
||||
ThirdParty [[codegen::key("Third Party")]],
|
||||
Application,
|
||||
Other,
|
||||
DontCare [[codegen::key("Don't care")]]
|
||||
};
|
||||
// The source of the identifier to be filtered
|
||||
Source source;
|
||||
|
||||
// Taken from ghoul::debugcontext.cpp
|
||||
enum class Type {
|
||||
Error,
|
||||
Deprecated,
|
||||
Undefined,
|
||||
Portability,
|
||||
Performance,
|
||||
Marker,
|
||||
PushGroup [[codegen::key("Push group")]],
|
||||
PopGroup [[codegen::key("Pop group")]],
|
||||
Other,
|
||||
DontCare [[codegen::key("Don't care")]]
|
||||
};
|
||||
// The type of the identifier to be filtered
|
||||
Type type;
|
||||
};
|
||||
// A list of OpenGL debug messages identifiers that are filtered
|
||||
std::optional<std::vector<Filter>> filterIdentifier;
|
||||
|
||||
// A list of severities that can are filtered out
|
||||
enum class Severity {
|
||||
High,
|
||||
Medium,
|
||||
Low,
|
||||
Notification
|
||||
};
|
||||
// Determines the settings for the creation of an OpenGL debug context
|
||||
std::optional<std::vector<Severity>> filterSeverity;
|
||||
};
|
||||
// Determines the settings for the creation of an OpenGL debug context
|
||||
std::optional<OpenGLDebugContext> openGLDebugContext;
|
||||
|
||||
// Determines whether the OpenGL state is checked after each OpenGL function call.
|
||||
// This will dramatically slow down the rendering, but will make finding OpenGL
|
||||
// errors easier. This defaults to 'false'
|
||||
std::optional<bool> checkOpenGLState;
|
||||
|
||||
// Determines whether each OpenGL call that happens should be logged using the
|
||||
// 'TRACE' loglevel. This will bring the rendering to a crawl but provides useful
|
||||
// debugging features for the order in which OpenGL calls occur. This defaults to
|
||||
// 'false'
|
||||
std::optional<bool> logEachOpenGLCall;
|
||||
|
||||
// This value determines whether the initialization of the scene graph should
|
||||
// occur multithreaded, that is, whether multiple scene graph nodes should
|
||||
// initialize in parallel. The only use for this value is to disable it for
|
||||
// debugging support
|
||||
std::optional<bool> useMultithreadedInitialization;
|
||||
|
||||
// If this value is set to 'true', the launcher will not be shown and OpenSpace
|
||||
// will start with the provided configuration options directly. Useful in
|
||||
// multiprojector setups where a launcher window would be undesired
|
||||
std::optional<bool> bypassLauncher;
|
||||
|
||||
// The URL that is pinged to check which version of OpenSpace is the most current
|
||||
// if you don't want this request to happen, this value should not be set at all
|
||||
std::optional<std::string> versionCheckUrl;
|
||||
|
||||
struct LoadingScreen {
|
||||
// If this value is set to 'true', the loading screen will display a message
|
||||
// information about the current phase the loading is in
|
||||
std::optional<bool> showMessage;
|
||||
|
||||
// If this value is set to 'true', the loading screen will display a list of
|
||||
// all of the nodes with their respective status (created, loaded,
|
||||
// initialized)
|
||||
std::optional<bool> showNodeNames;
|
||||
|
||||
// If this value is set to 'true', the loading screen will contain a progress
|
||||
// bar that gives an estimate of the loading progression
|
||||
std::optional<bool> showProgressbar;
|
||||
};
|
||||
// Values in this table describe the behavior of the loading screen that is
|
||||
// displayed while the scene graph is created and initialized
|
||||
std::optional<LoadingScreen> loadingScreen;
|
||||
|
||||
// List of profiles that cannot be overwritten by user
|
||||
std::optional<std::vector<std::string>> readOnlyProfiles;
|
||||
|
||||
// Configurations for each module
|
||||
std::optional<std::map<std::string, ghoul::Dictionary>> moduleConfigurations;
|
||||
};
|
||||
#include "configuration_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
#include "configuration_doc.inl"
|
||||
|
||||
namespace openspace::configuration {
|
||||
|
||||
void parseLuaState(Configuration& configuration) {
|
||||
@@ -317,40 +334,277 @@ void parseLuaState(Configuration& configuration) {
|
||||
Configuration& c = configuration;
|
||||
LuaState& s = c.state;
|
||||
|
||||
getValue(s, KeySGCTConfig, c.windowConfiguration);
|
||||
getValue(s, KeyAsset, c.asset);
|
||||
getValue(s, KeyProfile, c.profile);
|
||||
getValue(s, KeyGlobalCustomizationScripts, c.globalCustomizationScripts);
|
||||
getValue(s, KeyPaths, c.pathTokens);
|
||||
getValue(s, KeyFonts, c.fonts);
|
||||
getValue(s, KeyScriptLog, c.scriptLog);
|
||||
getValue(s, KeyVersionCheckUrl, c.versionCheckUrl);
|
||||
getValue(s, KeyUseMultithreadedInitialization, c.useMultithreadedInitialization);
|
||||
getValue(s, KeyCheckOpenGLState, c.isCheckingOpenGLState);
|
||||
getValue(s, KeyLogEachOpenGLCall, c.isLoggingOpenGLCalls);
|
||||
getValue(s, KeyShutdownCountdown, c.shutdownCountdown);
|
||||
getValue(s, KeyScreenshotUseDate, c.shouldUseScreenshotDate);
|
||||
getValue(s, KeyOnScreenTextScaling, c.onScreenTextScaling);
|
||||
getValue(s, KeyPerSceneCache, c.usePerSceneCache);
|
||||
getValue(s, KeyDisableRenderingOnMaster, c.isRenderingOnMasterDisabled);
|
||||
// The sgctConfigNameInitialized is a bit special
|
||||
lua_getglobal(s, "sgctconfiginitializeString");
|
||||
c.sgctConfigNameInitialized = ghoul::lua::value<std::string>(
|
||||
s,
|
||||
ghoul::lua::PopValue::Yes
|
||||
);
|
||||
|
||||
getValue(s, KeyGlobalRotation, c.globalRotation);
|
||||
getValue(s, KeyScreenSpaceRotation, c.screenSpaceRotation);
|
||||
getValue(s, KeyMasterRotation, c.masterRotation);
|
||||
getValue(s, KeyDisableInGameConsole, c.isConsoleDisabled);
|
||||
getValue(s, KeyRenderingMethod, c.renderingMethod);
|
||||
getValue(s, KeyLogging, c.logging);
|
||||
getValue(s, KeyDocumentation, c.documentation);
|
||||
getValue(s, KeyLoadingScreen, c.loadingScreen);
|
||||
getValue(s, KeyModuleConfigurations, c.moduleConfigurations);
|
||||
getValue(s, KeyOpenGLDebugContext, c.openGLDebugContext);
|
||||
getValue(s, KeyHttpProxy, c.httpProxy);
|
||||
|
||||
getValue(s, KeySgctConfigNameInitialized, c.sgctConfigNameInitialized);
|
||||
getValue(s, KeyReadOnlyProfiles, c.readOnlyProfiles);
|
||||
getValue(s, KeyBypassLauncher, c.bypassLauncher);
|
||||
// The configuration file sets all values as global variables, so we need to pull them
|
||||
// into a table first so that we can pass that table to the dictionary constructor
|
||||
lua_newtable(s);
|
||||
|
||||
// We go through all of the entries and lift them from global scope into the table on
|
||||
// the stack so that we can create a ghoul::Dictionary from this new table
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
for (const documentation::DocumentationEntry& e : doc.entries) {
|
||||
lua_pushstring(s, e.key.c_str());
|
||||
lua_getglobal(s, e.key.c_str());
|
||||
lua_settable(s, -3);
|
||||
}
|
||||
|
||||
|
||||
ghoul::Dictionary d;
|
||||
ghoul::lua::luaDictionaryFromState(s, d);
|
||||
lua_settop(s, 0);
|
||||
const Parameters p = codegen::bake<Parameters>(d);
|
||||
|
||||
c.windowConfiguration = p.windowConfiguration.value_or(c.windowConfiguration);
|
||||
c.asset = p.asset.value_or(c.asset);
|
||||
c.profile = p.profile.value_or(c.profile);
|
||||
c.globalCustomizationScripts =
|
||||
p.globalCustomizationScripts.value_or(c.globalCustomizationScripts);
|
||||
c.pathTokens = p.paths;
|
||||
c.fonts = p.fonts.value_or(c.fonts);
|
||||
c.scriptLog = p.scriptLog.value_or(c.scriptLog);
|
||||
c.versionCheckUrl = p.versionCheckUrl.value_or(c.versionCheckUrl);
|
||||
c.useMultithreadedInitialization =
|
||||
p.useMultithreadedInitialization.value_or(c.useMultithreadedInitialization);
|
||||
c.isCheckingOpenGLState = p.checkOpenGLState.value_or(c.isCheckingOpenGLState);
|
||||
c.isLoggingOpenGLCalls = p.logEachOpenGLCall.value_or(c.isLoggingOpenGLCalls);
|
||||
c.shutdownCountdown = p.shutdownCountdown.value_or(c.shutdownCountdown);
|
||||
c.shouldUseScreenshotDate = p.screenshotUseDate.value_or(c.shouldUseScreenshotDate);
|
||||
if (p.onScreenTextScaling.has_value()) {
|
||||
switch (*p.onScreenTextScaling) {
|
||||
case Parameters::Scaling::Window:
|
||||
c.onScreenTextScaling = "window";
|
||||
break;
|
||||
case Parameters::Scaling::Framebuffer:
|
||||
c.onScreenTextScaling = "framebuffer";
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
c.usePerSceneCache = p.perSceneCache.value_or(c.usePerSceneCache);
|
||||
c.isRenderingOnMasterDisabled =
|
||||
p.disableRenderingOnMaster.value_or(c.isRenderingOnMasterDisabled);
|
||||
c.globalRotation = p.globalRotation.value_or(c.globalRotation);
|
||||
c.masterRotation = p.masterRotation.value_or(c.masterRotation);
|
||||
c.screenSpaceRotation = p.screenSpaceRotation.value_or(c.screenSpaceRotation);
|
||||
if (p.renderingMethod.has_value()) {
|
||||
switch (*p.renderingMethod) {
|
||||
case Parameters::RenderingMethod::Framebuffer:
|
||||
c.renderingMethod = "Framebuffer";
|
||||
break;
|
||||
case Parameters::RenderingMethod::ABuffer:
|
||||
c.renderingMethod = "ABuffer";
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
c.isConsoleDisabled = p.disableInGameConsole.value_or(c.isConsoleDisabled);
|
||||
if (p.logging.has_value()) {
|
||||
if (p.logging->logLevel.has_value()) {
|
||||
switch (*p.logging->logLevel) {
|
||||
case Parameters::Logging::Level::Trace:
|
||||
c.logging.level = "Trace";
|
||||
break;
|
||||
case Parameters::Logging::Level::Debug:
|
||||
c.logging.level = "Debug";
|
||||
break;
|
||||
case Parameters::Logging::Level::Info:
|
||||
c.logging.level = "Info";
|
||||
break;
|
||||
case Parameters::Logging::Level::Warning:
|
||||
c.logging.level = "Warning";
|
||||
break;
|
||||
case Parameters::Logging::Level::Error:
|
||||
c.logging.level = "Error";
|
||||
break;
|
||||
case Parameters::Logging::Level::Fatal:
|
||||
c.logging.level = "Fatal";
|
||||
break;
|
||||
case Parameters::Logging::Level::None:
|
||||
c.logging.level = "None";
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
c.logging.forceImmediateFlush =
|
||||
p.logging->immediateFlush.value_or(c.logging.forceImmediateFlush);
|
||||
c.logging.logs = p.logging->logs.value_or(c.logging.logs);
|
||||
if (p.logging->capabilitiesVerbosity.has_value()) {
|
||||
switch (*p.logging->capabilitiesVerbosity) {
|
||||
case Parameters::Logging::Verbosity::None:
|
||||
c.logging.capabilitiesVerbosity = "None";
|
||||
break;
|
||||
case Parameters::Logging::Verbosity::Minimal:
|
||||
c.logging.capabilitiesVerbosity = "Minimal";
|
||||
break;
|
||||
case Parameters::Logging::Verbosity::Default:
|
||||
c.logging.capabilitiesVerbosity = "Default";
|
||||
break;
|
||||
case Parameters::Logging::Verbosity::Full:
|
||||
c.logging.capabilitiesVerbosity = "Full";
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p.documentation.has_value()) {
|
||||
c.documentation.path = p.documentation->path.value_or(c.documentation.path);
|
||||
}
|
||||
|
||||
if (p.loadingScreen.has_value()) {
|
||||
const Parameters::LoadingScreen& l = *p.loadingScreen;
|
||||
c.loadingScreen.isShowingMessages =
|
||||
l.showMessage.value_or(c.loadingScreen.isShowingMessages);
|
||||
c.loadingScreen.isShowingProgressbar =
|
||||
l.showProgressbar.value_or(c.loadingScreen.isShowingProgressbar);
|
||||
c.loadingScreen.isShowingNodeNames =
|
||||
l.showNodeNames.value_or(c.loadingScreen.isShowingNodeNames);
|
||||
}
|
||||
|
||||
c.moduleConfigurations = p.moduleConfigurations.value_or(c.moduleConfigurations);
|
||||
|
||||
if (p.openGLDebugContext.has_value()) {
|
||||
const Parameters::OpenGLDebugContext& l = *p.openGLDebugContext;
|
||||
c.openGLDebugContext.isActive = l.activate;
|
||||
c.openGLDebugContext.isSynchronous = l.synchronous.value_or(
|
||||
c.openGLDebugContext.isSynchronous
|
||||
);
|
||||
if (l.filterIdentifier.has_value()) {
|
||||
for (const Parameters::OpenGLDebugContext::Filter& f : *l.filterIdentifier) {
|
||||
Configuration::OpenGLDebugContext::IdentifierFilter filter;
|
||||
filter.identifier = static_cast<unsigned int>(f.identifier);
|
||||
switch (f.source) {
|
||||
case Parameters::OpenGLDebugContext::Filter::Source::API:
|
||||
filter.source = "API";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Source::WindowSystem:
|
||||
filter.source = "Window System";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Source::ShaderCompiler:
|
||||
filter.source = "Shader Compiler";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Source::ThirdParty:
|
||||
filter.source = "Third Party";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Source::Application:
|
||||
filter.source = "Application";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Source::Other:
|
||||
filter.source = "Other";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Source::DontCare:
|
||||
filter.source = "Don't care";
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
switch (f.type) {
|
||||
case Parameters::OpenGLDebugContext::Filter::Type::Error:
|
||||
filter.type = "Error";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Type::Deprecated:
|
||||
filter.type = "Deprecated";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Type::Undefined:
|
||||
filter.type = "Undefined";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Type::Portability:
|
||||
filter.type = "Portability";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Type::Performance:
|
||||
filter.type = "Performance";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Type::Marker:
|
||||
filter.type = "Marker";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Type::PushGroup:
|
||||
filter.type = "Push group";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Type::PopGroup:
|
||||
filter.type = "Pop group";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Type::Other:
|
||||
filter.type = "Other";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Filter::Type::DontCare:
|
||||
filter.type = "Don't care";
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
|
||||
c.openGLDebugContext.identifierFilters.push_back(filter);
|
||||
}
|
||||
}
|
||||
if (l.filterSeverity.has_value()) {
|
||||
for (Parameters::OpenGLDebugContext::Severity sev : *l.filterSeverity) {
|
||||
std::string severity;
|
||||
switch (sev) {
|
||||
case Parameters::OpenGLDebugContext::Severity::High:
|
||||
severity = "High";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Severity::Medium:
|
||||
severity = "Medium";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Severity::Low:
|
||||
severity = "Low";
|
||||
break;
|
||||
case Parameters::OpenGLDebugContext::Severity::Notification:
|
||||
severity = "Notification";
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
c.openGLDebugContext.severityFilters.push_back(severity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p.httpProxy.has_value()) {
|
||||
c.httpProxy.usingHttpProxy =
|
||||
p.httpProxy->activate.value_or(c.httpProxy.usingHttpProxy);
|
||||
c.httpProxy.address = p.httpProxy->address;
|
||||
c.httpProxy.port = static_cast<unsigned int>(p.httpProxy->port);
|
||||
if (p.httpProxy->authentication.has_value()) {
|
||||
switch (*p.httpProxy->authentication) {
|
||||
case Parameters::HttpProxy::Authentication::Basic:
|
||||
c.httpProxy.authentication = "basic";
|
||||
break;
|
||||
case Parameters::HttpProxy::Authentication::Ntlm:
|
||||
c.httpProxy.authentication = "ntlm";
|
||||
break;
|
||||
case Parameters::HttpProxy::Authentication::Digest:
|
||||
c.httpProxy.authentication = "digest";
|
||||
break;
|
||||
case Parameters::HttpProxy::Authentication::Any:
|
||||
c.httpProxy.authentication = "any";
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
c.httpProxy.user = p.httpProxy->user.value_or(c.httpProxy.user);
|
||||
c.httpProxy.password = p.httpProxy->password.value_or(c.httpProxy.password);
|
||||
}
|
||||
|
||||
c.readOnlyProfiles = p.readOnlyProfiles.value_or(c.readOnlyProfiles);
|
||||
c.bypassLauncher = p.bypassLauncher.value_or(c.bypassLauncher);
|
||||
}
|
||||
|
||||
documentation::Documentation Configuration::Documentation = codegen::doc<Parameters>();
|
||||
|
||||
std::string findConfiguration(const std::string& filename) {
|
||||
using ghoul::filesystem::Directory;
|
||||
|
||||
@@ -383,16 +637,14 @@ std::string findConfiguration(const std::string& filename) {
|
||||
}
|
||||
}
|
||||
|
||||
Configuration loadConfigurationFromFile(const std::string& filename) {
|
||||
Configuration loadConfigurationFromFile(const std::string& filename,
|
||||
const std::string& overrideScript)
|
||||
{
|
||||
ghoul_assert(!filename.empty(), "Filename must not be empty");
|
||||
ghoul_assert(FileSys.fileExists(filename), "File must exist");
|
||||
|
||||
Configuration result;
|
||||
|
||||
// Register the base path as the directory where 'filename' lives
|
||||
std::string basePath = ghoul::filesystem::File(filename).directoryName();
|
||||
FileSys.registerPathToken(BasePathToken, basePath);
|
||||
|
||||
// If there is an initial config helper file, load it into the state
|
||||
if (FileSys.fileExists(absPath(InitialConfigHelper))) {
|
||||
ghoul::lua::runScriptFile(result.state, absPath(InitialConfigHelper));
|
||||
@@ -401,6 +653,12 @@ Configuration loadConfigurationFromFile(const std::string& filename) {
|
||||
// Load the configuration file into the state
|
||||
ghoul::lua::runScriptFile(result.state, filename);
|
||||
|
||||
if (!overrideScript.empty()) {
|
||||
LDEBUGC("Configuration", "Executing Lua script passed through the commandline:");
|
||||
LDEBUGC("Configuration", overrideScript);
|
||||
ghoul::lua::runScript(result.state, overrideScript);
|
||||
}
|
||||
|
||||
parseLuaState(result);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,450 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* 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/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
|
||||
namespace openspace::configuration {
|
||||
|
||||
using namespace documentation;
|
||||
documentation::Documentation Configuration::Documentation = {
|
||||
"OpenSpace Configuration",
|
||||
"openspace_configuraion",
|
||||
{
|
||||
{
|
||||
KeySGCTConfig,
|
||||
new StringAnnotationVerifier("A valid SGCT configuration file"),
|
||||
Optional::Yes,
|
||||
"The SGCT configuration file that determines the window and view frustum "
|
||||
"settings that are being used when OpenSpace is started."
|
||||
},
|
||||
{
|
||||
KeySgctConfigNameInitialized,
|
||||
new StringAnnotationVerifier("The type of SGCT autogen function (if called)"),
|
||||
Optional::Yes,
|
||||
"The SGCT configuration can be defined from an .xml file, or auto-generated "
|
||||
"by an sgct.config.* lua function. If a lua function is used to generate the "
|
||||
"SGCT configuration, then this key contains the name of the function, "
|
||||
"otherwise is blank."
|
||||
},
|
||||
{
|
||||
KeyAsset,
|
||||
new StringAnnotationVerifier(
|
||||
"A valid scene file as described in the Scene documentation"
|
||||
),
|
||||
Optional::Yes,
|
||||
"The scene description that is used to populate the application after "
|
||||
"startup. The scene determines which objects are loaded, the startup "
|
||||
"time and other scene-specific settings. More information is provided in "
|
||||
"the Scene documentation."
|
||||
},
|
||||
{
|
||||
KeyGlobalCustomizationScripts,
|
||||
new StringListVerifier,
|
||||
Optional::Yes,
|
||||
"This value names a list of scripts that get executed after initialization "
|
||||
"of any scene. These scripts can be used for user-specific customization, "
|
||||
"such as a global rebinding of keys from the default."
|
||||
},
|
||||
{
|
||||
KeyPaths,
|
||||
new StringListVerifier,
|
||||
Optional::No,
|
||||
"A list of paths that are automatically registered with the file system. "
|
||||
"If a key X is used in the table, it is then useable by referencing ${X} "
|
||||
"in all other configuration files or scripts."
|
||||
},
|
||||
{
|
||||
KeyFonts,
|
||||
new StringListVerifier("Font paths loadable by FreeType"),
|
||||
Optional::Yes,
|
||||
"A list of all fonts that will automatically be loaded on startup. Each "
|
||||
"key-value pair contained in the table will become the name and the file "
|
||||
"for a font."
|
||||
},
|
||||
{
|
||||
KeyLogging,
|
||||
new TableVerifier({
|
||||
{
|
||||
KeyLogDir,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"The directory for logs. Default value is \"${BASE}\""
|
||||
},
|
||||
{
|
||||
KeyPerformancePrefix,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"A string to prefix PerformanceMeasurement logfiles."
|
||||
"Default value is \"PM-\""
|
||||
},
|
||||
{
|
||||
KeyLogLevel,
|
||||
new StringInListVerifier(
|
||||
// List from logmanager.cpp::levelFromString
|
||||
{ "Trace", "Debug", "Info", "Warning", "Error", "Fatal", "None" }
|
||||
),
|
||||
Optional::Yes,
|
||||
"The severity of log messages that will be displayed. Only "
|
||||
"messages of the selected level or higher will be displayed. All "
|
||||
"levels below will be silently discarded. The order of "
|
||||
"severities is: Debug < Info < Warning < Error < Fatal < None."
|
||||
},
|
||||
{
|
||||
KeyImmediateFlush,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"Determines whether error messages will be displayed immediately "
|
||||
"or if it is acceptable to have a short delay, but being more "
|
||||
"performant. If the delay is allowed ('true'), messages might "
|
||||
"get lost if the application crashes shortly after a message was "
|
||||
"logged."
|
||||
},
|
||||
{
|
||||
KeyLogs,
|
||||
new TableVerifier({
|
||||
{
|
||||
"*",
|
||||
new ReferencingVerifier("core_logfactory"),
|
||||
Optional::No,
|
||||
"Additional log files"
|
||||
}
|
||||
}),
|
||||
Optional::Yes,
|
||||
"Per default, log messages are written to the console, the "
|
||||
"onscreen text, and (if available) the Visual Studio output "
|
||||
"window. This table can define other logging methods that will "
|
||||
"be used additionally."
|
||||
},
|
||||
{
|
||||
KeyCapabilitiesVerbosity,
|
||||
new StringInListVerifier(
|
||||
// List from OpenspaceEngine::initialize
|
||||
{ "None", "Minimal", "Default", "Full" }
|
||||
),
|
||||
Optional::Yes,
|
||||
"At startup, a list of system capabilities is created and logged."
|
||||
"This value determines how verbose this listing should be."
|
||||
}
|
||||
}),
|
||||
Optional::Yes,
|
||||
"Configurations for the logging of messages that are generated "
|
||||
"throughout the code and are useful for debugging potential errors or "
|
||||
"other information."
|
||||
},
|
||||
{
|
||||
KeyScriptLog,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"The file that will be created on startup containing the log of all Lua "
|
||||
"scripts that are executed in the last session. Any existing file (including "
|
||||
"the results from previous runs) will be silently overwritten."
|
||||
},
|
||||
{
|
||||
KeyDocumentationPath,
|
||||
new TableVerifier({
|
||||
{
|
||||
KeyDocumentationPath,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"The path where the documentation files will be stored."
|
||||
},
|
||||
}),
|
||||
Optional::Yes,
|
||||
"Right now only contains the path where the documentation is written to."
|
||||
},
|
||||
{
|
||||
KeyShutdownCountdown,
|
||||
new DoubleGreaterEqualVerifier(0.0),
|
||||
Optional::Yes,
|
||||
"The countdown that the application will wait between pressing ESC and "
|
||||
"actually shutting down. If ESC is pressed again in this time, the "
|
||||
"shutdown is aborted."
|
||||
},
|
||||
{
|
||||
KeyPerSceneCache,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"If this is set to 'true', the name of the scene will be appended to the "
|
||||
"cache directory, thus not reusing the same directory. This is useful in "
|
||||
"cases where the same instance of OpenSpace is run with multiple scenes, but "
|
||||
"the caches should be retained. This value defaults to 'false'."
|
||||
},
|
||||
{
|
||||
KeyOnScreenTextScaling,
|
||||
new StringInListVerifier({
|
||||
// Values from RenderEngine:updateRenderer
|
||||
"window", "framebuffer"
|
||||
}),
|
||||
Optional::Yes,
|
||||
"The method for scaling the onscreen text in the window. As the resolution "
|
||||
"of the rendering can be different from the size of the window, the onscreen "
|
||||
"text can either be scaled according to the window size ('window'), or the "
|
||||
"rendering resolution ('framebuffer'). This value defaults to 'window'."
|
||||
},
|
||||
{
|
||||
KeyRenderingMethod,
|
||||
new StringInListVerifier(
|
||||
// List from RenderEngine::setRendererFromString
|
||||
{ "Framebuffer", "ABuffer" }
|
||||
),
|
||||
Optional::Yes,
|
||||
"The renderer that is use after startup. The renderer 'ABuffer' requires "
|
||||
"support for at least OpenGL 4.3"
|
||||
},
|
||||
{
|
||||
KeyDisableRenderingOnMaster,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"Toggles whether the master in a multi-application setup should be rendering "
|
||||
"or just managing the state of the network. This is desired in cases where "
|
||||
"the master computer does not have the resources to render a scene."
|
||||
},
|
||||
{
|
||||
KeyGlobalRotation,
|
||||
new DoubleVector3Verifier,
|
||||
Optional::Yes,
|
||||
"Applies a global view rotation. Use this to rotate the position of the "
|
||||
"focus node away from the default location on the screen. This setting "
|
||||
"persists even when a new focus node is selected. Defined using roll, pitch, "
|
||||
"yaw in radians"
|
||||
},
|
||||
{
|
||||
KeyMasterRotation,
|
||||
new DoubleVector3Verifier,
|
||||
Optional::Yes,
|
||||
"Applies a view rotation for only the master node, defined using "
|
||||
"roll, pitch yaw in radians. This can be used to compensate the master view "
|
||||
"direction for tilted display systems in clustered immersive environments."
|
||||
},
|
||||
{
|
||||
KeyScreenSpaceRotation,
|
||||
new DoubleVector3Verifier,
|
||||
Optional::Yes,
|
||||
"Applies a global rotation for all screenspace renderables. Defined using "
|
||||
"roll, pitch, yaw in radians."
|
||||
},
|
||||
{
|
||||
KeyScreenshotUseDate,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"Toggles whether screenshots generated by OpenSpace contain the date when "
|
||||
"the concrete OpenSpace instance was started. This value is enabled by "
|
||||
"default, but it is advised to disable this value if rendering sessions of "
|
||||
"individual frames pass beyond local midnight."
|
||||
},
|
||||
{
|
||||
KeyHttpProxy,
|
||||
new TableVerifier({
|
||||
{
|
||||
KeyActivate,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"Determines whether the proxy is being used"
|
||||
},
|
||||
{
|
||||
KeyAddress,
|
||||
new StringVerifier,
|
||||
Optional::No,
|
||||
"The address of the http proxy"
|
||||
},
|
||||
{
|
||||
KeyPort,
|
||||
new IntVerifier,
|
||||
Optional::No,
|
||||
"The port of the http proxy"
|
||||
},
|
||||
{
|
||||
KeyAuthentication,
|
||||
new StringInListVerifier(
|
||||
{ "basic", "ntlm", "digest", "any" }
|
||||
),
|
||||
Optional::Yes,
|
||||
"The authentication method of the http proxy"
|
||||
},
|
||||
{
|
||||
KeyUser,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"The user of the http proxy"
|
||||
},
|
||||
{
|
||||
KeyPassword,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"The password of the http proxy"
|
||||
}
|
||||
}),
|
||||
Optional::Yes,
|
||||
"This defines the use for a proxy when fetching data over http."
|
||||
"No proxy will be used if this is left out."
|
||||
},
|
||||
{
|
||||
KeyOpenGLDebugContext,
|
||||
new TableVerifier({
|
||||
{
|
||||
KeyActivate,
|
||||
new BoolVerifier,
|
||||
Optional::No,
|
||||
"Determines whether the OpenGL context should be a debug context"
|
||||
},
|
||||
{
|
||||
KeySynchronous,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"Determines whether the OpenGL debug callbacks are performed "
|
||||
"synchronously. If set to <True> the callbacks are in the same "
|
||||
"thread as the context and in the scope of the OpenGL function that "
|
||||
"triggered the message. The default value is <True>."
|
||||
},
|
||||
{
|
||||
KeyFilterIdentifier,
|
||||
new TableVerifier({{
|
||||
"*",
|
||||
new TableVerifier({
|
||||
{
|
||||
KeyIdentifier,
|
||||
new IntVerifier,
|
||||
Optional::No,
|
||||
"The identifier that is to be filtered"
|
||||
},
|
||||
{
|
||||
KeySource,
|
||||
new StringInListVerifier({
|
||||
// Taken from ghoul::debugcontext.cpp
|
||||
"API", "Window System", "Shader Compiler",
|
||||
"Third Party", "Application", "Other", "Don't care"
|
||||
}),
|
||||
Optional::No,
|
||||
"The source of the identifier to be filtered"
|
||||
},
|
||||
{
|
||||
KeyType,
|
||||
new StringInListVerifier({
|
||||
// Taken from ghoul::debugcontext.cpp
|
||||
"Error", "Deprecated", "Undefined", "Portability",
|
||||
"Performance", "Marker", "Push group", "Pop group",
|
||||
"Other", "Don't care"
|
||||
}),
|
||||
Optional::No,
|
||||
"The type of the identifier to be filtered"
|
||||
}
|
||||
}),
|
||||
Optional::No,
|
||||
"Individual OpenGL debug message identifiers"
|
||||
}}),
|
||||
Optional::Yes,
|
||||
"A list of OpenGL debug messages identifiers that are filtered"
|
||||
},
|
||||
{
|
||||
KeyFilterSeverity,
|
||||
new TableVerifier({
|
||||
{
|
||||
"*",
|
||||
new StringInListVerifier(
|
||||
// ghoul::debugcontext.cpp
|
||||
{ "High", "Medium", "Low", "Notification" }
|
||||
),
|
||||
Optional::No
|
||||
}
|
||||
}),
|
||||
Optional::Yes,
|
||||
"A list of severities that can are filtered out"
|
||||
}
|
||||
}),
|
||||
Optional::Yes,
|
||||
"Determines the settings for the creation of an OpenGL debug context.",
|
||||
},
|
||||
{
|
||||
KeyCheckOpenGLState,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"Determines whether the OpenGL state is checked after each OpenGL function "
|
||||
"call. This will dramatically slow down the rendering, but will make finding "
|
||||
"OpenGL errors easier. This defaults to 'false'."
|
||||
},
|
||||
{
|
||||
KeyLogEachOpenGLCall,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"Determines whether each OpenGL call that happens should be logged using the "
|
||||
"'TRACE' loglevel. This will bring the rendering to a crawl but provides "
|
||||
"useful debugging features for the order in which OpenGL calls occur. This "
|
||||
"defaults to 'false'."
|
||||
},
|
||||
{
|
||||
KeyUseMultithreadedInitialization,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"This value determines whether the initialization of the scene graph should "
|
||||
"occur multithreaded, that is, whether multiple scene graph nodes should "
|
||||
"initialize in parallel. The only use for this value is to disable it for "
|
||||
"debugging support."
|
||||
},
|
||||
{
|
||||
KeyLoadingScreen,
|
||||
new TableVerifier({
|
||||
{
|
||||
KeyShowMessage,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"If this value is set to 'true', the loading screen will display a "
|
||||
"message information about the current phase the loading is in."
|
||||
},
|
||||
{
|
||||
KeyShowNodeNames,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"If this value is set to 'true', the loading screen will display a "
|
||||
"list of all of the nodes with their respective status (created, "
|
||||
"loaded, initialized)."
|
||||
},
|
||||
{
|
||||
KeyShowProgressbar,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"If this value is set to 'true', the loading screen will contain a "
|
||||
"progress bar that gives an estimate of the loading progression."
|
||||
}
|
||||
}),
|
||||
Optional::Yes,
|
||||
"Values in this table describe the behavior of the loading screen that is "
|
||||
"displayed while the scene graph is created and initialized."
|
||||
},
|
||||
{
|
||||
KeyModuleConfigurations,
|
||||
new TableVerifier,
|
||||
Optional::Yes,
|
||||
"Configurations for each module"
|
||||
},
|
||||
{
|
||||
KeyReadOnlyProfiles,
|
||||
new StringListVerifier,
|
||||
Optional::Yes,
|
||||
"List of profiles that cannot be overwritten by user"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace openspace::configuration
|
||||
@@ -28,6 +28,7 @@ add_executable(
|
||||
test_assetloader.cpp
|
||||
test_concurrentjobmanager.cpp
|
||||
test_concurrentqueue.cpp
|
||||
test_configuration.cpp
|
||||
test_documentation.cpp
|
||||
test_iswamanager.cpp
|
||||
test_latlonpatch.cpp
|
||||
|
||||
+13
-2
@@ -44,7 +44,7 @@ int main(int argc, char** argv) {
|
||||
using namespace openspace;
|
||||
|
||||
ghoul::logging::LogManager::initialize(
|
||||
ghoul::logging::LogLevel::Debug,
|
||||
ghoul::logging::LogLevel::Info,
|
||||
ghoul::logging::LogManager::ImmediateFlush::Yes
|
||||
);
|
||||
ghoul::initialize();
|
||||
@@ -59,10 +59,21 @@ int main(int argc, char** argv) {
|
||||
);
|
||||
|
||||
std::string configFile = configuration::findConfiguration();
|
||||
*global::configuration = configuration::loadConfigurationFromFile(configFile);
|
||||
// Register the base path as the directory where 'filename' lives
|
||||
std::string base = ghoul::filesystem::File(configFile).directoryName();
|
||||
constexpr const char* BasePathToken = "${BASE}";
|
||||
FileSys.registerPathToken(BasePathToken, base);
|
||||
|
||||
*global::configuration = configuration::loadConfigurationFromFile(configFile, "");
|
||||
global::openSpaceEngine->registerPathTokens();
|
||||
global::openSpaceEngine->initialize();
|
||||
|
||||
ghoul::logging::LogManager::deinitialize();
|
||||
ghoul::logging::LogManager::initialize(
|
||||
ghoul::logging::LogLevel::Info,
|
||||
ghoul::logging::LogManager::ImmediateFlush::Yes
|
||||
);
|
||||
|
||||
FileSys.registerPathToken("${TESTDIR}", "${BASE}/tests");
|
||||
|
||||
// All of the relevant tests initialize the SpiceManager
|
||||
|
||||
@@ -0,0 +1,640 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* 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 "catch2/catch.hpp"
|
||||
|
||||
#include <openspace/engine/configuration.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
using namespace openspace::configuration;
|
||||
|
||||
namespace {
|
||||
std::string MinimalConfig = R"(
|
||||
Paths = {}
|
||||
)";
|
||||
|
||||
void writeConfig(const std::string& filename, const std::string& content) {
|
||||
std::string config = MinimalConfig + content;
|
||||
std::ofstream f(filename);
|
||||
f << MinimalConfig << '\n' << content;
|
||||
}
|
||||
|
||||
Configuration loadConfiguration(const std::string& tag, const std::string& content) {
|
||||
std::string filename = fmt::format("test_configuration_{}.cfg", tag);
|
||||
std::filesystem::path path = std::filesystem::temp_directory_path();
|
||||
std::string configFile = (path / filename).string();
|
||||
writeConfig(configFile, content);
|
||||
Configuration conf = loadConfigurationFromFile(configFile, content);
|
||||
std::filesystem::remove(configFile);
|
||||
return conf;
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Configuration: minimal", "[configuration]") {
|
||||
loadConfiguration("minimal", "");
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: windowConfiguration", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(SGCTConfig = "foobar")";
|
||||
const Configuration c = loadConfiguration("windowConfiguration", Extra);
|
||||
REQUIRE(c.windowConfiguration == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: asset", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(Asset = "foobar")";
|
||||
const Configuration c = loadConfiguration("asset", Extra);
|
||||
REQUIRE(c.asset == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: profile", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(Profile = "foobar")";
|
||||
const Configuration c = loadConfiguration("profile", Extra);
|
||||
REQUIRE(c.profile == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: globalCustomizationScripts", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(GlobalCustomizationScripts = { "foo", "bar" })";
|
||||
const Configuration c = loadConfiguration("globalCustomization", Extra);
|
||||
REQUIRE(c.globalCustomizationScripts.size() == 2);
|
||||
CHECK(c.globalCustomizationScripts == std::vector<std::string>{ "foo", "bar" });
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: paths", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(Paths = { foo = "1", bar = "2" })";
|
||||
const Configuration c = loadConfiguration("paths", Extra);
|
||||
REQUIRE(c.pathTokens.size() == 2);
|
||||
CHECK(
|
||||
c.pathTokens ==
|
||||
std::map<std::string, std::string>{ { "foo", "1" }, { "bar", "2" } }
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: fonts", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(Fonts = { foo = "1", bar = "2" })";
|
||||
const Configuration c = loadConfiguration("fonts", Extra);
|
||||
REQUIRE(c.fonts.size() == 2);
|
||||
CHECK(
|
||||
c.fonts ==
|
||||
std::map<std::string, std::string>{ { "foo", "1" }, { "bar", "2" } }
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: logging", "[configuration]") {
|
||||
Configuration defaultConf;
|
||||
{
|
||||
// Empty
|
||||
constexpr const char Extra[] = R"(Logging = {})";
|
||||
const Configuration c = loadConfiguration("logging1", Extra);
|
||||
|
||||
CHECK(c.logging.level == defaultConf.logging.level);
|
||||
CHECK(c.logging.forceImmediateFlush == defaultConf.logging.forceImmediateFlush);
|
||||
CHECK(
|
||||
c.logging.capabilitiesVerbosity ==
|
||||
defaultConf.logging.capabilitiesVerbosity
|
||||
);
|
||||
CHECK(c.logging.logs == defaultConf.logging.logs);
|
||||
}
|
||||
{
|
||||
// level
|
||||
constexpr const char Extra[] = R"(Logging = { LogLevel = "Fatal" })";
|
||||
const Configuration c = loadConfiguration("logging2", Extra);
|
||||
|
||||
CHECK(c.logging.level == "Fatal");
|
||||
CHECK(c.logging.forceImmediateFlush == defaultConf.logging.forceImmediateFlush);
|
||||
CHECK(
|
||||
c.logging.capabilitiesVerbosity ==
|
||||
defaultConf.logging.capabilitiesVerbosity
|
||||
);
|
||||
CHECK(c.logging.logs == defaultConf.logging.logs);
|
||||
}
|
||||
{
|
||||
// forceimmediate
|
||||
constexpr const char Extra[] = R"(Logging = { ImmediateFlush = false })";
|
||||
const Configuration c = loadConfiguration("logging3", Extra);
|
||||
|
||||
CHECK(c.logging.level == defaultConf.logging.level);
|
||||
CHECK(c.logging.forceImmediateFlush == false);
|
||||
CHECK(
|
||||
c.logging.capabilitiesVerbosity ==
|
||||
defaultConf.logging.capabilitiesVerbosity
|
||||
);
|
||||
CHECK(c.logging.logs == defaultConf.logging.logs);
|
||||
}
|
||||
{
|
||||
// logs
|
||||
constexpr const char Extra[] = R"(
|
||||
Logging = {
|
||||
Logs = {
|
||||
{ Type = "html", File = "foobar", Append = false }
|
||||
}
|
||||
}
|
||||
)";
|
||||
const Configuration c = loadConfiguration("logging4", Extra);
|
||||
|
||||
CHECK(c.logging.level == defaultConf.logging.level);
|
||||
CHECK(c.logging.forceImmediateFlush == defaultConf.logging.forceImmediateFlush);
|
||||
CHECK(
|
||||
c.logging.capabilitiesVerbosity ==
|
||||
defaultConf.logging.capabilitiesVerbosity
|
||||
);
|
||||
REQUIRE(c.logging.logs.size() == 1);
|
||||
const ghoul::Dictionary& d = c.logging.logs[0];
|
||||
REQUIRE(d.hasValue<std::string>("Type"));
|
||||
CHECK(d.value<std::string>("Type") == "html");
|
||||
REQUIRE(d.hasValue<std::string>("File"));
|
||||
CHECK(d.value<std::string>("File") == "foobar");
|
||||
REQUIRE(d.hasValue<bool>("Append"));
|
||||
CHECK(d.value<bool>("Append") == false);
|
||||
}
|
||||
{
|
||||
// capabilities verbosity
|
||||
constexpr const char Extra[] = R"(Logging = { CapabilitiesVerbosity = "Full" })";
|
||||
const Configuration c = loadConfiguration("logging5", Extra);
|
||||
|
||||
CHECK(c.logging.level == defaultConf.logging.level);
|
||||
CHECK(c.logging.forceImmediateFlush == defaultConf.logging.forceImmediateFlush);
|
||||
CHECK(c.logging.capabilitiesVerbosity == "Full");
|
||||
CHECK(c.logging.logs == defaultConf.logging.logs);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: scriptlog", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(ScriptLog = "foobar")";
|
||||
const Configuration c = loadConfiguration("scriptlog", Extra);
|
||||
CHECK(c.scriptLog == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: documentationpath", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(Documentation = { Path = "foobar" })";
|
||||
const Configuration c = loadConfiguration("documentationpath", Extra);
|
||||
CHECK(c.documentation.path == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: versioncheckurl", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(VersionCheckUrl = "foobar")";
|
||||
const Configuration c = loadConfiguration("versioncheckurl", Extra);
|
||||
CHECK(c.versionCheckUrl == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: useMultithreadedInit", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(UseMultithreadedInitialization = true)";
|
||||
const Configuration c = loadConfiguration("useMultithreadedInit", Extra);
|
||||
CHECK(c.useMultithreadedInitialization == true);
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: loadingscreen", "[configuration]") {
|
||||
Configuration defaultConf;
|
||||
|
||||
{
|
||||
// empty
|
||||
constexpr const char Extra[] = R"(LoadingScreen = {})";
|
||||
const Configuration c = loadConfiguration("loadingscreen1", Extra);
|
||||
CHECK(
|
||||
c.loadingScreen.isShowingMessages ==
|
||||
defaultConf.loadingScreen.isShowingMessages
|
||||
);
|
||||
CHECK(
|
||||
c.loadingScreen.isShowingProgressbar ==
|
||||
defaultConf.loadingScreen.isShowingProgressbar
|
||||
);
|
||||
CHECK(
|
||||
c.loadingScreen.isShowingNodeNames ==
|
||||
defaultConf.loadingScreen.isShowingNodeNames
|
||||
);
|
||||
}
|
||||
{
|
||||
// isShowingMessages
|
||||
constexpr const char Extra[] = R"(LoadingScreen = { ShowMessage = true })";
|
||||
const Configuration c = loadConfiguration("loadingscreen2", Extra);
|
||||
CHECK(c.loadingScreen.isShowingMessages == true);
|
||||
CHECK(
|
||||
c.loadingScreen.isShowingProgressbar ==
|
||||
defaultConf.loadingScreen.isShowingProgressbar
|
||||
);
|
||||
CHECK(
|
||||
c.loadingScreen.isShowingNodeNames ==
|
||||
defaultConf.loadingScreen.isShowingNodeNames
|
||||
);
|
||||
}
|
||||
{
|
||||
// isShowingProgressbar
|
||||
constexpr const char Extra[] = R"(LoadingScreen = { ShowProgressbar = true })";
|
||||
const Configuration c = loadConfiguration("loadingscreen3", Extra);
|
||||
CHECK(
|
||||
c.loadingScreen.isShowingMessages ==
|
||||
defaultConf.loadingScreen.isShowingMessages
|
||||
);
|
||||
CHECK(c.loadingScreen.isShowingProgressbar == true);
|
||||
CHECK(
|
||||
c.loadingScreen.isShowingNodeNames ==
|
||||
defaultConf.loadingScreen.isShowingNodeNames
|
||||
);
|
||||
}
|
||||
{
|
||||
// isShowingNodeNames
|
||||
constexpr const char Extra[] = R"(LoadingScreen = { ShowNodeNames = true })";
|
||||
const Configuration c = loadConfiguration("loadingscreen4", Extra);
|
||||
CHECK(
|
||||
c.loadingScreen.isShowingMessages ==
|
||||
defaultConf.loadingScreen.isShowingMessages
|
||||
);
|
||||
CHECK(
|
||||
c.loadingScreen.isShowingProgressbar ==
|
||||
defaultConf.loadingScreen.isShowingProgressbar
|
||||
);
|
||||
CHECK(c.loadingScreen.isShowingNodeNames == true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: isCheckingOpenGLState", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(CheckOpenGLState = true)";
|
||||
const Configuration c = loadConfiguration("isCheckingOpenGLState", Extra);
|
||||
CHECK(c.isCheckingOpenGLState == true);
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: isLoggingOpenGLCalls", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(LogEachOpenGLCall = true)";
|
||||
const Configuration c = loadConfiguration("isLoggingOpenGLCalls", Extra);
|
||||
CHECK(c.isLoggingOpenGLCalls == true);
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: shutdownCountdown", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(ShutdownCountdown = 0.5)";
|
||||
const Configuration c = loadConfiguration("shutdownCountdown", Extra);
|
||||
CHECK(c.shutdownCountdown == 0.5f);
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: shouldUseScreenshotDate", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(ScreenshotUseDate = true)";
|
||||
const Configuration c = loadConfiguration("shouldUseScreenshotDate", Extra);
|
||||
CHECK(c.shouldUseScreenshotDate == true);
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: onScreenTextScaling", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(OnScreenTextScaling = "framebuffer")";
|
||||
const Configuration c = loadConfiguration("onScreenTextScaling", Extra);
|
||||
CHECK(c.onScreenTextScaling == "framebuffer");
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: usePerSceneCache", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(PerSceneCache = true)";
|
||||
const Configuration c = loadConfiguration("usePerSceneCache", Extra);
|
||||
CHECK(c.usePerSceneCache == true);
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: isRenderingOnMasterDisabled", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(DisableRenderingOnMaster = true)";
|
||||
const Configuration c = loadConfiguration("isRenderingOnMasterDisabled", Extra);
|
||||
CHECK(c.isRenderingOnMasterDisabled == true);
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: globalRotation", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(GlobalRotation = { 1.0, 2.0, 3.0 })";
|
||||
const Configuration c = loadConfiguration("globalRotation", Extra);
|
||||
CHECK(c.globalRotation == glm::dvec3(1.0, 2.0, 3.0));
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: screenSpaceRotation", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(ScreenSpaceRotation = { 1.0, 2.0, 3.0 })";
|
||||
const Configuration c = loadConfiguration("screenSpaceRotation", Extra);
|
||||
CHECK(c.screenSpaceRotation == glm::dvec3(1.0, 2.0, 3.0));
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: masterRotation", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(MasterRotation = { 1.0, 2.0, 3.0 })";
|
||||
const Configuration c = loadConfiguration("masterRotation", Extra);
|
||||
CHECK(c.masterRotation == glm::dvec3(1.0, 2.0, 3.0));
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: isConsoleDisabled", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(DisableInGameConsole = true)";
|
||||
const Configuration c = loadConfiguration("isConsoleDisabled", Extra);
|
||||
CHECK(c.isConsoleDisabled == true);
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: bypassLauncher", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(BypassLauncher = true)";
|
||||
const Configuration c = loadConfiguration("bypassLauncher", Extra);
|
||||
CHECK(c.bypassLauncher == true);
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: moduleConfigurations", "[configuration]") {
|
||||
{
|
||||
// empty
|
||||
constexpr const char Extra[] = R"(ModuleConfigurations = {})";
|
||||
const Configuration c = loadConfiguration("moduleConfigurations", Extra);
|
||||
CHECK(c.moduleConfigurations.empty());
|
||||
}
|
||||
{
|
||||
// values
|
||||
constexpr const char Extra[] = R"(
|
||||
ModuleConfigurations = {
|
||||
Foo = {
|
||||
Foo2 = 1.0,
|
||||
Foo3 = "abc"
|
||||
},
|
||||
Bar = {
|
||||
Bar2 = true,
|
||||
Bar3 = { 1.0, 2.0, 3.0 }
|
||||
}
|
||||
}
|
||||
)";
|
||||
const Configuration c = loadConfiguration("moduleConfigurations", Extra);
|
||||
REQUIRE(c.moduleConfigurations.size() == 2);
|
||||
ghoul::Dictionary foo = c.moduleConfigurations.at("Foo");
|
||||
REQUIRE(foo.size() == 2);
|
||||
REQUIRE(foo.hasValue<double>("Foo2"));
|
||||
CHECK(foo.value<double>("Foo2") == 1.0);
|
||||
REQUIRE(foo.hasValue<std::string>("Foo3"));
|
||||
CHECK(foo.value<std::string>("Foo3") == std::string("abc"));
|
||||
|
||||
ghoul::Dictionary bar = c.moduleConfigurations.at("Bar");
|
||||
REQUIRE(bar.size() == 2);
|
||||
REQUIRE(bar.hasValue<bool>("Bar2"));
|
||||
CHECK(bar.value<bool>("Bar2") == true);
|
||||
REQUIRE(bar.hasValue<glm::dvec3>("Bar3"));
|
||||
CHECK(bar.value<glm::dvec3>("Bar3") == glm::dvec3(1.0, 2.0, 3.0));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: renderingMethod", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(RenderingMethod = "ABuffer")";
|
||||
const Configuration c = loadConfiguration("renderingMethod", Extra);
|
||||
CHECK(c.renderingMethod == "ABuffer");
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: openGLDebugContext", "[configuration]") {
|
||||
Configuration defaultConf;
|
||||
{
|
||||
// empty-ish / activate
|
||||
constexpr const char Extra[] = R"(OpenGLDebugContext = { Activate = true })";
|
||||
const Configuration c = loadConfiguration("openGLDebugContext1", Extra);
|
||||
CHECK(c.openGLDebugContext.isActive == true);
|
||||
CHECK(
|
||||
c.openGLDebugContext.isSynchronous ==
|
||||
defaultConf.openGLDebugContext.isSynchronous
|
||||
);
|
||||
REQUIRE(
|
||||
c.openGLDebugContext.identifierFilters.size() ==
|
||||
defaultConf.openGLDebugContext.identifierFilters.size()
|
||||
);
|
||||
for (size_t i = 0; i < c.openGLDebugContext.identifierFilters.size(); i += 1) {
|
||||
CHECK(
|
||||
c.openGLDebugContext.identifierFilters[i].identifier ==
|
||||
defaultConf.openGLDebugContext.identifierFilters[i].identifier
|
||||
);
|
||||
CHECK(
|
||||
c.openGLDebugContext.identifierFilters[i].source ==
|
||||
defaultConf.openGLDebugContext.identifierFilters[i].source
|
||||
);
|
||||
CHECK(
|
||||
c.openGLDebugContext.identifierFilters[i].type ==
|
||||
defaultConf.openGLDebugContext.identifierFilters[i].type
|
||||
);
|
||||
}
|
||||
CHECK(
|
||||
c.openGLDebugContext.severityFilters ==
|
||||
defaultConf.openGLDebugContext.severityFilters
|
||||
);
|
||||
}
|
||||
{
|
||||
// isSynchronous
|
||||
constexpr const char Extra[] = R"(
|
||||
OpenGLDebugContext = { Activate = true, Synchronous = true }
|
||||
)";
|
||||
const Configuration c = loadConfiguration("openGLDebugContext2", Extra);
|
||||
CHECK(c.openGLDebugContext.isActive == true);
|
||||
CHECK(c.openGLDebugContext.isSynchronous == true);
|
||||
REQUIRE(
|
||||
c.openGLDebugContext.identifierFilters.size() ==
|
||||
defaultConf.openGLDebugContext.identifierFilters.size()
|
||||
);
|
||||
for (size_t i = 0; i < c.openGLDebugContext.identifierFilters.size(); i += 1) {
|
||||
CHECK(
|
||||
c.openGLDebugContext.identifierFilters[i].identifier ==
|
||||
defaultConf.openGLDebugContext.identifierFilters[i].identifier
|
||||
);
|
||||
CHECK(
|
||||
c.openGLDebugContext.identifierFilters[i].source ==
|
||||
defaultConf.openGLDebugContext.identifierFilters[i].source
|
||||
);
|
||||
CHECK(
|
||||
c.openGLDebugContext.identifierFilters[i].type ==
|
||||
defaultConf.openGLDebugContext.identifierFilters[i].type
|
||||
);
|
||||
}
|
||||
CHECK(
|
||||
c.openGLDebugContext.severityFilters ==
|
||||
defaultConf.openGLDebugContext.severityFilters
|
||||
);
|
||||
}
|
||||
{
|
||||
// identifierFilters
|
||||
constexpr const char Extra[] = R"(
|
||||
OpenGLDebugContext = {
|
||||
Activate = true,
|
||||
FilterIdentifier = {
|
||||
{ Identifier = 1, Source = "API", Type = "Error" },
|
||||
{ Identifier = 2, Source = "Window System", Type = "Deprecated" },
|
||||
{ Identifier = 3, Source = "Shader Compiler", Type = "Undefined" },
|
||||
{ Identifier = 4, Source = "Third Party", Type = "Portability" },
|
||||
{ Identifier = 5, Source = "Application", Type = "Performance" },
|
||||
{ Identifier = 6, Source = "Other", Type = "Marker" },
|
||||
{ Identifier = 7, Source = "Don't care", Type = "Push group" },
|
||||
{ Identifier = 8, Source = "API", Type = "Pop group" },
|
||||
{ Identifier = 9, Source = "Window System", Type = "Other" },
|
||||
{ Identifier = 10, Source = "Shader Compiler", Type = "Don't care" }
|
||||
}
|
||||
}
|
||||
)";
|
||||
const Configuration c = loadConfiguration("openGLDebugContext3", Extra);
|
||||
CHECK(c.openGLDebugContext.isActive == true);
|
||||
CHECK(
|
||||
c.openGLDebugContext.isSynchronous ==
|
||||
defaultConf.openGLDebugContext.isSynchronous
|
||||
);
|
||||
REQUIRE(c.openGLDebugContext.identifierFilters.size() == 10);
|
||||
CHECK(c.openGLDebugContext.identifierFilters[0].identifier == 1);
|
||||
CHECK(c.openGLDebugContext.identifierFilters[0].source == "API");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[0].type == "Error");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[1].identifier == 2);
|
||||
CHECK(c.openGLDebugContext.identifierFilters[1].source == "Window System");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[1].type == "Deprecated");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[2].identifier == 3);
|
||||
CHECK(c.openGLDebugContext.identifierFilters[2].source == "Shader Compiler");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[2].type == "Undefined");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[3].identifier == 4);
|
||||
CHECK(c.openGLDebugContext.identifierFilters[3].source == "Third Party");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[3].type == "Portability");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[4].identifier == 5);
|
||||
CHECK(c.openGLDebugContext.identifierFilters[4].source == "Application");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[4].type == "Performance");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[5].identifier == 6);
|
||||
CHECK(c.openGLDebugContext.identifierFilters[5].source == "Other");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[5].type == "Marker");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[6].identifier == 7);
|
||||
CHECK(c.openGLDebugContext.identifierFilters[6].source == "Don't care");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[6].type == "Push group");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[7].identifier == 8);
|
||||
CHECK(c.openGLDebugContext.identifierFilters[7].source == "API");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[7].type == "Pop group");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[8].identifier == 9);
|
||||
CHECK(c.openGLDebugContext.identifierFilters[8].source == "Window System");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[8].type == "Other");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[9].identifier == 10);
|
||||
CHECK(c.openGLDebugContext.identifierFilters[9].source == "Shader Compiler");
|
||||
CHECK(c.openGLDebugContext.identifierFilters[9].type == "Don't care");
|
||||
|
||||
CHECK(
|
||||
c.openGLDebugContext.severityFilters ==
|
||||
defaultConf.openGLDebugContext.severityFilters
|
||||
);
|
||||
}
|
||||
{
|
||||
// filterSeverity
|
||||
constexpr const char Extra[] = R"(
|
||||
OpenGLDebugContext = { Activate = true, FilterSeverity = { "High", "Medium" } }
|
||||
)";
|
||||
const Configuration c = loadConfiguration("openGLDebugContext4", Extra);
|
||||
CHECK(c.openGLDebugContext.isActive == true);
|
||||
CHECK(
|
||||
c.openGLDebugContext.isSynchronous ==
|
||||
defaultConf.openGLDebugContext.isSynchronous
|
||||
);
|
||||
REQUIRE(
|
||||
c.openGLDebugContext.identifierFilters.size() ==
|
||||
defaultConf.openGLDebugContext.identifierFilters.size()
|
||||
);
|
||||
for (size_t i = 0; i < c.openGLDebugContext.identifierFilters.size(); i += 1) {
|
||||
CHECK(
|
||||
c.openGLDebugContext.identifierFilters[i].identifier ==
|
||||
defaultConf.openGLDebugContext.identifierFilters[i].identifier
|
||||
);
|
||||
CHECK(
|
||||
c.openGLDebugContext.identifierFilters[i].source ==
|
||||
defaultConf.openGLDebugContext.identifierFilters[i].source
|
||||
);
|
||||
CHECK(
|
||||
c.openGLDebugContext.identifierFilters[i].type ==
|
||||
defaultConf.openGLDebugContext.identifierFilters[i].type
|
||||
);
|
||||
}
|
||||
REQUIRE(c.openGLDebugContext.severityFilters.size() == 2);
|
||||
CHECK(
|
||||
c.openGLDebugContext.severityFilters ==
|
||||
std::vector<std::string>{ "High", "Medium" }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: httpProxy", "[configuration]") {
|
||||
Configuration defaultConf;
|
||||
{
|
||||
// empty-ish / address + port
|
||||
constexpr const char Extra[] = R"(
|
||||
HttpProxy = {
|
||||
Address = "foobar",
|
||||
Port = 1234
|
||||
}
|
||||
)";
|
||||
const Configuration c = loadConfiguration("httpProxy1", Extra);
|
||||
CHECK(c.httpProxy.usingHttpProxy == defaultConf.httpProxy.usingHttpProxy);
|
||||
CHECK(c.httpProxy.address == "foobar");
|
||||
CHECK(c.httpProxy.port == 1234);
|
||||
CHECK(c.httpProxy.authentication == defaultConf.httpProxy.authentication);
|
||||
CHECK(c.httpProxy.user == defaultConf.httpProxy.user);
|
||||
CHECK(c.httpProxy.password == defaultConf.httpProxy.password);
|
||||
}
|
||||
{
|
||||
// activate
|
||||
constexpr const char Extra[] = R"(
|
||||
HttpProxy = {
|
||||
Activate = true,
|
||||
Address = "foobar",
|
||||
Port = 1234
|
||||
}
|
||||
)";
|
||||
const Configuration c = loadConfiguration("httpProxy2", Extra);
|
||||
CHECK(c.httpProxy.usingHttpProxy == true);
|
||||
CHECK(c.httpProxy.address == "foobar");
|
||||
CHECK(c.httpProxy.port == 1234);
|
||||
CHECK(c.httpProxy.authentication == defaultConf.httpProxy.authentication);
|
||||
CHECK(c.httpProxy.user == defaultConf.httpProxy.user);
|
||||
CHECK(c.httpProxy.password == defaultConf.httpProxy.password);
|
||||
}
|
||||
{
|
||||
// authentication
|
||||
constexpr const char Extra[] = R"(
|
||||
HttpProxy = {
|
||||
Address = "foobar",
|
||||
Port = 1234,
|
||||
Authentication = "ntlm"
|
||||
}
|
||||
)";
|
||||
const Configuration c = loadConfiguration("httpProxy3", Extra);
|
||||
CHECK(c.httpProxy.usingHttpProxy == defaultConf.httpProxy.usingHttpProxy);
|
||||
CHECK(c.httpProxy.address == "foobar");
|
||||
CHECK(c.httpProxy.port == 1234);
|
||||
CHECK(c.httpProxy.authentication == "ntlm");
|
||||
CHECK(c.httpProxy.user == defaultConf.httpProxy.user);
|
||||
CHECK(c.httpProxy.password == defaultConf.httpProxy.password);
|
||||
}
|
||||
{
|
||||
// user
|
||||
constexpr const char Extra[] = R"(
|
||||
HttpProxy = {
|
||||
Address = "foobar",
|
||||
Port = 1234,
|
||||
User = "user-bar"
|
||||
}
|
||||
)";
|
||||
const Configuration c = loadConfiguration("httpProxy4", Extra);
|
||||
CHECK(c.httpProxy.usingHttpProxy == defaultConf.httpProxy.usingHttpProxy);
|
||||
CHECK(c.httpProxy.address == "foobar");
|
||||
CHECK(c.httpProxy.port == 1234);
|
||||
CHECK(c.httpProxy.authentication == defaultConf.httpProxy.authentication);
|
||||
CHECK(c.httpProxy.user == "user-bar");
|
||||
CHECK(c.httpProxy.password == defaultConf.httpProxy.password);
|
||||
}
|
||||
{
|
||||
// password
|
||||
constexpr const char Extra[] = R"(
|
||||
HttpProxy = {
|
||||
Address = "foobar",
|
||||
Port = 1234,
|
||||
Password = "password-bar"
|
||||
}
|
||||
)";
|
||||
const Configuration c = loadConfiguration("httpProxy5", Extra);
|
||||
CHECK(c.httpProxy.usingHttpProxy == defaultConf.httpProxy.usingHttpProxy);
|
||||
CHECK(c.httpProxy.address == "foobar");
|
||||
CHECK(c.httpProxy.port == 1234);
|
||||
CHECK(c.httpProxy.authentication == defaultConf.httpProxy.authentication);
|
||||
CHECK(c.httpProxy.user == defaultConf.httpProxy.user);
|
||||
CHECK(c.httpProxy.password == "password-bar");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user