7 #ifndef PXR_BASE_TF_DEBUG_H
8 #define PXR_BASE_TF_DEBUG_H
31 class Tf_DebugSymbolRegistry;
123 enum _NodeState { _NodeUninitialized, _NodeDisabled, _NodeEnabled };
135 _SetNode(_GetNode(val), Tf_DebugGetEnumName(val),
true);
141 _SetNode(_GetNode(val), Tf_DebugGetEnumName(val),
false);
153 for (
int i = 0; i !=
n; ++i) {
154 T code =
static_cast<T>(i);
155 _SetNode(_GetNode(code), Tf_DebugGetEnumName(code),
true);
163 for (
int i = 0; i !=
n; ++i) {
164 T code =
static_cast<T>(i);
165 _SetNode(_GetNode(code), Tf_DebugGetEnumName(code),
false);
178 "Must declare debug codes with TF_DEBUG_CODES()");
180 _Node &node = _GetNode(val);
181 _NodeState curState = node.
state.load();
183 _InitializeNode(_GetNode(val), Tf_DebugGetEnumName(val));
184 curState = node.
state.load();
186 return curState == _NodeEnabled;
196 "Must declare debug codes with TF_DEBUG_CODES()");
206 "Must declare debug codes with TF_DEBUG_CODES()");
210 #if !defined(doxygen)
213 template <
class Enum>
214 explicit _Helper(Enum
val) : _enumName(Tf_DebugGetEnumName(val)) {}
215 TF_API void Msg(
const std::string& msg)
const;
216 TF_API void Msg(
const char* msg, ...) const ARCH_PRINTF_FUNCTION(2,3);
218 char const * const _enumName = "<< no
debug code >>";
222 template <
class A1,
class ...Args>
223 static void Msg(
char const *fmt, A1 &&a1, Args && ...
args) {
225 fmt, std::forward<A1>(a1), std::forward<Args>(
args)...);
227 static void Msg(
const std::string &msg) {
238 TfDebug::_ScopedOutput(
true, str);
246 TfDebug::_ScopedOutput(
false, str);
256 ARCH_PRINTF_FUNCTION(3, 4);
312 T enumVal,
char const *
name,
char const *descrip) {
314 "Must declare debug codes with TF_DEBUG_CODES()");
315 const int index =
static_cast<int>(enumVal);
318 _ComplainAboutInvalidSymbol(name);
326 char const *descrip);
334 static constexpr
bool IsDeclared =
false;
340 mutable std::atomic<_NodeState>
state;
352 return _Data<T>::nodes[
static_cast<int>(
val)];
358 static void _InitializeNode(
_Node &node,
char const *
name);
361 static void _ComplainAboutInvalidSymbol(
char const *
name);
367 static void _ScopedOutput(
bool start,
char const *str);
376 ARCH_PRINTF_FUNCTION(3, 4) {
392 #define TF_DEBUG_CODES(...) \
393 TF_CONDITIONALLY_COMPILE_TIME_ENABLED_DEBUG_CODES(true, __VA_ARGS__)
413 #define TF_CONDITIONALLY_COMPILE_TIME_ENABLED_DEBUG_CODES(condition, ...) \
414 enum _TF_DEBUG_ENUM_NAME(__VA_ARGS__) { \
416 TF_PP_CAT( _TF_DEBUG_ENUM_NAME(__VA_ARGS__), __PAST_END) \
419 struct TfDebug::_Traits<_TF_DEBUG_ENUM_NAME(__VA_ARGS__)> { \
420 static constexpr bool IsDeclared = true; \
421 static constexpr int NumCodes = \
422 TF_PP_CAT(_TF_DEBUG_ENUM_NAME(__VA_ARGS__), __PAST_END); \
423 static constexpr bool CompileTimeEnabled = (condition); \
425 inline char const * \
426 Tf_DebugGetEnumName(_TF_DEBUG_ENUM_NAME(__VA_ARGS__) val) { \
427 constexpr char const *CStrings[] = { \
428 TF_PP_FOR_EACH(_TF_DEBUG_MAKE_STRING, __VA_ARGS__) \
430 return CStrings[static_cast<int>(val)]; \
433 #define _TF_DEBUG_MAKE_STRING(x) #x,
438 #define _TF_DEBUG_ENUM_NAME(...) \
439 TF_PP_CAT(_TF_DEBUG_FIRST_CODE(__VA_ARGS__, dummy), __DebugCodes)
441 #define _TF_DEBUG_FIRST_CODE(first, ...) first
465 #define TF_DEBUG_MSG(enumVal, ...) \
466 if (!TfDebug::IsEnabled(enumVal)) ; \
467 else TfDebug::_Helper(enumVal).Msg(__VA_ARGS__)
501 #define TF_DEBUG(enumVal) \
502 if (!TfDebug::IsEnabled(enumVal)) ; \
503 else TfDebug::_Helper(enumVal)
512 #define TF_INFO(x) TF_DEBUG(x)
541 #define TF_DEBUG_TIMED_SCOPE(enumVal, ...) \
542 TfDebug::TimedScopeHelper< \
544 std::decay<decltype(enumVal)>::type>::CompileTimeEnabled> \
545 TF_PP_CAT(local__TfScopeDebugSwObject, __LINE__)( \
546 TfDebug::IsEnabled(enumVal), __VA_ARGS__)
566 #define TF_DEBUG_ENVIRONMENT_SYMBOL(VAL, descrip) \
567 if (TfDebug::_Traits< \
568 std::decay<decltype(VAL)>::type>::CompileTimeEnabled) { \
569 TF_ADD_ENUM_NAME(VAL); \
570 TfDebug::_RegisterDebugSymbol(VAL, #VAL, descrip); \
static TF_API void SetOutputFile(FILE *file)
static size_t GetNumDebugCodes()
static TF_API std::vector< std::string > SetDebugSymbolsByName(const std::string &pattern, bool value)
static void Msg(char const *fmt, A1 &&a1, Args &&...args)
static TF_API std::string GetDebugSymbolDescription(const std::string &name)
#define PXR_NAMESPACE_OPEN_SCOPE
GLsizei const GLfloat * value
static void Disable(T val)
Mark debugging as disabled for enum value val.
GLenum GLenum GLsizei const GLuint GLboolean enabled
static TF_API std::string GetDebugSymbolDescriptions()
static void Enable(T val)
friend class Tf_DebugSymbolRegistry
static void _RegisterDebugSymbol(T enumVal, char const *name, char const *descrip)
static TF_API void _RegisterDebugSymbolImpl(_Node *addr, char const *enumName, char const *descrip)
GLuint const GLchar * name
static bool IsEnabled(T val)
that also have some descendant prim *whose name begins with which in turn has a child named baz where *the predicate active
static bool IsCompileTimeEnabled()
#define PXR_NAMESPACE_CLOSE_SCOPE
static TF_API bool IsDebugSymbolNameEnabled(const std::string &name)
True if the specified debug symbol is set.
**If you just want to fire and args
static void Msg(const std::string &msg)
TF_API void Msg(const std::string &msg) const
TimedScopeHelper(bool enabled, const char *fmt,...) ARCH_PRINTF_FUNCTION(3
ScopeHelper(bool enabled, const char *name)
static void DisableAll()
Mark debugging as disabled for all enum values of type T.
std::atomic< _NodeState > state
static TF_API std::vector< std::string > GetDebugSymbolNames()
Get a listing of all debug symbols.