|
1
|
1 #pragma once
|
|
|
2 #include "string-lite.h"
|
|
|
3 #include <functional>
|
|
|
4
|
|
|
5 #ifdef __ANDROID__
|
|
|
6 #define PFC_SET_THREAD_DESCRIPTION_EXTERNAL
|
|
|
7 #endif
|
|
|
8
|
|
|
9 namespace pfc {
|
|
|
10 void debugBreak();
|
|
|
11 [[noreturn]] void crash();
|
|
|
12 [[noreturn]] void crashWithMessageOnStack( const char * msg );
|
|
|
13 void outputDebugLine(const char * msg);
|
|
|
14
|
|
|
15 #ifdef __APPLE__
|
|
|
16 [[noreturn]] void appleThrowException( const char * name, const char * reason );
|
|
|
17 #endif
|
|
|
18
|
|
|
19 // Debug logger service.
|
|
|
20 // It is up to the caller to ensure thread safety. You want to create debugLineReceiver instances on app startup and never destroy them.
|
|
|
21 class debugLineReceiver {
|
|
|
22 public:
|
|
|
23 debugLineReceiver();
|
|
|
24 virtual void onLine( const char *) {}
|
|
|
25
|
|
|
26
|
|
|
27 static void dispatch( const char * msg );
|
|
|
28 private:
|
|
|
29 debugLineReceiver * m_chain;
|
|
|
30
|
|
|
31 void operator=( const debugLineReceiver & ) = delete;
|
|
|
32 debugLineReceiver( const debugLineReceiver & ) = delete;
|
|
|
33 };
|
|
|
34
|
|
|
35 class debugLog : public string_formatter {
|
|
|
36 public:
|
|
|
37 ~debugLog() { outputDebugLine(this->get_ptr()); }
|
|
|
38 };
|
|
|
39 #define PFC_DEBUGLOG ::pfc::debugLog()._formatter()
|
|
|
40
|
|
|
41 void setCurrentThreadDescription( const char * );
|
|
|
42
|
|
|
43 #ifdef PFC_SET_THREAD_DESCRIPTION_EXTERNAL
|
|
|
44 void initSetCurrentThreadDescription( std::function<void (const char*)> );
|
|
|
45 #endif
|
|
|
46 }
|
|
|
47
|
|
|
48 #define PFC_SET_THREAD_DESCRIPTION(X) { ::pfc::setCurrentThreadDescription(X); }
|
|
|
49 #define PFC_SET_THREAD_DESCRIPTION_SUPPORTED
|
|
|
50
|
|
|
51 #define PFC_DEBUG_PRINT_FORCED(...) ::pfc::outputDebugLine(pfc::format(__VA_ARGS__))
|
|
|
52
|
|
|
53 #if PFC_DEBUG
|
|
|
54 #define PFC_DEBUG_PRINT(...) PFC_DEBUG_PRINT_FORCED(pfc::format(__VA_ARGS__))
|
|
|
55 #else
|
|
|
56 #define PFC_DEBUG_PRINT(...)
|
|
|
57 #endif
|