Icarus
Vehicle Simulation as a Transformable Computational Graph, built on Vulcan and Janus
Loading...
Searching...
No Matches
Console.hpp
Go to the documentation of this file.
1#pragma once
2
10
11#include <cstdio>
12#include <iomanip>
13#include <iostream>
14#include <sstream>
15#include <string>
16#include <string_view>
17
18#ifdef _WIN32
19#include <io.h>
20#define isatty _isatty
21#define STDOUT_FILENO 1
22#else
23#include <unistd.h>
24#endif
25
26namespace icarus {
27
28// =============================================================================
29// LogLevel
30// =============================================================================
31
44
45// =============================================================================
46// AnsiColor
47// =============================================================================
48
52struct AnsiColor {
53 static constexpr const char *Reset = "\033[0m";
54 static constexpr const char *Bold = "\033[1m";
55 static constexpr const char *Dim = "\033[2m";
56
57 // Foreground colors
58 static constexpr const char *Red = "\033[31m";
59 static constexpr const char *Green = "\033[32m";
60 static constexpr const char *Yellow = "\033[33m";
61 static constexpr const char *Blue = "\033[34m";
62 static constexpr const char *Magenta = "\033[35m";
63 static constexpr const char *Cyan = "\033[36m";
64 static constexpr const char *White = "\033[37m";
65 static constexpr const char *Gray = "\033[90m";
66
67 // Background colors
68 static constexpr const char *BgRed = "\033[41m";
69 static constexpr const char *BgGreen = "\033[42m";
70};
71
72// =============================================================================
73// BoxChars
74// =============================================================================
75
79struct BoxChars {
80 // Single-line box drawing
81 static constexpr const char *TopLeft = "\u250C"; // ┌
82 static constexpr const char *TopRight = "\u2510"; // ┐
83 static constexpr const char *BottomLeft = "\u2514"; // └
84 static constexpr const char *BottomRight = "\u2518"; // ┘
85 static constexpr const char *Horizontal = "\u2500"; // ─
86 static constexpr const char *Vertical = "\u2502"; // │
87 static constexpr const char *TeeRight = "\u251C"; // ├
88 static constexpr const char *TeeLeft = "\u2524"; // ┤
89 static constexpr const char *TeeDown = "\u252C"; // ┬
90 static constexpr const char *TeeUp = "\u2534"; // ┴
91 static constexpr const char *Cross = "\u253C"; // ┼
92
93 // Tree characters
94 static constexpr const char *TreeBranch = "\u251C"; // ├
95 static constexpr const char *TreeLast = "\u2514"; // └
96 static constexpr const char *TreePipe = "\u2502"; // │
97
98 // Heavy line (for headers)
99 static constexpr const char *HeavyHoriz = "\u2550"; // ═
100};
101
102// =============================================================================
103// Console
104// =============================================================================
105
111class Console {
112 public:
113 Console() : is_tty_(isatty(STDOUT_FILENO) != 0), color_enabled_(is_tty_) {}
114
116 [[nodiscard]] bool IsTerminal() const { return is_tty_; }
117
119 void SetColorEnabled(bool enabled) { color_enabled_ = enabled; }
120 [[nodiscard]] bool IsColorEnabled() const { return color_enabled_; }
121
123 void SetLogLevel(LogLevel level) { min_level_ = level; }
124 [[nodiscard]] LogLevel GetLogLevel() const { return min_level_; }
125
126 // === Logging Methods ===
127
128 void Trace(std::string_view msg) { Log(LogLevel::Trace, msg); }
129 void Debug(std::string_view msg) { Log(LogLevel::Debug, msg); }
130 void Info(std::string_view msg) { Log(LogLevel::Info, msg); }
131 void Event(std::string_view msg) { Log(LogLevel::Event, msg); }
132 void Warning(std::string_view msg) { Log(LogLevel::Warning, msg); }
133 void Error(std::string_view msg) { Log(LogLevel::Error, msg); }
134 void Fatal(std::string_view msg) { Log(LogLevel::Fatal, msg); }
135
137 void Log(LogLevel level, std::string_view msg) {
138 if (level < min_level_) {
139 return;
140 }
141
142 std::string output;
143 if (color_enabled_) {
144 output = std::string(GetLevelColor(level)) + std::string(GetLevelPrefix(level)) +
145 std::string(AnsiColor::Reset) + " " + std::string(msg);
146 } else {
147 output = std::string(GetLevelPrefix(level)) + " " + std::string(msg);
148 }
149
150 std::cout << output << "\n";
151 }
152
154 void LogTimed(LogLevel level, double sim_time, std::string_view msg) {
155 if (level < min_level_) {
156 return;
157 }
158
159 std::ostringstream oss;
160 oss << "[" << std::fixed << std::setprecision(3) << sim_time << "] ";
161
162 std::string output;
163 if (color_enabled_) {
164 output = oss.str() + std::string(GetLevelColor(level)) +
165 std::string(GetLevelPrefix(level)) + std::string(AnsiColor::Reset) + " " +
166 std::string(msg);
167 } else {
168 output = oss.str() + std::string(GetLevelPrefix(level)) + " " + std::string(msg);
169 }
170
171 std::cout << output << "\n";
172 }
173
174 // === Formatting Helpers ===
175
177 [[nodiscard]] std::string Colorize(std::string_view text, const char *color) const {
178 if (!color_enabled_) {
179 return std::string(text);
180 }
181 return std::string(color) + std::string(text) + AnsiColor::Reset;
182 }
183
185 [[nodiscard]] std::string HorizontalRule(int width = 80, char c = '-') const {
186 return std::string(static_cast<std::size_t>(width), c);
187 }
188
190 [[nodiscard]] std::string BoxHorizontalRule(int width = 80) const {
191 std::string result;
192 result.reserve(static_cast<std::size_t>(width) * 3); // UTF-8 can be 3 bytes per char
193 for (int i = 0; i < width; ++i) {
194 result += BoxChars::Horizontal;
195 }
196 return result;
197 }
198
200 [[nodiscard]] static std::string PadRight(std::string_view text, std::size_t width) {
201 if (text.size() >= width) {
202 return std::string(text);
203 }
204 return std::string(text) + std::string(width - text.size(), ' ');
205 }
206
208 [[nodiscard]] static std::string PadLeft(std::string_view text, std::size_t width) {
209 if (text.size() >= width) {
210 return std::string(text);
211 }
212 return std::string(width - text.size(), ' ') + std::string(text);
213 }
214
216 [[nodiscard]] static std::string PadCenter(std::string_view text, std::size_t width) {
217 if (text.size() >= width) {
218 return std::string(text);
219 }
220 std::size_t padding = width - text.size();
221 std::size_t left_pad = padding / 2;
222 std::size_t right_pad = padding - left_pad;
223 return std::string(left_pad, ' ') + std::string(text) + std::string(right_pad, ' ');
224 }
225
227 [[nodiscard]] static std::string FormatNumber(double value, int precision = 2) {
228 std::ostringstream oss;
229 oss << std::fixed << std::setprecision(precision) << value;
230 return oss.str();
231 }
232
234 void Write(std::string_view text) const { std::cout << text; }
235
237 void WriteLine(std::string_view text = "") const { std::cout << text << "\n"; }
238
240 void Flush() const { std::cout.flush(); }
241
242 private:
243 bool is_tty_ = false;
244 bool color_enabled_ = false;
245 LogLevel min_level_ = LogLevel::Info;
246
247 [[nodiscard]] const char *GetLevelColor(LogLevel level) const {
248 switch (level) {
249 case LogLevel::Trace:
250 return AnsiColor::Gray;
251 case LogLevel::Debug:
252 return AnsiColor::Cyan;
253 case LogLevel::Info:
254 return AnsiColor::White;
255 case LogLevel::Event:
256 return AnsiColor::Green;
258 return AnsiColor::Yellow;
259 case LogLevel::Error:
260 return AnsiColor::Red;
261 case LogLevel::Fatal:
262 return AnsiColor::BgRed;
263 }
264 return AnsiColor::White;
265 }
266
267 [[nodiscard]] static const char *GetLevelPrefix(LogLevel level) {
268 switch (level) {
269 case LogLevel::Trace:
270 return "[TRC]";
271 case LogLevel::Debug:
272 return "[DBG]";
273 case LogLevel::Info:
274 return "[INF]";
275 case LogLevel::Event:
276 return "[EVT]";
278 return "[WRN]";
279 case LogLevel::Error:
280 return "[ERR]";
281 case LogLevel::Fatal:
282 return "[FTL]";
283 }
284 return "[???]";
285 }
286};
287
288} // namespace icarus
void Event(std::string_view msg)
Definition Console.hpp:131
void Fatal(std::string_view msg)
Definition Console.hpp:134
void WriteLine(std::string_view text="") const
Write raw string with newline.
Definition Console.hpp:237
std::string BoxHorizontalRule(int width=80) const
Create horizontal rule with box-drawing character.
Definition Console.hpp:190
static std::string FormatNumber(double value, int precision=2)
Format number with fixed precision.
Definition Console.hpp:227
void Flush() const
Flush output.
Definition Console.hpp:240
void Write(std::string_view text) const
Write raw string (no formatting).
Definition Console.hpp:234
bool IsColorEnabled() const
Definition Console.hpp:120
static std::string PadCenter(std::string_view text, std::size_t width)
Pad string to width (center-aligned).
Definition Console.hpp:216
static std::string PadLeft(std::string_view text, std::size_t width)
Pad string to width (left-aligned).
Definition Console.hpp:208
bool IsTerminal() const
Check if stdout is a terminal (supports ANSI codes).
Definition Console.hpp:116
void LogTimed(LogLevel level, double sim_time, std::string_view msg)
Log with timestamp prefix.
Definition Console.hpp:154
void Log(LogLevel level, std::string_view msg)
Log with explicit level.
Definition Console.hpp:137
void Info(std::string_view msg)
Definition Console.hpp:130
static std::string PadRight(std::string_view text, std::size_t width)
Pad string to width (right-aligned).
Definition Console.hpp:200
std::string HorizontalRule(int width=80, char c='-') const
Create horizontal rule.
Definition Console.hpp:185
std::string Colorize(std::string_view text, const char *color) const
Apply color if enabled.
Definition Console.hpp:177
void Error(std::string_view msg)
Definition Console.hpp:133
void SetColorEnabled(bool enabled)
Enable/disable color output (auto-detected by default).
Definition Console.hpp:119
void SetLogLevel(LogLevel level)
Set minimum log level for output.
Definition Console.hpp:123
void Warning(std::string_view msg)
Definition Console.hpp:132
LogLevel GetLogLevel() const
Definition Console.hpp:124
Console()
Definition Console.hpp:113
void Debug(std::string_view msg)
Definition Console.hpp:129
void Trace(std::string_view msg)
Definition Console.hpp:128
Base class for all Icarus exceptions.
Definition Error.hpp:52
Definition AggregationTypes.hpp:13
@ Warning
Proceed with caution.
Definition ValidationResult.hpp:20
@ Info
Informational note.
Definition ValidationResult.hpp:21
LogLevel
Log severity levels.
Definition Console.hpp:35
@ Warning
Potential issues.
Definition Console.hpp:40
@ Info
Normal operation.
Definition Console.hpp:38
@ Fatal
Unrecoverable errors.
Definition Console.hpp:42
@ Error
Recoverable errors.
Definition Console.hpp:41
@ Event
Simulation events (phase changes, etc.).
Definition Console.hpp:39
@ Debug
Debugging info.
Definition Console.hpp:37
@ Trace
Most verbose, internal debugging.
Definition Console.hpp:36
ANSI color codes.
Definition Console.hpp:52
static constexpr const char * BgRed
Definition Console.hpp:68
static constexpr const char * Cyan
Definition Console.hpp:63
static constexpr const char * Blue
Definition Console.hpp:61
static constexpr const char * Gray
Definition Console.hpp:65
static constexpr const char * Red
Definition Console.hpp:58
static constexpr const char * Reset
Definition Console.hpp:53
static constexpr const char * Dim
Definition Console.hpp:55
static constexpr const char * BgGreen
Definition Console.hpp:69
static constexpr const char * White
Definition Console.hpp:64
static constexpr const char * Green
Definition Console.hpp:59
static constexpr const char * Yellow
Definition Console.hpp:60
static constexpr const char * Magenta
Definition Console.hpp:62
static constexpr const char * Bold
Definition Console.hpp:54
Box-drawing characters (Unicode).
Definition Console.hpp:79
static constexpr const char * TeeRight
Definition Console.hpp:87
static constexpr const char * TreePipe
Definition Console.hpp:96
static constexpr const char * TeeLeft
Definition Console.hpp:88
static constexpr const char * TeeUp
Definition Console.hpp:90
static constexpr const char * TeeDown
Definition Console.hpp:89
static constexpr const char * TopLeft
Definition Console.hpp:81
static constexpr const char * HeavyHoriz
Definition Console.hpp:99
static constexpr const char * BottomLeft
Definition Console.hpp:83
static constexpr const char * TreeBranch
Definition Console.hpp:94
static constexpr const char * Horizontal
Definition Console.hpp:85
static constexpr const char * TreeLast
Definition Console.hpp:95
static constexpr const char * BottomRight
Definition Console.hpp:84
static constexpr const char * Vertical
Definition Console.hpp:86
static constexpr const char * TopRight
Definition Console.hpp:82
static constexpr const char * Cross
Definition Console.hpp:91