crn_console.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // File: crn_console.cpp
  2. // See Copyright Notice and license at the end of inc/crnlib.h
  3. #include "crn_core.h"
  4. #include "crn_console.h"
  5. #include "crn_data_stream.h"
  6. #include "crn_threading.h"
  7. namespace crnlib
  8. {
  9. eConsoleMessageType console::m_default_category = cInfoConsoleMessage;
  10. crnlib::vector<console::console_func> console::m_output_funcs;
  11. bool console::m_crlf = true;
  12. bool console::m_prefixes = true;
  13. bool console::m_output_disabled;
  14. data_stream* console::m_pLog_stream;
  15. mutex* console::m_pMutex;
  16. uint console::m_num_messages[cCMTTotal];
  17. bool console::m_at_beginning_of_line = true;
  18. const uint cConsoleBufSize = 4096;
  19. void console::init()
  20. {
  21. if (!m_pMutex)
  22. {
  23. m_pMutex = crnlib_new<mutex>();
  24. }
  25. }
  26. void console::deinit()
  27. {
  28. if (m_pMutex)
  29. {
  30. crnlib_delete(m_pMutex);
  31. m_pMutex = NULL;
  32. }
  33. }
  34. void console::disable_crlf()
  35. {
  36. init();
  37. m_crlf = false;
  38. }
  39. void console::enable_crlf()
  40. {
  41. init();
  42. m_crlf = true;
  43. }
  44. void console::vprintf(eConsoleMessageType type, const char* p, va_list args)
  45. {
  46. init();
  47. scoped_mutex lock(*m_pMutex);
  48. m_num_messages[type]++;
  49. char buf[cConsoleBufSize];
  50. vsprintf_s(buf, cConsoleBufSize, p, args);
  51. bool handled = false;
  52. if (m_output_funcs.size())
  53. {
  54. for (uint i = 0; i < m_output_funcs.size(); i++)
  55. if (m_output_funcs[i].m_func(type, buf, m_output_funcs[i].m_pData))
  56. handled = true;
  57. }
  58. const char* pPrefix = NULL;
  59. if ((m_prefixes) && (m_at_beginning_of_line))
  60. {
  61. switch (type)
  62. {
  63. case cDebugConsoleMessage: pPrefix = "Debug: "; break;
  64. case cWarningConsoleMessage: pPrefix = "Warning: "; break;
  65. case cErrorConsoleMessage: pPrefix = "Error: "; break;
  66. default: break;
  67. }
  68. }
  69. if ((!m_output_disabled) && (!handled))
  70. {
  71. if (pPrefix)
  72. ::printf("%s", pPrefix);
  73. ::printf(m_crlf ? "%s\n" : "%s", buf);
  74. }
  75. uint n = strlen(buf);
  76. m_at_beginning_of_line = (m_crlf) || ((n) && (buf[n - 1] == '\n'));
  77. if ((type != cProgressConsoleMessage) && (m_pLog_stream))
  78. {
  79. // Yes this is bad.
  80. dynamic_string tmp_buf(buf);
  81. tmp_buf.translate_lf_to_crlf();
  82. m_pLog_stream->printf(m_crlf ? "%s\r\n" : "%s", tmp_buf.get_ptr());
  83. m_pLog_stream->flush();
  84. }
  85. }
  86. void console::printf(eConsoleMessageType type, const char* p, ...)
  87. {
  88. va_list args;
  89. va_start(args, p);
  90. vprintf(type, p, args);
  91. va_end(args);
  92. }
  93. void console::printf(const char* p, ...)
  94. {
  95. va_list args;
  96. va_start(args, p);
  97. vprintf(m_default_category, p, args);
  98. va_end(args);
  99. }
  100. void console::set_default_category(eConsoleMessageType category)
  101. {
  102. init();
  103. m_default_category = category;
  104. }
  105. eConsoleMessageType console::get_default_category()
  106. {
  107. init();
  108. return m_default_category;
  109. }
  110. void console::add_console_output_func(console_output_func pFunc, void* pData)
  111. {
  112. init();
  113. scoped_mutex lock(*m_pMutex);
  114. m_output_funcs.push_back(console_func(pFunc, pData));
  115. }
  116. void console::remove_console_output_func(console_output_func pFunc)
  117. {
  118. init();
  119. scoped_mutex lock(*m_pMutex);
  120. for (int i = m_output_funcs.size() - 1; i >= 0; i--)
  121. {
  122. if (m_output_funcs[i].m_func == pFunc)
  123. {
  124. m_output_funcs.erase(m_output_funcs.begin() + i);
  125. }
  126. }
  127. if (!m_output_funcs.size())
  128. {
  129. m_output_funcs.clear();
  130. }
  131. }
  132. void console::progress(const char* p, ...)
  133. {
  134. va_list args;
  135. va_start(args, p);
  136. vprintf(cProgressConsoleMessage, p, args);
  137. va_end(args);
  138. }
  139. void console::info(const char* p, ...)
  140. {
  141. va_list args;
  142. va_start(args, p);
  143. vprintf(cInfoConsoleMessage, p, args);
  144. va_end(args);
  145. }
  146. void console::message(const char* p, ...)
  147. {
  148. va_list args;
  149. va_start(args, p);
  150. vprintf(cMessageConsoleMessage, p, args);
  151. va_end(args);
  152. }
  153. void console::cons(const char* p, ...)
  154. {
  155. va_list args;
  156. va_start(args, p);
  157. vprintf(cConsoleConsoleMessage, p, args);
  158. va_end(args);
  159. }
  160. void console::debug(const char* p, ...)
  161. {
  162. va_list args;
  163. va_start(args, p);
  164. vprintf(cDebugConsoleMessage, p, args);
  165. va_end(args);
  166. }
  167. void console::warning(const char* p, ...)
  168. {
  169. va_list args;
  170. va_start(args, p);
  171. vprintf(cWarningConsoleMessage, p, args);
  172. va_end(args);
  173. }
  174. void console::error(const char* p, ...)
  175. {
  176. va_list args;
  177. va_start(args, p);
  178. vprintf(cErrorConsoleMessage, p, args);
  179. va_end(args);
  180. }
  181. } // namespace crnlib