ASW Lib
A.D.S. Games SDL Wrapper Library. A library targeted at Allegro4 users who want to switch to SDL3 and use modern c++.
Loading...
Searching...
No Matches
log.cpp
Go to the documentation of this file.
1#include "./asw/modules/log.h"
2
3#include <chrono>
4
5#ifdef __EMSCRIPTEN__
6#include <emscripten.h>
7#endif
8
9namespace {
11std::ostream* output = &std::cerr;
12
14{
15 using enum asw::log::Level;
16
17 switch (level) {
18 case DEBUG:
19 return "DEBUG";
20 case INFO:
21 return "INFO ";
22 case WARN:
23 return "WARN ";
24 case ERROR:
25 return "ERROR";
26 }
27 return "?????";
28}
29
31enum class AnsiCode : int {
32 Reset = 0,
33 BoldOn = 1,
34 Faint = 2,
35 ItalicOn = 3,
36 UnderlineOn = 4,
37 SlowBlinkOn = 5,
38 RapidBlinkOn = 6,
40 ConcealOn = 8,
41 CrossedOutOn = 9,
42 BoldOff = 22,
43 ItalicOff = 23,
44 UnderlineOff = 24,
45 BlinkOff = 25,
46 ReverseVideoOff = 27,
47 ConcealOff = 28,
48 CrossedOutOff = 29,
49
50 // Standard text colors
51 TextBlack = 30,
52 TextRed = 31,
53 TextGreen = 32,
54 TextYellow = 33,
55 TextBlue = 34,
56 TextMagenta = 35,
57 TextCyan = 36,
58 TextWhite = 37,
59 TextDefault = 39,
60
61 // Background color
62 BgBlack = 40,
63 BgRed = 41,
64 BgGreen = 42,
65 BgYellow = 43,
66 BgBlue = 44,
67 BgMagenta = 45,
68 BgCyan = 46,
69 BgWhite = 47,
70 BgDefault = 49,
71
72 // Bright (high-intensity) text colors
73 TextBrightBlack = 90,
74 TextBrightRed = 91,
75 TextBrightGreen = 92,
77 TextBrightBlue = 94,
79 TextBrightCyan = 96,
80 TextBrightWhite = 97,
81};
82
83inline std::string ansi_to_string(AnsiCode code)
84{
85 return "\033[" + std::to_string(static_cast<int>(code)) + "m";
86}
87
89{
90 using enum asw::log::Level;
91
92 switch (level) {
93 case DEBUG:
95 case INFO:
97 case WARN:
99 case ERROR:
101 }
102 return AnsiCode::Reset;
103}
104
105std::string get_timestamp()
106{
107 auto now = std::chrono::system_clock::now();
108 return std::format("{:%H:%M:%S}", now);
109}
110} // namespace
111
112void asw::log::log_message(asw::log::Level level, const std::string& message)
113{
114 if (level < current_level) {
115 return;
116 }
117
118#ifdef __EMSCRIPTEN__
119 int emLevel = EM_LOG_CONSOLE;
120 switch (level) {
122 emLevel = EM_LOG_CONSOLE;
123 break;
125 emLevel = EM_LOG_CONSOLE;
126 break;
128 emLevel = EM_LOG_WARN;
129 break;
131 emLevel = EM_LOG_ERROR;
132 break;
133 }
134 emscripten_log(
135 emLevel, "[%s] [%s] %s", level_to_string(level), get_timestamp().c_str(), message.c_str());
136#else
137 const std::string reset = ansi_to_string(AnsiCode::Reset);
138 const std::string color = ansi_to_string(level_to_ansi(level));
139 const std::string bold = ansi_to_string(AnsiCode::BoldOn);
140 const std::string faint = ansi_to_string(AnsiCode::Faint);
141
142 // Dim timestamp
143 *output << faint << "[" << get_timestamp() << "]" << reset << " ";
144
145 // Bold + bright colored level badge
146 *output << bold << color << "[" << level_to_string(level) << "]" << reset << " ";
147
148 // Level-colored message
149 *output << color << message << reset << "\n";
150#endif
151}
152
154{
155 current_level = level;
156}
157
158void asw::log::set_output(std::ostream& stream)
159{
160 output = &stream;
161}
162
163void asw::log::debug(const std::string& message)
164{
165 log_message(Level::DEBUG, message);
166}
167
168void asw::log::info(const std::string& message)
169{
170 log_message(Level::INFO, message);
171}
172
173void asw::log::warn(const std::string& message)
174{
175 log_message(Level::WARN, message);
176}
177
178void asw::log::error(const std::string& message)
179{
180 log_message(Level::ERROR, message);
181}
182
183void asw::log::progress(float progress, std::string message)
184{
185 constexpr int bar_width = 20;
186 const int filled = static_cast<int>(progress * static_cast<float>(bar_width));
187
188 // Build Unicode block bar: █ filled, ░ empty
189 std::string bar;
190 bar.reserve(bar_width * 3);
191 for (int i = 0; i < bar_width; ++i) {
192 bar += (i < filled) ? "█" : "░";
193 }
194
195 const std::string progress_message
196 = std::format("[{}] {:>3}% {}", bar, static_cast<int>(progress * 100.0f), message);
197 log_message(Level::INFO, progress_message);
198}
Structured logging system.
const char * level_to_string(asw::log::Level level)
Definition log.cpp:13
AnsiCode level_to_ansi(asw::log::Level level)
Definition log.cpp:88
AnsiCode
ANSI escape codes for terminal formatting.
Definition log.cpp:31
asw::log::Level current_level
Definition log.cpp:10
std::string get_timestamp()
Definition log.cpp:105
std::ostream * output
Definition log.cpp:11
std::string ansi_to_string(AnsiCode code)
Definition log.cpp:83
void set_output(std::ostream &stream)
Set the output stream (default: std::cerr).
Definition log.cpp:158
void info(const std::string &message)
Log an info message.
Definition log.cpp:168
void debug(const std::string &message)
Log a debug message.
Definition log.cpp:163
void log_message(Level level, const std::string &message)
Log a message at the specified level. Messages below the current log level are ignored.
Definition log.cpp:112
void error(const std::string &message)
Log an error message.
Definition log.cpp:178
void warn(const std::string &message)
Log a warning message.
Definition log.cpp:173
Level
Log severity levels.
Definition log.h:19
void progress(float progress, std::string message)
Log a progress message with a percentage.
Definition log.cpp:183
void set_level(Level level)
Set the minimum log level (messages below this are ignored).
Definition log.cpp:153