Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
3.5KB

  1. // Copyright: 2014, Ableton AG, Berlin, all rights reserved
  2. #pragma once
  3. #include <ableton/util/Injected.hpp>
  4. #include <iostream>
  5. #include <string>
  6. namespace ableton
  7. {
  8. namespace util
  9. {
  10. // Null object for the Log concept
  11. struct NullLog
  12. {
  13. template <typename T>
  14. friend const NullLog& operator<<(const NullLog& log, const T&)
  15. {
  16. return log;
  17. }
  18. friend const NullLog& debug(const NullLog& log)
  19. {
  20. return log;
  21. }
  22. friend const NullLog& info(const NullLog& log)
  23. {
  24. return log;
  25. }
  26. friend const NullLog& warning(const NullLog& log)
  27. {
  28. return log;
  29. }
  30. friend const NullLog& error(const NullLog& log)
  31. {
  32. return log;
  33. }
  34. friend NullLog channel(const NullLog&, std::string)
  35. {
  36. return {};
  37. }
  38. };
  39. // std streams-based log
  40. struct StdLog
  41. {
  42. StdLog(std::string channelName = "")
  43. : mChannelName(std::move(channelName))
  44. {
  45. }
  46. // Stream type used by std log to prepend the channel name to log messages
  47. struct StdLogStream
  48. {
  49. StdLogStream(std::ostream& ioStream, const std::string& channelName)
  50. : mpIoStream(&ioStream)
  51. , mChannelName(channelName)
  52. {
  53. ioStream << "[" << mChannelName << "] ";
  54. }
  55. StdLogStream(StdLogStream&& rhs)
  56. : mpIoStream(rhs.mpIoStream)
  57. , mChannelName(rhs.mChannelName)
  58. {
  59. rhs.mpIoStream = nullptr;
  60. }
  61. ~StdLogStream()
  62. {
  63. if (mpIoStream)
  64. {
  65. (*mpIoStream) << "\n";
  66. }
  67. }
  68. template <typename T>
  69. std::ostream& operator<<(const T& rhs)
  70. {
  71. (*mpIoStream) << rhs;
  72. return *mpIoStream;
  73. }
  74. std::ostream* mpIoStream;
  75. const std::string& mChannelName;
  76. };
  77. friend StdLogStream debug(const StdLog& log)
  78. {
  79. return {std::clog, log.mChannelName};
  80. }
  81. friend StdLogStream info(const StdLog& log)
  82. {
  83. return {std::clog, log.mChannelName};
  84. }
  85. friend StdLogStream warning(const StdLog& log)
  86. {
  87. return {std::clog, log.mChannelName};
  88. }
  89. friend StdLogStream error(const StdLog& log)
  90. {
  91. return {std::cerr, log.mChannelName};
  92. }
  93. friend StdLog channel(const StdLog& log, const std::string& channelName)
  94. {
  95. auto compositeName =
  96. log.mChannelName.empty() ? channelName : log.mChannelName + "::" + channelName;
  97. return {std::move(compositeName)};
  98. }
  99. std::string mChannelName;
  100. };
  101. // Log adapter that adds timestamps
  102. template <typename Log>
  103. struct Timestamped
  104. {
  105. using InnerLog = typename util::Injected<Log>::type;
  106. Timestamped() = default;
  107. Timestamped(util::Injected<Log> log)
  108. : mLog(std::move(log))
  109. {
  110. }
  111. util::Injected<Log> mLog;
  112. friend decltype(debug(std::declval<InnerLog>())) debug(const Timestamped& log)
  113. {
  114. return log.logTimestamp(debug(*log.mLog));
  115. }
  116. friend decltype(info(std::declval<InnerLog>())) info(const Timestamped& log)
  117. {
  118. return log.logTimestamp(info(*log.mLog));
  119. }
  120. friend decltype(warning(std::declval<InnerLog>())) warning(const Timestamped& log)
  121. {
  122. return log.logTimestamp(warning(*log.mLog));
  123. }
  124. friend decltype(error(std::declval<InnerLog>())) error(const Timestamped& log)
  125. {
  126. return log.logTimestamp(error(*log.mLog));
  127. }
  128. friend Timestamped channel(const Timestamped& log, const std::string& channelName)
  129. {
  130. return {channel(*log.mLog, channelName)};
  131. }
  132. template <typename Stream>
  133. Stream logTimestamp(Stream&& streamRef) const
  134. {
  135. using namespace std::chrono;
  136. Stream stream = std::forward<Stream>(streamRef);
  137. stream << "|"
  138. << duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count()
  139. << "ms| ";
  140. return stream;
  141. }
  142. };
  143. } // namespace util
  144. } // namespace ableton