-
Notifications
You must be signed in to change notification settings - Fork 0
/
MaxLib.h
159 lines (133 loc) · 5 KB
/
MaxLib.h
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
159
#pragma once
/*
* Name:
* MaxLib
* Description:
* A Set of Utility functions (written on the Raspberry Pi 3b / 4)
*/
#include "MaxLib/ads1115.h"
#include "MaxLib/File.h"
#include "MaxLib/Geom.h"
#include "MaxLib/Vector.h"
#include "MaxLib/String.h"
namespace MaxLib {
// Normalises seconds into hours, minutes & seconds
class Time {
public:
Time(uint hours, uint minutes, uint seconds) : m_hr(hours), m_min(minutes), m_sec(seconds) {}
Time(uint seconds) {
m_hr = seconds / 3600;
seconds %= 3600;
m_min = seconds / 60;
seconds %= 60;
m_sec = seconds;
}
uint Hours() { return m_hr; }
uint Mins() { return m_min; }
uint Secs() { return m_sec; }
std::string TimeString() { return MaxLib::String::va_str("%u:%.2u:%.2u", m_hr, m_min, m_sec); }
private:
uint m_hr;
uint m_min;
uint m_sec;
};
class Log {
public:
enum LogLevel {
LevelInfo,
LevelWarning,
LevelError,
LevelCritical,
LevelDebug
};
static std::string LevelPrefix(LogLevel level) {
if (level == LevelInfo)
return "[Info] ";
else if (level == LevelWarning)
return "[Warning] ";
else if (level == LevelError)
return "[Error] ";
else if (level == LevelCritical)
return "[Critical] ";
else if (level == LevelDebug)
return "[Debug] ";
return "";
}
static void SetLevel(LogLevel level) {
// lock the mutex
std::lock_guard<std::mutex> guard(get().m_mutex);
get().m_logLevelTerminal = level;
}
static int NextDebugBit() {
return (0x1 << get().m_DebugBit++);
}
// set bit flags for use with debugging
static void SetDebugFlags(int flags) {
// lock the mutex
std::lock_guard<std::mutex> guard(get().m_mutex);
get().m_DebugFlags = flags;
}
// returns unique id of handler
static void RegisterHandler(const std::function<void(const char*, LogLevel, const std::string&)>& eventHandler) {
std::lock_guard<std::mutex> guard(get().m_mutex);
get().m_PrintHandler = eventHandler;
}
static void Debug(int flag, const std::string &msg) { get().Print(flag, LevelDebug, msg.c_str()); }
static void Critical(const std::string &msg) { get().Print(LevelCritical, msg.c_str()); }
static void Error(const std::string &msg) { get().Print(LevelError, msg.c_str()); }
static void Warning(const std::string &msg) { get().Print(LevelWarning, msg.c_str()); }
static void Info(const std::string &msg) { get().Print(LevelInfo, msg.c_str()); }
template <typename... Args>
static void Debug(int flag, const char *msg, Args... args) { get().Print(flag, LevelDebug, msg, args...); }
template <typename... Args>
static void Critical(const char *msg, Args... args) { get().Print(LevelCritical, msg, args...); }
template <typename... Args>
static void Error(const char *msg, Args... args) { get().Print(LevelError, msg, args...); }
template <typename... Args>
static void Warning(const char *msg, Args... args) { get().Print(LevelWarning, msg, args...); }
template <typename... Args>
static void Info(const char *msg, Args... args) { get().Print(LevelInfo, msg, args...); }
private:
LogLevel m_logLevelTerminal = LevelInfo; // default show all
int m_DebugBit = 0;
int m_DebugFlags = 0; // default show none
std::mutex m_mutex;
// user settable print handler
std::function<void(const char*, LogLevel, const std::string&)> m_PrintHandler;
template <typename... Args>
void Print(int debugFlag, LogLevel level, const char *msg, Args... args) {
if (!PrintDebug(debugFlag))
return;
Print(level, msg, args...);
}
template <typename... Args>
void Print(LogLevel level, const char *msg, Args... args) {
// lock the mutex
std::lock_guard<std::mutex> guard(m_mutex);
// Make date string
char date[32];
time_t t = time(NULL);
strftime(date, 32, "[%H:%M:%S]", localtime(&t));
// Make message string
std::string message = MaxLib::String::va_str(msg, args...);
// Print to terminal
if(m_logLevelTerminal <= level) { printf("%s%s%s\n", date, LevelPrefix(level).c_str(), message.c_str()); }
// print to handler
if(m_PrintHandler) { m_PrintHandler(date, level, message); }
// stop program execution
if (level == LevelCritical)
exit(1);
}
bool PrintDebug(int flag) {
std::lock_guard<std::mutex> guard(m_mutex);
return m_DebugFlags & flag;
}
static Log &get() {
static Log log;
return log;
}
Log() {} // delete the constructor
Log(const Log &) = delete; // delete the copy constructor
Log &operator=(const Log &) = delete; // delete the copy assignment operatory
};
} // end namespace MaxLib