stub_analytics_plugin  1.6
Network Optix Video Analytics SDK
debug.h
Go to the documentation of this file.
1 #pragma once
2 
10 #include <iostream>
11 #include <cstdint>
12 #include <functional>
13 #include <sstream>
14 #include <memory>
15 
16 #include <nx/kit/utils.h>
17 
18 #if !defined(NX_KIT_API)
19  #define NX_KIT_API /*empty*/
20 #endif
21 
22 namespace nx {
23 namespace kit {
24 namespace debug {
25 
26 //-------------------------------------------------------------------------------------------------
27 // Tools
28 
30 NX_KIT_API char pathSeparator();
31 
32 NX_KIT_API size_t commonPrefixSize(const std::string& s1, const std::string& s2);
33 
38 NX_KIT_API const char* relativeSrcFilename(const char* file);
39 
40 NX_KIT_API std::string fileBaseNameWithoutExt(const char* file);
41 
42 //-------------------------------------------------------------------------------------------------
43 // Output
44 
46 #if defined(NX_PRINT_TO_QDEBUG)
47  #define NX_DEBUG_STREAM qDebug().nospace().noquote()
48  #define NX_DEBUG_ENDL /*empty*/
49  static inline QDebug operator<<(QDebug d, const std::string& s)
50  {
51  return d << QString::fromStdString(s);
52  }
53 #endif
54 
55 #if !defined(NX_DEBUG_INI)
56 
57  #define NX_DEBUG_INI ini().
58 #endif
59 
60 #if !defined(NX_DEBUG_ENABLE_OUTPUT)
61 
62  #define NX_DEBUG_ENABLE_OUTPUT NX_DEBUG_INI enableOutput
63 #endif
64 
65 #if !defined(NX_PRINT_PREFIX)
66 
67  #define NX_PRINT_PREFIX ::nx::kit::debug::detail::printPrefix(__FILE__)
68 #endif
69 
70 #if !defined(NX_DEBUG_STREAM)
71 
72  #define NX_DEBUG_STREAM *::nx::kit::debug::stream()
73 #endif
74 
75 #if !defined(NX_DEBUG_ENDL)
76 
77  #define NX_DEBUG_ENDL << std::endl
78 #endif
79 
84 NX_KIT_API std::ostream*& stream();
85 
86 #if !defined(NX_PRINT)
87 
91  #define NX_PRINT /* << args... */ \
92  /* Allocate a temp value, which prints endl in its destructor, in the "<<" expression. */ \
93  ( []() { struct Endl { ~Endl() { NX_DEBUG_STREAM NX_DEBUG_ENDL; } }; \
94  return std::make_shared<Endl>(); }() ) /*operator,*/, \
95  NX_DEBUG_STREAM << NX_PRINT_PREFIX
96 #endif
97 
101 #define NX_OUTPUT /* << args... */ \
102  for (/* Executed either once or never; `for` instead of `if` gives no warnings. */ \
103  int NX_KIT_DEBUG_DETAIL_CONCAT(nxOutput_, __line__) = 0; \
104  NX_KIT_DEBUG_DETAIL_CONCAT(nxOutput_, __line__) != 1 && (NX_DEBUG_ENABLE_OUTPUT); \
105  ++NX_KIT_DEBUG_DETAIL_CONCAT(nxOutput_, __line__) \
106  ) NX_PRINT
107 
108 //-------------------------------------------------------------------------------------------------
109 // Assertions
110 
126 #define NX_KIT_ASSERT(/* CONDITION, MESSAGE = "" */ ...) \
127  NX_KIT_DEBUG_DETAIL_MSVC_EXPAND(NX_KIT_DEBUG_DETAIL_GET_3RD_ARG( \
128  __VA_ARGS__, NX_KIT_DEBUG_DETAIL_ASSERT2, NX_KIT_DEBUG_DETAIL_ASSERT1, \
129  /* Helps to generate a reasonable compiler error. */ args_required)(__VA_ARGS__))
130 
131 //-------------------------------------------------------------------------------------------------
132 // Print info
133 
137 #define LL \
138  NX_PRINT << "####### LL line " << __LINE__ \
139  << NX_KIT_DEBUG_DETAIL_THREAD_ID() \
140  << ", file " << ::nx::kit::debug::relativeSrcFilename(__FILE__);
141 
145 #define NX_PRINT_VALUE(VALUE) \
146  NX_PRINT << "####### " #VALUE ": " << ::nx::kit::utils::toString((VALUE))
147 
151 #define NX_PRINT_HEX_DUMP(CAPTION, BYTES, SIZE) \
152  ::nx::kit::debug::detail::printHexDump( \
153  NX_KIT_DEBUG_DETAIL_PRINT_FUNC, (CAPTION), (const char*) (BYTES), (int) (SIZE))
154 
155 //-------------------------------------------------------------------------------------------------
156 // Time
157 
158 #if !defined(NX_DEBUG_ENABLE_TIME)
159 
160  #define NX_DEBUG_ENABLE_TIME NX_DEBUG_INI enableTime
161 #endif
162 
166 #define NX_TIME_BEGIN(TAG) \
167  ::nx::kit::debug::detail::Timer nxTimer_##TAG( \
168  (NX_DEBUG_ENABLE_TIME), NX_KIT_DEBUG_DETAIL_PRINT_FUNC, #TAG)
169 
174 #define NX_TIME_MARK(TAG, MARK) do \
175 { \
176  if (NX_DEBUG_ENABLE_TIME) \
177  nxTimer_##TAG.mark((MARK)); \
178 } while (0)
179 
183 #define NX_TIME_END(TAG) do \
184 { \
185  if (NX_DEBUG_ENABLE_TIME) \
186  nxTimer_##TAG.finish(); \
187 } while (0)
188 
189 //-------------------------------------------------------------------------------------------------
190 // Fps
191 
192 #if !defined(NX_DEBUG_ENABLE_FPS)
193 
194  #define NX_DEBUG_ENABLE_FPS NX_DEBUG_INI enableFps
195 #endif
196 
201 #define NX_FPS(TAG, /*OPTIONAL_MARK*/...) do \
202 { \
203  if (NX_KIT_DEBUG_DETAIL_CONCAT(NX_DEBUG_ENABLE_FPS, TAG)) \
204  { \
205  static ::nx::kit::debug::detail::Fps fps( \
206  NX_KIT_DEBUG_DETAIL_PRINT_FUNC, #TAG); \
207  fps.mark(__VA_ARGS__); \
208  } \
209 } while (0)
210 
211 //-------------------------------------------------------------------------------------------------
212 // Implementation
213 
214 namespace detail {
215 
216 typedef std::function<void(const char*)> PrintFunc;
217 
218 #define NX_KIT_DEBUG_DETAIL_PRINT_FUNC ([&](const char* message) { NX_PRINT << message; })
219 
224 #define NX_KIT_DEBUG_DETAIL_MSVC_EXPAND(ARG) ARG
225 
227 #define NX_KIT_DEBUG_DETAIL_GET_3RD_ARG(ARG1, ARG2, ARG3, ...) ARG3
228 
229 #define NX_KIT_DEBUG_DETAIL_ASSERT1(CONDITION) \
230  ::nx::kit::debug::detail::doAssert( \
231  !!(CONDITION), NX_KIT_DEBUG_DETAIL_PRINT_FUNC, #CONDITION, "", __FILE__, __LINE__)
232 
233 #define NX_KIT_DEBUG_DETAIL_ASSERT2(CONDITION, MESSAGE) \
234  ::nx::kit::debug::detail::doAssert( \
235  !!(CONDITION), NX_KIT_DEBUG_DETAIL_PRINT_FUNC, #CONDITION, MESSAGE, __FILE__, __LINE__)
236 
237 NX_KIT_API void assertionFailed(
238  PrintFunc printFunc, const char* conditionStr, const std::string& message,
239  const char* file, int line);
240 
241 inline bool doAssert(
242  bool condition, PrintFunc printFunc, const char* conditionStr, const std::string& message,
243  const char* file, int line)
244 {
245  if (!condition)
246  assertionFailed(printFunc, conditionStr, message, file, line);
247  return condition;
248 }
249 
250 #define NX_KIT_DEBUG_DETAIL_CONCAT(X, Y) NX_KIT_DEBUG_DETAIL_CONCAT2(X, Y)
251 #define NX_KIT_DEBUG_DETAIL_CONCAT2(X, Y) X##Y
252 
254 NX_KIT_API std::string printPrefix(const char* file);
255 
256 class NX_KIT_API Timer
257 {
258 public:
259  Timer(bool enabled, PrintFunc printFunc, const char* tag);
260  ~Timer();
261  void mark(const char* markStr);
262  void finish();
263 
264 private:
265  struct Impl;
266  Impl* const d;
267 };
268 
269 class NX_KIT_API Fps
270 {
271 public:
272  Fps(PrintFunc printFunc, const char* tag);
273  ~Fps();
274  void mark(const char* markStr = nullptr);
275 
276 private:
277  struct Impl;
278  Impl* const d;
279 };
280 
281 NX_KIT_API void printHexDump(
282  PrintFunc printFunc, const char* caption, const char* bytes, int size);
283 
284 } // namespace detail
285 
286 } // namespace debug
287 } // namespace kit
288 } // namespace nx
289 
290 #if defined(__linux__)
291  #include <pthread.h>
292  #define NX_KIT_DEBUG_DETAIL_THREAD_ID() \
293  ::nx::kit::utils::format(", thread %llx", (long long) pthread_self())
294 #elif defined(QT_CORE_LIB)
295  #include <QtCore/QThread>
296  #define NX_KIT_DEBUG_DETAIL_THREAD_ID() \
297  ::nx::kit::utils::format(", thread %llx", (long long) QThread::currentThreadId())
298 #else
299  // No threading libs available - do not print thread id.
300  #define NX_KIT_DEBUG_DETAIL_THREAD_ID() ""
301 #endif
Definition: debug.h:269
Definition: debug.cpp:285
Definition: debug.cpp:210
Definition: debug.cpp:12
Definition: debug.h:256