ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Logging.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 #include <functional>
11 #include <iostream>
12 #include <sstream>
13 #include <string>
14 
15 #include "CVCoreLib.h"
16 
17 // NVCC does not support deprecated attribute on Windows prior to v11.
18 #if defined(__CUDACC__) && defined(_MSC_VER) && __CUDACC_VER_MAJOR__ < 11
19 #ifndef FMT_DEPRECATED
20 #define FMT_DEPRECATED
21 #endif
22 #endif
23 
24 #include <fmt/core.h>
25 #include <fmt/printf.h>
26 #include <fmt/ranges.h>
27 #if FMT_VERSION >= 100000
28 #include <fmt/std.h>
29 #endif
30 
31 #define DEFAULT_IO_BUFFER_SIZE 1024
32 
33 // Compiler-specific function macro.
34 // Ref: https://stackoverflow.com/a/4384825
35 #ifdef _WIN32
36 #define __FN__ __FUNCSIG__
37 #else
38 #define __FN__ __PRETTY_FUNCTION__
39 #endif
40 
41 // Mimic "macro in namespace" by concatenating `utility::` and a macro.
42 // Ref: https://stackoverflow.com/a/11791202
43 //
44 // We avoid using (format, ...) since in this case __VA_ARGS__ can be
45 // empty, and the behavior of pruning trailing comma with ##__VA_ARGS__ is not
46 // officially standard.
47 // Ref: https://stackoverflow.com/a/28074198
48 //
49 // __PRETTY_FUNCTION__ has to be converted, otherwise a bug regarding [noreturn]
50 // will be triggered.
51 // Ref: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94742
52 
53 // LogError throws now a runtime_error with the given error message. This
54 // should be used if there is no point in continuing the given algorithm at
55 // some point and the error is not returned in another way (e.g., via a
56 // bool/int as return value).
57 //
58 // Usage : utility::LogError(format_string, arg0, arg1, ...);
59 // Example: utility::LogError("name: {}, age: {}", "dog", 5);
60 #define LogError(...) \
61  Logger::LogError_(__FILE__, __LINE__, static_cast<const char *>(__FN__), \
62  __VA_ARGS__)
63 
64 // LogWarning is used if an error occurs, but the error is also signaled
65 // via a return value (i.e., there is no need to throw an exception). This
66 // warning should further be used, if the algorithms encounters a state
67 // that does not break its continuation, but the output is likely not to be
68 // what the user expected.
69 //
70 // Usage : utility::LogWarning(format_string, arg0, arg1, ...);
71 // Example: utility::LogWarning("name: {}, age: {}", "dog", 5);
72 #define LogWarning(...) \
73  Logger::LogWarning_(__FILE__, __LINE__, static_cast<const char *>(__FN__), \
74  __VA_ARGS__)
75 
76 // LogInfo is used to inform the user with expected output, e.g, pressed a
77 // key in the visualizer prints helping information.
78 //
79 // Usage : utility::LogInfo(format_string, arg0, arg1, ...);
80 // Example: utility::LogInfo("name: {}, age: {}", "dog", 5);
81 #define LogInfo(...) \
82  Logger::LogInfo_(__FILE__, __LINE__, static_cast<const char *>(__FN__), \
83  __VA_ARGS__)
84 
85 // LogDebug is used to print debug/additional information on the state of
86 // the algorithm.
87 //
88 // Usage : utility::LogDebug(format_string, arg0, arg1, ...);
89 // Example: utility::LogDebug("name: {}, age: {}", "dog", 5);
90 #define LogDebug(...) \
91  Logger::LogDebug_(__FILE__, __LINE__, static_cast<const char *>(__FN__), \
92  __VA_ARGS__)
93 
94 namespace cloudViewer {
95 namespace utility {
96 
102  Error = 0,
108  Warning = 1,
111  Info = 2,
114  Debug = 3,
115 };
116 
118  Black = 0,
119  Red = 1,
120  Green = 2,
121  Yellow = 3,
122  Blue = 4,
123  Magenta = 5,
124  Cyan = 6,
125  White = 7
126 };
127 
130 public:
132  // The current print function.
133  std::function<void(const std::string &)> print_fcn_;
134 
135  // The default print function (that prints to console).
136  static std::function<void(const std::string &)> console_print_fcn_;
137 
138  // Verbosity level.
140 
141  // Colorize and reset the color of a string, does not work on Windows,
142  std::string ColorString(const std::string &text,
143  TextColor text_color,
144  int highlight_text) const {
145  std::ostringstream msg;
146 #ifndef _WIN32
147  msg << fmt::sprintf("%c[%d;%dm", 0x1B, highlight_text,
148  (int)text_color + 30);
149 #endif
150  msg << text;
151 #ifndef _WIN32
152  msg << fmt::sprintf("%c[0;m", 0x1B);
153 #endif
154  return msg.str();
155  }
156  };
157 
158 public:
159  Logger(Logger const &) = delete;
160  void operator=(Logger const &) = delete;
161 
163  static Logger &GetInstance();
164 
171  void SetPrintFunction(std::function<void(const std::string &)> print_fcn);
172 
174  void ResetPrintFunction();
175 
177  const std::function<void(const std::string &)> GetPrintFunction();
178 
183  void SetVerbosityLevel(VerbosityLevel verbosity_level);
184 
187 
188  template <typename... Args>
189  static void LogError_ [[noreturn]] (const char *file,
190  int line,
191  const char *function,
192  const char *format,
193  Args &&...args) {
194  if (sizeof...(Args) > 0) {
195  Logger::GetInstance().VError(
196  file, line, function,
197  FormatArgs(format, fmt::make_format_args(args...)));
198  } else {
199  Logger::GetInstance().VError(file, line, function,
200  std::string(format));
201  }
202  }
203  template <typename... Args>
204  static void LogWarning_(const char *file,
205  int line,
206  const char *function,
207  const char *format,
208  Args &&...args) {
211  if (sizeof...(Args) > 0) {
212  Logger::GetInstance().VWarning(
213  file, line, function,
214  FormatArgs(format, fmt::make_format_args(args...)));
215  } else {
216  Logger::GetInstance().VWarning(file, line, function,
217  std::string(format));
218  }
219  }
220  }
221  template <typename... Args>
222  static void LogInfo_(const char *file,
223  int line,
224  const char *function,
225  const char *format,
226  Args &&...args) {
228  if (sizeof...(Args) > 0) {
229  Logger::GetInstance().VInfo(
230  file, line, function,
231  FormatArgs(format, fmt::make_format_args(args...)));
232  } else {
233  Logger::GetInstance().VInfo(file, line, function,
234  std::string(format));
235  }
236  }
237  }
238  template <typename... Args>
239  static void LogDebug_(const char *file,
240  int line,
241  const char *function,
242  const char *format,
243  Args &&...args) {
246  if (sizeof...(Args) > 0) {
247  Logger::GetInstance().VDebug(
248  file, line, function,
249  FormatArgs(format, fmt::make_format_args(args...)));
250  } else {
251  Logger::GetInstance().VDebug(file, line, function,
252  std::string(format));
253  }
254  }
255  }
256 
257 private:
258  Logger();
259  static std::string FormatArgs(const char *format, fmt::format_args args) {
260  std::string err_msg = fmt::vformat(format, args);
261  return err_msg;
262  }
263  void VError [[noreturn]] (const char *file,
264  int line,
265  const char *function,
266  const std::string &message) const;
267  void VWarning(const char *file,
268  int line,
269  const char *function,
270  const std::string &message) const;
271  void VInfo(const char *file,
272  int line,
273  const char *function,
274  const std::string &message) const;
275  void VDebug(const char *file,
276  int line,
277  const char *function,
278  const std::string &message) const;
279 
280 private:
281  std::unique_ptr<Impl> impl_;
282 };
283 
289 
292 
294 public:
295  VerbosityContextManager(VerbosityLevel level) : level_(level) {}
296 
297  void Enter() {
298  level_backup_ = Logger::GetInstance().GetVerbosityLevel();
300  }
301 
302  void Exit() { Logger::GetInstance().SetVerbosityLevel(level_backup_); }
303 
304 private:
305  VerbosityLevel level_;
306  VerbosityLevel level_backup_;
307 };
308 
310 public:
311  ConsoleProgressBar(size_t expected_count,
312  const std::string &progress_info,
313  bool active = false);
314 
315  void reset(size_t expected_count,
316  const std::string &progress_info,
317  bool active);
318 
319  ConsoleProgressBar &operator++();
320 
321  void setCurrentCount(size_t n);
322 
323 private:
324  const size_t resolution_ = 40;
325  size_t expected_count_;
326  size_t current_count_;
327  std::string progress_info_;
328  size_t progress_pixel_;
329  bool active_;
330 };
331 
332 } // namespace utility
333 } // namespace cloudViewer
#define CV_CORE_LIB_API
Definition: CVCoreLibWin.h:15
filament::Texture::InternalFormat format
Logger class should be used as a global singleton object (GetInstance()).
Definition: Logging.h:129
static void LogWarning_(const char *file, int line, const char *function, const char *format, Args &&...args)
Definition: Logging.h:204
void operator=(Logger const &)=delete
static void LogDebug_(const char *file, int line, const char *function, const char *format, Args &&...args)
Definition: Logging.h:239
Logger(Logger const &)=delete
static void LogInfo_(const char *file, int line, const char *function, const char *format, Args &&...args)
Definition: Logging.h:222
void SetVerbosityLevel(VerbosityLevel verbosity_level)
Definition: Logging.cpp:81
static Logger & GetInstance()
Get Logger global singleton instance.
Definition: Logging.cpp:25
VerbosityLevel GetVerbosityLevel() const
Get global verbosity level of CloudViewer.
Definition: Logging.cpp:85
VerbosityContextManager(VerbosityLevel level)
Definition: Logging.h:295
ccGuiPythonInstance * GetInstance() noexcept
Definition: Runtime.cpp:72
void SetVerbosityLevel(VerbosityLevel level)
Definition: Logging.cpp:89
VerbosityLevel GetVerbosityLevel()
Get global verbosity level of CloudViewer.
Definition: Logging.cpp:93
Generic file read and write utility for python interface.
std::function< void(const std::string &)> print_fcn_
Definition: Logging.h:133
std::string ColorString(const std::string &text, TextColor text_color, int highlight_text) const
Definition: Logging.h:142
static std::function< void(const std::string &)> console_print_fcn_
Definition: Logging.h:136