/* /\ +--------------------------------------------------------------+ ____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, | \ / / | copy, modify and sell without restriction | +--\ ^__^ /--+ | | | ~/ \~ | | - originally created at [http://nugget.fun] | | ~~~~~~~~~~~~ | +--------------------------------------------------------------+ | SPACE ~~~~~ | / | ~~~~~~~ BOX |/ +--------------+ */ #include "Log.hpp" /* Send a message to SDL's log function, which currently gets overridden in the Game class. * The default level is INFO. Category will default to SDL's custom category. Using the default * category will ensure that debug level statements are handled according to the options in the * global configuration. */ void sb::Log::log(const std::string& message, const Level level, const int category) { SDL_LogMessage(category, static_cast(level), "%s", message.c_str()); } /* Convert string stream to string and forward */ void sb::Log::log(const std::ostringstream& message, const Level level, const int category) { log(message.str(), level, category); } /* Log all GL errors accumulated since the last time this function was called */ bool sb::Log::gl_errors(const std::string& heading) { GLenum error; bool error_logged = false; while ((error = glGetError()) != GL_NO_ERROR) { error_logged = true; std::ostringstream message; if (!heading.empty()) { message << heading << ": "; } if (error == GL_INVALID_ENUM) { message << "GL_INVALID_ENUM, an unacceptable value is specified for an enumerated argument"; } else if (error == GL_INVALID_VALUE) { message << "GL_INVALID_VALUE, a numeric argument is out of range"; } else if (error == GL_INVALID_OPERATION) { message << "GL_INVALID_OPERATION, the specified operation is not allowed in the current state"; } else if (error == GL_INVALID_FRAMEBUFFER_OPERATION) { message << "GL_INVALID_FRAMEBUFFER_OPERATION, the framebuffer object is not complete"; } else if (error == GL_OUT_OF_MEMORY) { message << "GL_OUT_OF_MEMORY, there is not enough memory left to execute the command"; } else if (error == GL_STACK_UNDERFLOW) { message << "GL_STACK_UNDERFLOW, an attempt has been made to perform an operation that would " << "cause an internal stack to underflow"; } else if (error == GL_STACK_OVERFLOW) { message << "GL_STACK_OVERFLOW, an attempt has been made to perform an operation that would " << "cause an internal stack to overflow"; } log(message); } return error_logged; } void sb::Log::sdl_error(const std::string& original_message) { std::ostringstream message; message << original_message << " " << SDL_GetError(); log(message, Level::ERROR); } /* Overrides SDL's default log function to log a message to stdout/stderr and, if log is enabled in the * global configuration, to a file. Debug level statements may be suppressed, printed to stdout, or printed to * both stdout and file, depending on the global configuration. */ // void sb::Log::record(void* userdata, int category, SDL_LogPriority priority, const char* message) // { // Game* game = static_cast(userdata); // std::ostream& out = (priority > SDL_LOG_PRIORITY_WARN) ? std::cerr : std::cout; // /* print to stdout/stderr if priority is higher than debug or debug statements are enabled */ // if (priority > SDL_LOG_PRIORITY_DEBUG /* || game->configuration()["log"]["debug-to-stdout"] */) // { // out << message << std::endl; // } // /* handle writing to log file */ // if (game->configuration()["log"]["enabled"]) // { // fs::path path = game->configuration()["log"]["output-directory"]; // if (!fs::exists(path)) // { // fs::create_directories(path); // } // /* prepend a timestamp to the message */ // std::time_t now = std::time(nullptr); // std::stringstream stamped_message; // stamped_message << std::put_time(std::localtime(&now), "%F %T ") << message; // /* if debug is enabled, append message to debug log file */ // if (game->configuration()["log"]["debug-to-file"]) // { // fs::path debug_path = path / game->configuration()["log"]["debug-file-name"]; // std::ofstream debug_stream(debug_path, std::ios_base::app); // debug_stream << stamped_message.str() << std::endl; // } // /* only append messages to the info log that are higher than debug priority */ // if (priority > SDL_LOG_PRIORITY_DEBUG) // { // fs::path info_path = path / game->configuration()["log"]["info-file-name"]; // std::ofstream info_stream(info_path, std::ios_base::app); // info_stream << stamped_message.str() << std::endl; // } // } // }