Logger.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #ifndef ANKI_UTIL_LOGGER_H
  6. #define ANKI_UTIL_LOGGER_H
  7. #include "anki/Config.h"
  8. #include "anki/util/Singleton.h"
  9. #include "anki/util/Thread.h"
  10. namespace anki {
  11. // Forward
  12. class File;
  13. /// @addtogroup util_private
  14. /// @{
  15. /// The logger singleton class. The logger cannot print errors or throw
  16. /// exceptions, it has to recover somehow. Its thread safe
  17. /// To add a new signal:
  18. /// @code logger.addMessageHandler((void*)obj, &function) @endcode
  19. class Logger
  20. {
  21. public:
  22. /// Logger message type
  23. enum class MessageType: U8
  24. {
  25. NORMAL,
  26. ERROR,
  27. WARNING,
  28. FATAL,
  29. COUNT
  30. };
  31. /// Used as parammeter when emitting the signal
  32. class Info
  33. {
  34. public:
  35. const char* m_file;
  36. I32 m_line;
  37. const char* m_func;
  38. MessageType m_type;
  39. const char* m_msg;
  40. };
  41. /// The message handler callback
  42. using MessageHandlerCallback = void (*)(void*, const Info& info);
  43. /// Initialize the logger and add the default message handler
  44. Logger();
  45. ~Logger();
  46. /// Add a new message handler
  47. void addMessageHandler(void* data, MessageHandlerCallback callback);
  48. /// Add file message handler.
  49. void addFileMessageHandler(File* file);
  50. /// Send a message
  51. void write(const char* file, int line, const char* func,
  52. MessageType type, const char* msg);
  53. /// Send a formated message
  54. void writeFormated(const char* file, int line, const char* func,
  55. MessageType type, const char* fmt, ...);
  56. private:
  57. class Handler
  58. {
  59. public:
  60. void* m_data = nullptr;
  61. MessageHandlerCallback m_callback = nullptr;
  62. Handler() = default;
  63. Handler(const Handler&) = default;
  64. Handler(void* data, MessageHandlerCallback callback)
  65. : m_data(data),
  66. m_callback(callback)
  67. {}
  68. };
  69. Mutex m_mutex; ///< For thread safety
  70. Array<Handler, 4> m_handlers;
  71. U32 m_handlersCount = 0;
  72. static void defaultSystemMessageHandler(void*, const Info& info);
  73. static void fileMessageHandler(void* file, const Info& info);
  74. };
  75. typedef Singleton<Logger> LoggerSingleton;
  76. #define ANKI_LOGGER_MESSAGE(t, ...) \
  77. do \
  78. { \
  79. LoggerSingleton::get().writeFormated(ANKI_FILE, __LINE__, ANKI_FUNC, \
  80. t, __VA_ARGS__); \
  81. } while(false);
  82. /// @}
  83. /// @addtogroup util_logging
  84. /// @{
  85. /// Log information message.
  86. #define ANKI_LOGI(...) ANKI_LOGGER_MESSAGE(Logger::MessageType::NORMAL, \
  87. __VA_ARGS__)
  88. /// Log warning message.
  89. #define ANKI_LOGW(...) ANKI_LOGGER_MESSAGE(Logger::MessageType::WARNING, \
  90. __VA_ARGS__)
  91. /// Log error message.
  92. #define ANKI_LOGE(...) ANKI_LOGGER_MESSAGE(Logger::MessageType::ERROR, \
  93. __VA_ARGS__)
  94. /// Log fatal message. It will will abort.
  95. #define ANKI_LOGF(...) ANKI_LOGGER_MESSAGE(Logger::MessageType::FATAL, \
  96. __VA_ARGS__)
  97. /// @}
  98. } // end namespace anki
  99. #endif