-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDebug.hpp
158 lines (127 loc) · 4.51 KB
/
Debug.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#pragma once
#include <fstream>
#include <chrono>
#include <string>
#ifdef PROFILING
#include "papi.h"
#endif
/////////////////////// Error handling and logging ////////////////////
/////////////////////// and Drawing debug shapes //////////////////////
class Debug {
static constexpr const char* LOG_FILE_NAME = "log.txt";
static FILE* log;
struct DebugCircle {
Color color;
Vec2 position;
float radius;
};
struct DebugRect {
Color color;
Vec2 min, max;
};
static RenderInfo circleRenderInfo;
static RenderInfo rectRenderInfo;
static std::vector< DebugCircle > circleBufferData;
static std::vector< DebugRect > rectBufferData;
public:
static constexpr Color RED = { 1, 0, 0, 1 };
static constexpr Color GREEN = { 0, 1, 0, 1 };
static constexpr Color BLUE = { 0, 0, 1, 1 };
static constexpr Color WHITE = { 1, 1, 1, 1 };
static constexpr Color BLACK = { 0, 0, 0, 1 };
// write messages
static void initializeLogger();
static void shutdownLogger();
static void shutdown();
static void write( const char* format, ... );
static void write( const char* format, va_list args );
static void writeError( const char* format, ... );
static void writeError( const char* format, va_list args );
static void haltWithMessage( const char* failedCond, const char* file, const char* function, s32 line, ... );
// draw basic shapes
static void initializeRenderer();
static void drawCircle( Circle circle, Color color );
static void drawRect( Rect rect, Color color );
#ifdef DOD
static void drawShape( Shape shape, Color color );
#elif defined OOP
static void drawShape( Shape* shape, Color color );
#endif
static void renderAndClear();
static void setOrthoProjection( float aspectRatio, float height );
};
#ifdef __GNUC__
#define __FUNC__ __PRETTY_FUNCTION__
#else
#define __FUNC__ __func__
#endif
#ifdef NDEBUG
#define ASSERT( condition, ... ) ( ( void )0 )
#else
#define ASSERT( condition, ... ) { \
if ( !( condition ) ) { \
Debug::haltWithMessage( #condition, __FILE__, __FUNC__, __LINE__, __VA_ARGS__ ); \
} \
}
#endif
// based on chapter 9.8 'In-Game Profiling' of the book 'Game Engine Architecture' by Jason Gregory, second edition
typedef std::chrono::time_point< std::chrono::high_resolution_clock > TimePoint;
typedef std::chrono::high_resolution_clock Clock;
struct AutoProfile {
AutoProfile( const char* name );
~AutoProfile();
};
class Profiler {
#ifdef DOD
static constexpr const char* PROFILER_LOG_FILE_NAME = "DODprofilerLog.csv";
#elif defined OOP
static constexpr const char* PROFILER_LOG_FILE_NAME = "OOPprofilerLog.csv";
#endif
static FILE* profilerLog;
static u32 frameNumber;
static constexpr const u8 NUM_PERF_COUNTERS = 3;
static const s32 PERF_COUNTER_CODES[ NUM_PERF_COUNTERS ];
static const char* PERF_COUNTER_NAMES[ NUM_PERF_COUNTERS ];
static s32 perfCounters;
struct ProfileSample {
long long startPerfCounts[ NUM_PERF_COUNTERS ];
long long deltaPerfCounts[ NUM_PERF_COUNTERS ];
TimePoint startTime;
u64 elapsedNanos;
u32 callCount;
u32 recursionCount;
};
static std::vector< ProfileSample > samples;
// SampleNodeIndex & ProfileSampleIndex value 0 is reserved to mean null,
// so these indices must start from 1
// TODO standarize indices starting at 1
typedef u32 ProfileSampleIndex;
typedef u32 SampleNodeIndex;
struct SampleNode {
SampleNodeIndex parent;
SampleNodeIndex firstChild;
SampleNodeIndex nextSibling;
const char* name;
ProfileSampleIndex dataInd;
};
static std::vector< SampleNode > sampleTree;
static SampleNodeIndex currentNodeInd;
static SampleNodeIndex addChildSampleNode( SampleNodeIndex nodeInd, const char* name );
static SampleNodeIndex getParentSampleNode( const SampleNodeIndex nodeInd );
static SampleNodeIndex getChildSampleNode( SampleNodeIndex nodeInd, const char* name );
static void callSampleNode( const SampleNodeIndex nodeInd );
static bool returnFromSampleNode( const SampleNodeIndex nodeInd );
public:
static void initialize();
static void shutdown();
static void startProfile( const char* name );
static void stopProfile();
static bool updateOutputsAndReset();
};
#ifndef PROFILING
#define PROFILE_BLOCK( name ) ( ( void )0 )
#define PROFILE ( ( void )0 )
#else
#define PROFILE_BLOCK( name ) AutoProfile p( name )
#define PROFILE PROFILE_BLOCK( __FUNC__ )
#endif