spacebox/src/Log.cpp

129 lines
5.3 KiB
C++

/* +------------------------------------------------------+
____/ \____ /| - Open source game framework licensed to freely use, |
\ / / | copy, modify and sell without restriction |
+--\ ^__^ /--+ | |
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
| ~~~~~~~~~~~~ | +------------------------------------------------------+
| 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<SDL_LogPriority>(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";
}
/* The following error codes aren't available in Open GL ES */
#if !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !defined(ANDROID)
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";
}
#endif
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<Game*>(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;
// }
// }
// }