diff --git a/src/engine/logfactory.cpp b/src/engine/logfactory.cpp index a1f65f8898..e07c794afa 100644 --- a/src/engine/logfactory.cpp +++ b/src/engine/logfactory.cpp @@ -32,186 +32,131 @@ #include #include #include +#include namespace { - constexpr const char* KeyType = "Type"; - constexpr const char* KeyFilename = "File"; - constexpr const char* KeyAppend = "Append"; - constexpr const char* KeyTimeStamping = "TimeStamping"; - constexpr const char* KeyDateStamping = "DateStamping"; - constexpr const char* KeyCategoryStamping = "CategoryStamping"; - constexpr const char* KeyLogLevelStamping = "LogLevelStamping"; - constexpr const char* KeyLogLevel = "LogLevel"; - - constexpr const char* ValueHtmlLog = "html"; - constexpr const char* ValueTextLog = "Text"; - constexpr const char* BootstrapPath = "${WEB}/common/bootstrap.min.css"; constexpr const char* CssPath = "${WEB}/log/style.css"; constexpr const char* JsPath = "${WEB}/log/script.js"; + + struct [[codegen::Dictionary(LogFactory)]] Parameters { + enum class Type { + Html [[codegen::key("html")]], + Text + }; + // The type of the new log to be generated + Type type; + + // The filename to which the log will be written + std::string file; + + // Determines whether the file will be cleared at startup or if the contents will + // be appended to previous runs + std::optional append; + + // Determines whether the log entires should be stamped with the time at which the + // message was logged + std::optional timeStamping; + + // Determines whether the log entries should be stamped with the date at which the + // message was logged + std::optional dateStamping; + + // Determines whether the log entries should be stamped with the category that + // creates the log message + std::optional categoryStamping; + + // Determines whether the log entries should be stamped with the log level that + // was used to create the log message + std::optional logLevelStamping; + + enum class LogLevel { + AllLogging, + Trace, + Debug, + Info, + Warning, + Error, + Fatal, + NoLogging + }; + // The log level for this specific text-based log + std::optional logLevel; + }; +#include "logfactory_codegen.cpp" } // namespace namespace openspace { documentation::Documentation LogFactoryDocumentation() { - using namespace documentation; - - return { - "LogFactory", - "core_logfactory", - { - { - KeyType, - new StringInListVerifier({ - // List from createLog - ValueTextLog, ValueHtmlLog - }), - Optional::No, - "The type of the new log to be generated." - }, - { - KeyFilename, - new StringVerifier, - Optional::No, - "The filename to which the log will be written." - }, - { - KeyAppend, - new BoolVerifier, - Optional::Yes, - "Determines whether the file will be cleared at startup or if the " - "contents will be appended to previous runs." - }, - { - KeyTimeStamping, - new BoolVerifier, - Optional::Yes, - "Determines whether the log entires should be stamped with the time at " - "which the message was logged." - }, - { - KeyDateStamping, - new BoolVerifier, - Optional::Yes, - "Determines whether the log entries should be stamped with the date at " - "which the message was logged." - }, - { - KeyCategoryStamping, - new BoolVerifier, - Optional::Yes, - "Determines whether the log entries should be stamped with the " - "category that creates the log message." - }, - { - KeyLogLevelStamping, - new BoolVerifier, - Optional::Yes, - "Determines whether the log entries should be stamped with the log level " - "that was used to create the log message." - } - } - }; + documentation::Documentation doc = codegen::doc(); + doc.id = "core_logfactory"; + return doc; } std::unique_ptr createLog(const ghoul::Dictionary& dictionary) { - documentation::testSpecificationAndThrow( - LogFactoryDocumentation(), - dictionary, - "LogFactory" - ); + const Parameters p = codegen::bake(dictionary); - // 'type' and 'filename' are required keys - const std::string& type = dictionary.value(KeyType); - const std::string& filename = absPath(dictionary.value(KeyFilename)); - - // the rest are optional - bool append = true; - if (dictionary.hasValue(KeyAppend)) { - append = dictionary.value(KeyAppend); - } - bool timeStamp = true; - if (dictionary.hasValue(KeyTimeStamping)) { - timeStamp = dictionary.value(KeyTimeStamping); - } - bool dateStamp = true; - if (dictionary.hasValue(KeyDateStamping)) { - dateStamp = dictionary.value(KeyDateStamping); - } - bool categoryStamp = true; - if (dictionary.hasValue(KeyCategoryStamping)) { - categoryStamp = dictionary.value(KeyCategoryStamping); - } - bool logLevelStamp = true; - if (dictionary.hasValue(KeyLogLevelStamping)) { - logLevelStamp = dictionary.value(KeyLogLevelStamping); - } - std::string logLevel; - if (dictionary.hasValue(KeyLogLevel)) { - logLevel = dictionary.value(KeyLogLevel); - } - - using Append = ghoul::logging::TextLog::Append; - using TimeStamping = ghoul::logging::Log::TimeStamping; - using DateStamping = ghoul::logging::Log::DateStamping; - using CategoryStamping = ghoul::logging::Log::CategoryStamping; - using LogLevelStamping = ghoul::logging::Log::LogLevelStamping; - - if (type == ValueHtmlLog) { - std::vector cssFiles{absPath(BootstrapPath), absPath(CssPath)}; - std::vector jsFiles{absPath(JsPath)}; - - if (logLevel.empty()) { - return std::make_unique( - filename, - Append(append), - TimeStamping(timeStamp), - DateStamping(dateStamp), - CategoryStamping(categoryStamp), - LogLevelStamping(logLevelStamp), - cssFiles, - jsFiles - ); + std::string filename = absPath(p.file); + bool append = p.append.value_or(true); + bool timeStamp = p.timeStamping.value_or(true); + bool dateStamp = p.dateStamping.value_or(true); + bool categoryStamp = p.categoryStamping.value_or(true); + bool logLevelStamp = p.logLevelStamping.value_or(true); + Parameters::LogLevel logLevel = p.logLevel.value_or(Parameters::LogLevel::AllLogging); + ghoul::logging::LogLevel level = [](Parameters::LogLevel l) { + switch (l) { + case Parameters::LogLevel::AllLogging: + return ghoul::logging::LogLevel::AllLogging; + case Parameters::LogLevel::Trace: + return ghoul::logging::LogLevel::Trace; + case Parameters::LogLevel::Debug: + return ghoul::logging::LogLevel::Debug; + case Parameters::LogLevel::Info: + return ghoul::logging::LogLevel::Info; + case Parameters::LogLevel::Warning: + return ghoul::logging::LogLevel::Warning; + case Parameters::LogLevel::Error: + return ghoul::logging::LogLevel::Error; + case Parameters::LogLevel::Fatal: + return ghoul::logging::LogLevel::Fatal; + case Parameters::LogLevel::NoLogging: + return ghoul::logging::LogLevel::NoLogging; + default: + throw ghoul::MissingCaseException(); } - else { + }(p.logLevel.value_or(Parameters::LogLevel::AllLogging)); + + switch (p.type) { + case Parameters::Type::Html: + { + std::vector cssFiles{ absPath(BootstrapPath), absPath(CssPath) }; + std::vector jsFiles{ absPath(JsPath) }; + return std::make_unique( filename, - Append(append), - TimeStamping(timeStamp), - DateStamping(dateStamp), - CategoryStamping(categoryStamp), - LogLevelStamping(logLevelStamp), + ghoul::logging::TextLog::Append(append), + ghoul::logging::Log::TimeStamping(timeStamp), + ghoul::logging::Log::DateStamping(dateStamp), + ghoul::logging::Log::CategoryStamping(categoryStamp), + ghoul::logging::Log::LogLevelStamping(logLevelStamp), cssFiles, jsFiles, - ghoul::from_string(logLevel) - ); + level + ); } - } - else if (type == ValueTextLog) { - if (logLevel.empty()) { + case Parameters::Type::Text: return std::make_unique( filename, - Append(append), - TimeStamping(timeStamp), - DateStamping(dateStamp), - CategoryStamping(categoryStamp), - LogLevelStamping(logLevelStamp) + ghoul::logging::TextLog::Append(append), + ghoul::logging::Log::TimeStamping(timeStamp), + ghoul::logging::Log::DateStamping(dateStamp), + ghoul::logging::Log::CategoryStamping(categoryStamp), + ghoul::logging::Log::LogLevelStamping(logLevelStamp), + level ); - } - else { - return std::make_unique( - filename, - Append(append), - TimeStamping(timeStamp), - DateStamping(dateStamp), - CategoryStamping(categoryStamp), - LogLevelStamping(logLevelStamp), - ghoul::from_string(logLevel) - ); - } - } - else { - throw ghoul::MissingCaseException(); + default: + throw new ghoul::MissingCaseException(); } }