Logger.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2019.08.13
  7. #pragma once
  8. #include <mutex>
  9. #include <set>
  10. #include <stdexcept>
  11. #include <string>
  12. namespace WwiseGTE
  13. {
  14. class Logger
  15. {
  16. public:
  17. // Listeners subscribe to Logger to receive message strings.
  18. class Listener
  19. {
  20. public:
  21. enum
  22. {
  23. LISTEN_FOR_NOTHING = 0x00000000,
  24. LISTEN_FOR_ASSERTION = 0x00000001,
  25. LISTEN_FOR_ERROR = 0x00000002,
  26. LISTEN_FOR_WARNING = 0x00000004,
  27. LISTEN_FOR_INFORMATION = 0x00000008,
  28. LISTEN_FOR_ALL = 0xFFFFFFFF
  29. };
  30. // Construction and destruction.
  31. virtual ~Listener() = default;
  32. Listener(int flags = LISTEN_FOR_NOTHING)
  33. :
  34. mFlags(flags)
  35. {
  36. }
  37. // What the listener wants to hear.
  38. inline int GetFlags() const
  39. {
  40. return mFlags;
  41. }
  42. // Handlers for the messages received from the logger.
  43. void Assertion(std::string const& message)
  44. {
  45. Report("\nGTE ASSERTION:\n" + message);
  46. }
  47. void Error(std::string const& message)
  48. {
  49. Report("\nGTE ERROR:\n" + message);
  50. }
  51. void Warning(std::string const& message)
  52. {
  53. Report("\nGTE WARNING:\n" + message);
  54. }
  55. void Information(std::string const& message)
  56. {
  57. Report("\nGTE INFORMATION:\n" + message);
  58. }
  59. private:
  60. virtual void Report(std::string const& message)
  61. {
  62. // Stub for derived classes.
  63. (void)message;
  64. }
  65. int mFlags;
  66. };
  67. // Construction. The Logger object is designed to exist only for a
  68. // single-line call. A string is generated from the input parameters and
  69. // is used for reporting.
  70. Logger(char const* file, char const* function, int line, std::string const& message)
  71. {
  72. mMessage =
  73. "File: " + std::string(file) + "\n" +
  74. "Func: " + std::string(function) + "\n" +
  75. "Line: " + std::to_string(line) + "\n" +
  76. message + "\n\n";
  77. }
  78. // Notify current listeners about the logged information.
  79. void Assertion()
  80. {
  81. Mutex().lock();
  82. for (auto listener : Listeners())
  83. {
  84. if (listener->GetFlags() & Listener::LISTEN_FOR_ASSERTION)
  85. {
  86. listener->Assertion(mMessage);
  87. }
  88. }
  89. Mutex().unlock();
  90. }
  91. void Error()
  92. {
  93. Mutex().lock();
  94. for (auto listener : Listeners())
  95. {
  96. if (listener->GetFlags() & Listener::LISTEN_FOR_ERROR)
  97. {
  98. listener->Error(mMessage);
  99. }
  100. }
  101. Mutex().unlock();
  102. }
  103. void Warning()
  104. {
  105. Mutex().lock();
  106. for (auto listener : Listeners())
  107. {
  108. if (listener->GetFlags() & Listener::LISTEN_FOR_WARNING)
  109. {
  110. listener->Warning(mMessage);
  111. }
  112. }
  113. Mutex().unlock();
  114. }
  115. void Information()
  116. {
  117. Mutex().lock();
  118. for (auto listener : Listeners())
  119. {
  120. if (listener->GetFlags() & Listener::LISTEN_FOR_INFORMATION)
  121. {
  122. listener->Information(mMessage);
  123. }
  124. }
  125. Mutex().unlock();
  126. }
  127. static void Subscribe(Listener* listener)
  128. {
  129. Mutex().lock();
  130. Listeners().insert(listener);
  131. Mutex().unlock();
  132. }
  133. static void Unsubscribe(Listener* listener)
  134. {
  135. Mutex().lock();
  136. Listeners().erase(listener);
  137. Mutex().unlock();
  138. }
  139. private:
  140. std::string mMessage;
  141. static std::mutex& Mutex()
  142. {
  143. static std::mutex sMutex;
  144. return sMutex;
  145. }
  146. static std::set<Listener*>& Listeners()
  147. {
  148. static std::set<Listener*> sListeners;
  149. return sListeners;
  150. }
  151. };
  152. }
  153. #define LogAssert(condition, message) \
  154. if (!(condition)) \
  155. { \
  156. WwiseGTE::Logger(__FILE__, __FUNCTION__, __LINE__, message).Assertion(); \
  157. throw std::runtime_error(message); \
  158. }
  159. #define LogError(message) \
  160. WwiseGTE::Logger(__FILE__, __FUNCTION__, __LINE__, message).Error(); \
  161. throw std::runtime_error(message)
  162. #define LogWarning(message) \
  163. WwiseGTE::Logger(__FILE__, __FUNCTION__, __LINE__, message).Warning()
  164. #define LogInformation(message) \
  165. WwiseGTE::Logger(__FILE__, __FUNCTION__, __LINE__, message).Information()