ErrorHandler.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //#include <Windows.h>
  2. #include "Config.h"
  3. #include "ConfigLoader.h"
  4. #include "ErrorHandler.h"
  5. #include "WindowLocator.h"
  6. // Predefined variables for "AddVariablePredef" macro
  7. #define ERR_TYP_PREDEF m_errorTypes
  8. #define ERR_DATA_PREDEF m_errorData
  9. #define ERR_DATA_TYPE_PREDEF m_errorType
  10. #define ERR_HASH_PREDEF m_errHashmap
  11. #define AssignErrorType(ERROR_CODE, ERROR_TYPE) ERR_DATA_PREDEF[ERROR_CODE].ERR_DATA_TYPE_PREDEF = ERROR_TYPE; ERR_HASH_PREDEF[GetString(ERROR_CODE)] = ERROR_CODE
  12. // AssignErrorType(ERROR_CODE, ERROR_TYPE) ERR_TYP_PREDEF[ERROR_CODE] = ERROR_TYPE; ERR_HASH_PREDEF[GetString(ERROR_CODE)] = ERROR_CODE
  13. //#define AssignErrorSource(ERROR_CODE, ERROR_TYPE) ERR_TYP_PREDEF[ERROR_CODE] = ERROR_TYPE; ERR_HASH_PREDEF[GetString(ERROR_CODE)] = ERROR_CODE
  14. ErrorHandler::ErrorHandler()
  15. {
  16. m_console = nullptr;
  17. // Add the error codes to the hash map and also assign their error types in the error type array
  18. AssignErrorType(Undefined, Warning);
  19. AssignErrorType(Success, Info);
  20. AssignErrorType(Failure, Warning);
  21. AssignErrorType(Initialize_success, Info);
  22. AssignErrorType(Initialize_failure, Info);
  23. AssignErrorType(File_not_found, Warning);
  24. AssignErrorType(Filename_empty, Warning);
  25. AssignErrorType(Audio_no_drivers, Error);
  26. AssignErrorType(Audio_system_init_failed, Error);
  27. AssignErrorType(Destroy_obj_not_found, Warning);
  28. AssignErrorType(Glew_failed, FatalError);
  29. AssignErrorType(Ifstream_failed, Warning);
  30. AssignErrorType(Clock_QueryFrequency, FatalError);
  31. AssignErrorType(Framebuffer_failed, FatalError);
  32. AssignErrorType(Geometrybuffer_failed, FatalError);
  33. AssignErrorType(Editor_path_outside_current_dir, Warning);
  34. AssignErrorType(GL_context_missing, Error);
  35. AssignErrorType(Window_handle_missing, Error);
  36. AssignErrorType(AssimpScene_failed, Error);
  37. AssignErrorType(ObjectPool_full, Warning);
  38. AssignErrorType(Collision_invalid, Warning);
  39. AssignErrorType(Collision_missing, Warning);
  40. AssignErrorType(Kinematic_has_mass, Warning);
  41. AssignErrorType(Property_missing_size, Warning);
  42. AssignErrorType(Property_missing_radius, Warning);
  43. AssignErrorType(Property_missing_type, Warning);
  44. AssignErrorType(Property_no_filename, Warning);
  45. AssignErrorType(Shader_attach_failed, Error);
  46. AssignErrorType(Shader_compile_failed, Error);
  47. AssignErrorType(Shader_creation_failed, Error);
  48. AssignErrorType(Shader_link_failed, Error);
  49. AssignErrorType(Shader_loading_failed, Error);
  50. AssignErrorType(GameObjects_missing, Error);
  51. AssignErrorType(Texture_not_found, Warning);
  52. AssignErrorType(Texture_empty, Warning);
  53. AssignErrorType(Invalid_num_vid_displays, Warning);
  54. AssignErrorType(SDL_video_init_failed, FatalError);
  55. AssignErrorType(SDL_vsync_failed, Warning);
  56. AssignErrorType(Window_creation_failed, FatalError);
  57. AssignErrorType(Invalid_object_id, Warning);
  58. AssignErrorType(Duplicate_object_id, Warning);
  59. // Add error sources to the hash map, and offset them by number of error codes, because they share the same hash map
  60. for(unsigned int i = 0; i < Source_NumberOfErrorSources; i++)
  61. {
  62. ErrorSource errorSource = static_cast<ErrorSource>(i);
  63. m_errHashmap[GetString(errorSource)] = NumberOfErrorCodes + errorSource;
  64. }
  65. // Add error types to the hash map, and offset them by number of error codes and error sources, because they share the same hash map
  66. m_errHashmap[GetString(Info)] = NumberOfErrorCodes + Source_NumberOfErrorSources + Info;
  67. m_errHashmap[GetString(Warning)] = NumberOfErrorCodes + Source_NumberOfErrorSources + Warning;
  68. m_errHashmap[GetString(Error)] = NumberOfErrorCodes + Source_NumberOfErrorSources + Error;
  69. m_errHashmap[GetString(FatalError)] = NumberOfErrorCodes + Source_NumberOfErrorSources + FatalError;
  70. }
  71. ErrorHandler::~ErrorHandler()
  72. {
  73. }
  74. ErrorCode ErrorHandler::init()
  75. {
  76. m_console = new CoutConsole;
  77. ConfigFile errorCodes;
  78. if(errorCodes.import(Config::filepathVar().config_path + Config::configFileVar().error_code_strings_eng, m_errHashmap) != Success)
  79. {
  80. log(ErrorType::Error, ErrorSource::Source_General, "Error strings has failed to load");
  81. }
  82. else
  83. {
  84. NodeIterator rootNode = errorCodes.getRootNode();
  85. NodeIterator it = rootNode.getNode("Error Codes");
  86. for(int i = 0; i < ErrorCode::NumberOfErrorCodes; i++)
  87. {
  88. m_errorData[i].m_errorString = it.getValue(i).getString();
  89. }
  90. it = rootNode.getNode("Error Sources");
  91. for(int i = ErrorCode::NumberOfErrorCodes, size = ErrorSource::Source_NumberOfErrorSources + ErrorCode::NumberOfErrorCodes; i < size; i++)
  92. m_errorSources[i - ErrorCode::NumberOfErrorCodes] = it.getValue(i).getString();
  93. it = rootNode.getNode("Error Types");
  94. for(int i = ErrorCode::NumberOfErrorCodes + ErrorSource::Source_NumberOfErrorSources,
  95. size = ErrorSource::Source_NumberOfErrorSources + ErrorCode::NumberOfErrorCodes + ErrorType::NumberOfErrorTypes; i < size; i++)
  96. m_errorTypeStrings[i - ErrorCode::NumberOfErrorCodes - ErrorSource::Source_NumberOfErrorSources] = it.getValue(i).getString();
  97. }
  98. return ErrorCode::Success;
  99. }
  100. void ErrorHandler::log(ErrorCode p_errorCode)
  101. {
  102. log(p_errorCode, ErrorSource::Source_Unknown);
  103. }
  104. void ErrorHandler::log(ErrorCode p_errorCode, ErrorSource p_errorSource)
  105. {
  106. if(p_errorCode == ErrorCode::CachedError)
  107. {
  108. if(m_cachedError.errorPresent())
  109. {
  110. log(m_errorData[m_cachedError.m_errorCode].m_errorType, p_errorSource, m_errorData[m_cachedError.m_errorCode].m_errorString + ": " + m_cachedError.m_errorString);
  111. m_cachedError.clear();
  112. }
  113. }
  114. else
  115. log(m_errorData[p_errorCode].m_errorType, p_errorSource, m_errorData[p_errorCode].m_errorString);
  116. }
  117. void ErrorHandler::log(ErrorType p_errorType, ErrorSource p_errorSource, std::string p_error)
  118. {
  119. // If the engine has already been set to shutdown, don't process any errors
  120. if(Config::m_engineVar.running == true)
  121. {
  122. std::string displayMessage;
  123. switch(p_errorType)
  124. {
  125. case ErrorType::Info:
  126. {
  127. m_console->displayMessage(m_errorTypeStrings[p_errorType] + ": " + m_errorSources[p_errorSource] + ": " + p_error + ".");
  128. break;
  129. }
  130. case ErrorType::Warning:
  131. {
  132. m_console->displayMessage(m_errorTypeStrings[p_errorType] + ": " + m_errorSources[p_errorSource] + ": " + p_error + ".");
  133. break;
  134. }
  135. case ErrorType::Error:
  136. {
  137. // Remove a 'new line' character if it's present, as it would break the formating
  138. if(p_error[p_error.size() - 1] == '\n')
  139. p_error.pop_back();
  140. // TODO make the error question data driven
  141. if(!WindowLocator().get().spawnYesNoErrorBox(m_errorTypeStrings[p_errorType] + ": " + m_errorSources[p_errorSource], m_errorSources[p_errorSource] + ": " + p_error + ".\n\nWould you like to continue?"))
  142. Config::m_engineVar.running = false;
  143. break;
  144. }
  145. case ErrorType::FatalError:
  146. {
  147. WindowLocator().get().spawnErrorBox(m_errorTypeStrings[p_errorType] + ": " + m_errorSources[p_errorSource], m_errorSources[p_errorSource] + ": " + p_error + ".");
  148. Config::m_engineVar.running = false;
  149. break;
  150. }
  151. default:
  152. break;
  153. }
  154. }
  155. }
  156. void ErrorHandler::log(ErrorCode p_errorCode, ErrorSource p_errorSource, std::string p_error)
  157. {
  158. if(p_errorCode == ErrorCode::CachedError)
  159. {
  160. if(m_cachedError.errorPresent())
  161. {
  162. log(m_errorData[m_cachedError.m_errorCode].m_errorType, p_errorSource, m_errorData[m_cachedError.m_errorCode].m_errorString + ": " + p_error + ": " + m_cachedError.m_errorString);
  163. m_cachedError.clear();
  164. }
  165. }
  166. else
  167. log(m_errorData[p_errorCode].m_errorType, p_errorSource, m_errorData[p_errorCode].m_errorString + ": " + p_error);
  168. }
  169. void ErrorHandler::log(const ErrorCode p_errorCode, const std::string &p_objectName, const ErrorSource p_errorSource)
  170. {
  171. log(m_errorData[p_errorCode].m_errorType, p_errorSource, "\'" + p_objectName + "\': " + m_errorData[p_errorCode].m_errorString);
  172. }