BARE2D
BAREErrors.cpp
Go to the documentation of this file.
1 #include "BAREErrors.hpp"
2 
3 #include <iostream>
4 #include <iomanip>
5 #include <csignal>
6 #include <SDL2/SDL.h>
7 #include <GL/glew.h>
8 
9 #include <cxxabi.h>
10 #include <typeinfo>
11 #include <memory>
12 #include <cstdlib>
13 
14 #include "Logger.hpp"
15 
16 std::string demangle(const char* mangled) {
17  int status;
18  std::unique_ptr<char[], void (*)(void*)> result(abi::__cxa_demangle(mangled, 0, 0, &status), std::free);
19  return result.get() ? std::string(result.get()) : "error occurred";
20 }
21 
22 void GLAPIENTRY MessageCallback(GLenum source,
23  GLenum type,
24  GLuint id,
25  GLenum severity,
26  GLsizei length,
27  const GLchar* message,
28  const void* userParam) {
29  std::string severityStr = "Unspecified";
31  switch(severity) {
32  case GL_DEBUG_SEVERITY_HIGH:
33  severityStr = "High (UB)";
34  severityEnum = BARE2D::GLErrorSeverity::HIGH;
35  break;
36  case GL_DEBUG_SEVERITY_MEDIUM:
37  severityStr = "Medium (Performance, deprecated)";
38  severityEnum = BARE2D::GLErrorSeverity::MED;
39  break;
40  case GL_DEBUG_SEVERITY_LOW:
41  severityStr = "Low (performance generally)";
42  severityEnum = BARE2D::GLErrorSeverity::LOW;
43  break;
44  case GL_DEBUG_SEVERITY_NOTIFICATION:
45  severityStr = "Notification";
46  severityEnum = BARE2D::GLErrorSeverity::NOTIF;
47  break;
48  default:
49  severityStr = "Unspecified";
50  break;
51  }
52 
53  if((unsigned int)severityEnum < (unsigned int)BARE2D::GLErrorMinSeverity)
54  return;
55 
56  std::string sourceStr = "Unspecified";
57  switch(source) {
58  case GL_DEBUG_SOURCE_API:
59  sourceStr = "OpenGL API";
60  break;
61  case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
62  sourceStr = "Window System";
63  break;
64  case GL_DEBUG_SOURCE_SHADER_COMPILER:
65  sourceStr = "Shader Compiler";
66  break;
67  case GL_DEBUG_SOURCE_THIRD_PARTY:
68  sourceStr = "Assoc. Application";
69  break;
70  case GL_DEBUG_SOURCE_APPLICATION:
71  sourceStr = "Application User";
72  break;
73  case GL_DEBUG_SOURCE_OTHER:
74  sourceStr = "Other";
75  break;
76  default:
77  sourceStr = "Unspecified";
78  break;
79  }
80 
81  std::string typeStr = "Unspecified";
82  switch(type) {
83  case GL_DEBUG_TYPE_ERROR:
84  typeStr = "Error";
85  break;
86  case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
87  typeStr = "Deprecated Behaviour";
88  break;
89  case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
90  typeStr = "Undefined Behaviour";
91  break;
92  case GL_DEBUG_TYPE_PORTABILITY:
93  typeStr = "Portability Concern";
94  break;
95  case GL_DEBUG_TYPE_PERFORMANCE:
96  typeStr = "Performance Issue";
97  break;
98  case GL_DEBUG_TYPE_MARKER:
99  typeStr = "Command Stream Annotation";
100  break;
101  case GL_DEBUG_TYPE_PUSH_GROUP:
102  typeStr = "Group Pushing";
103  break;
104  case GL_DEBUG_TYPE_POP_GROUP:
105  typeStr = "Documented as 'foo'";
106  break;
107  case GL_DEBUG_TYPE_OTHER:
108  typeStr = "Other";
109  break;
110  default:
111  typeStr = "Unspecified";
112  break;
113  }
114 
115  std::string errorString = "GL Callback: " + std::string(type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "") + "\n";
116  errorString += "Type: " + typeStr + "\n";
117  errorString += "Severity: " + severityStr + "\n";
118  errorString += "Message: " + std::string(message) + "\n";
119 
120  BARE2D::Logger::getInstance()->log(errorString);
121 
122  /*fprintf(stderr, "GL Callback: %s \nType: %s \nSeverity: %s \nMessage: %s\n\n",
123  (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""),
124  typeStr.c_str(),
125  severityStr.c_str(),
126  message);*/
127 }
128 
129 namespace BARE2D {
131 
132  std::vector<BAREError> thrownErrors;
133 
134  std::string getErrString(BAREError err) {
135  switch(err) {
137  return "EC SDL_FAILURE - SDL Failure to initialize. SDL_GetError() yields the following: \n\n" +
138  std::string(SDL_GetError());
140  return "EC DOUBLE_INIT - There was an attempted double-initialization in the program. Not too serious, but fix it anyways, nerd.";
142  return "EC GLEW_FAILURE - GLEW could not be initialized!";
144  return "EC GL_FAILURE_VERSION - GL Version is not good enough.";
146  return "EC TEXTURE_FAILURE - Texture could not be loaded from file or created.";
148  return "EC VERTEX_SHADER_FAILURE";
150  return "EC FRAGMENT_SHADER_FAILURE";
152  return "EC UNIFORM_NOT_FOUND";
154  return "EC SHADER_COMPILE_FAILURE";
156  return "EC SHADER_LINK_FAILURE";
158  return "EC GLSL_PROGRAM_FAILURE";
160  return "EC FONT_FAILURE";
162  return "EC FBO_FAILURE";
164  return "EC LOGGER_FAILURE";
166  return "EC XML_FAILURE";
168  return "EC UNINITIALIZED_FUNCTION";
170  return "EC LUA_FAILURE";
172  return "EC NULL_PTR_ACCESS";
173  default:
174  return "EC DNE - Unknown error. (enum " + std::to_string((unsigned int)err) + ")";
175  }
176  }
177 
178  void throwFatalError(BAREError err, std::string message) {
179  std::cout << "\n";
180  std::cout << std::setfill('#') << std::setw(50) << "\n";
181  std::cout << "FATAL ERROR: "
182  << "\n";
183  std::cout << std::setfill('#') << std::setw(50) << "\n\n";
184  throwError(err, message);
185  displayErrors();
186  std::raise(SIGABRT);
187  exit(EXIT_FAILURE);
188  }
189 
190  void throwError(BAREError err, std::string message) {
191  thrownErrors.push_back(err);
192  // We use std::cout just in case the Logger never actually got inited.
193  if(message != "") {
194  std::cout << std::setfill('-') << std::setw(50) << "\n";
195  std::cout << "Error: " << message << std::endl;
196  std::cout << thrownErrors.size() - 1 << ": " << getErrString(err) << std::endl;
197  std::cout << std::setfill('-') << std::setw(50) << "\n";
198  }
199  }
200 
201  void displayErrors() {
202  std::cout << std::endl << "Thrown Errors: " << std::endl;
203  std::cout << std::setfill('-') << std::setw(50) << "\n";
204  for(unsigned int i = 0; i < thrownErrors.size(); i++) {
205  std::cout << i << ": " << getErrString(thrownErrors[i]) << std::endl;
206  std::cout << std::setfill('-') << std::setw(50) << "\n";
207  }
208  thrownErrors.clear();
209  }
210 
212  GLErrorMinSeverity = minSeverity;
213 
214  GLboolean inited = GL_FALSE;
215  glGetBooleanv(GL_DEBUG_OUTPUT, &inited);
216 
217  if(!inited) {
218  glEnable(GL_DEBUG_OUTPUT);
219  glDebugMessageCallback(MessageCallback, 0);
220  }
221  }
222 } // namespace BARE2D
MessageCallback
void GLAPIENTRY MessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam)
Definition: BAREErrors.cpp:22
BARE2D::BAREError::GLEW_FAILURE
@ GLEW_FAILURE
BARE2D::BAREError::XML_FAILURE
@ XML_FAILURE
BARE2D::getErrString
std::string getErrString(BAREError err)
Returns the string representing/explaining the error that occurred.
Definition: BAREErrors.cpp:134
BARE2D
Definition: App.cpp:13
BARE2D::BAREError::GLSL_PROGRAM_FAILURE
@ GLSL_PROGRAM_FAILURE
BARE2D::Logger::getInstance
static Logger * getInstance()
Definition: Logger.cpp:34
BARE2D::BAREError::UNIFORM_NOT_FOUND
@ UNIFORM_NOT_FOUND
BARE2D::BAREError::SHADER_COMPILE_FAILURE
@ SHADER_COMPILE_FAILURE
BARE2D::BAREError::GL_FAILURE_VERSION
@ GL_FAILURE_VERSION
BARE2D::BAREError::SDL_FAILURE
@ SDL_FAILURE
BARE2D::BAREError::DOUBLE_INIT
@ DOUBLE_INIT
BARE2D::GLErrorSeverity::UNKNOWN
@ UNKNOWN
BARE2D::Logger::log
void log(std::string message, bool important=false)
Logs a message to a file and the terminal.
Definition: Logger.cpp:42
BARE2D::BAREError::UNINITIALIZED_FUNCTION
@ UNINITIALIZED_FUNCTION
BARE2D::BAREError::VERTEX_SHADER_FAILURE
@ VERTEX_SHADER_FAILURE
BARE2D::GLErrorSeverity::MED
@ MED
BAREErrors.hpp
BARE2D::BAREError
BAREError
Represents a specific type of error that has occured.
Definition: BAREErrors.hpp:18
BARE2D::throwError
void throwError(BAREError err, std::string message)
Throws an error silently. Adds it to the pile.
Definition: BAREErrors.cpp:190
BARE2D::BAREError::TEXTURE_FAILURE
@ TEXTURE_FAILURE
BARE2D::thrownErrors
std::vector< BAREError > thrownErrors
Definition: BAREErrors.cpp:132
BARE2D::BAREError::NULL_PTR_ACCESS
@ NULL_PTR_ACCESS
BARE2D::BAREError::LUA_FAILURE
@ LUA_FAILURE
BARE2D::displayErrors
void displayErrors()
Displays the latest thrown errors (really just all the thrown errors) in the console.
Definition: BAREErrors.cpp:201
BARE2D::GLErrorSeverity::NOTIF
@ NOTIF
BARE2D::GLErrorSeverity::LOW
@ LOW
BARE2D::BAREError::LOGGER_FAILURE
@ LOGGER_FAILURE
BARE2D::BAREError::FRAGMENT_SHADER_FAILURE
@ FRAGMENT_SHADER_FAILURE
BARE2D::BAREError::SHADER_LINK_FAILURE
@ SHADER_LINK_FAILURE
BARE2D::GLErrorSeverity
GLErrorSeverity
Definition: BAREErrors.hpp:49
BARE2D::BAREError::FBO_FAILURE
@ FBO_FAILURE
BARE2D::GLErrorSeverity::HIGH
@ HIGH
BARE2D::BAREError::FONT_FAILURE
@ FONT_FAILURE
BARE2D::initGLErrorCallback
void initGLErrorCallback(GLErrorSeverity minSeverity)
Initializes the GL Debug Message Callback function, and enables debug output straight from OpenGL.
Definition: BAREErrors.cpp:211
BARE2D::throwFatalError
void throwFatalError(BAREError err, std::string message)
Throws an error (fatal). Also calls displayErrors and exits the program.
Definition: BAREErrors.cpp:178
Logger.hpp
demangle
std::string demangle(const char *mangled)
PLEASE NOTE THAT IF MINGW BREAKS, THIS IS PROBABLY WHY.
Definition: BAREErrors.cpp:16
BARE2D::GLErrorMinSeverity
GLErrorSeverity GLErrorMinSeverity
Definition: BAREErrors.cpp:130