feat(log): printStatus amb claudàtor acolorit al davant

This commit is contained in:
JailDesigner committed 2026-05-14 19:02:43 +02:00
1 parent 7a1261202c
commit b81a453b32
7 files changed
+112 -19

No files matched your search

+1 -1
View File
@@ -62,7 +62,7 @@ Surface::Surface(const std::string& file_path) {
palette_[i] = Rendering::OPAQUE_ALPHA | rgb[i]; palette_[i] = Rendering::OPAQUE_ALPHA | rgb[i];
} }
printWithDots("Surface", getFileName(file_path), "[ LOADED ]"); printStatus("Surface", getFileName(file_path), StatusKind::SUCCESS);
} }
void Surface::clear(Uint8 color) { void Surface::clear(Uint8 color) {
+1 -1
View File
@@ -101,7 +101,7 @@ auto Text::loadTextFile(const std::string& file_path) -> std::shared_ptr<File> {
} }
} }
printWithDots("Text File", getFileName(file_path), "[ LOADED ]"); printStatus("Text File", getFileName(file_path), StatusKind::SUCCESS);
return tf; return tf;
} }
+4 -4
View File
@@ -37,13 +37,13 @@ namespace Resource {
throw std::runtime_error("Cache: cannot load animation " + file_path); throw std::runtime_error("Cache: cannot load animation " + file_path);
} }
animations_.emplace_back(AnimationResource{.name = name, .yaml_data = std::move(bytes)}); animations_.emplace_back(AnimationResource{.name = name, .yaml_data = std::move(bytes)});
printWithDots("Animation", getFileName(file_path), "[ LOADED ]"); printStatus("Animation", getFileName(file_path), StatusKind::SUCCESS);
} }
void Cache::loadPalette(const std::string& name, const std::string& file_path) { void Cache::loadPalette(const std::string& name, const std::string& file_path) {
auto palette = PaletteLoader::loadFromFile(file_path); auto palette = PaletteLoader::loadFromFile(file_path);
palettes_.emplace_back(PaletteResource{.name = name, .palette = palette}); palettes_.emplace_back(PaletteResource{.name = name, .palette = palette});
printWithDots("Palette", getFileName(file_path), "[ LOADED ]"); printStatus("Palette", getFileName(file_path), StatusKind::SUCCESS);
} }
auto Cache::getSurface(const std::string& name) -> std::shared_ptr<Surface> { auto Cache::getSurface(const std::string& name) -> std::shared_ptr<Surface> {
@@ -83,7 +83,7 @@ namespace Resource {
throw std::runtime_error("Cache: Ja::loadMusic failed for " + file_path); throw std::runtime_error("Cache: Ja::loadMusic failed for " + file_path);
} }
musics_.emplace_back(MusicResource{.name = name, .music = std::unique_ptr<Ja::Music, MusicDeleter>(raw)}); musics_.emplace_back(MusicResource{.name = name, .music = std::unique_ptr<Ja::Music, MusicDeleter>(raw)});
printWithDots("Music", getFileName(file_path), "[ LOADED ]"); printStatus("Music", getFileName(file_path), StatusKind::SUCCESS);
} }
void Cache::loadSound(const std::string& name, const std::string& file_path) { void Cache::loadSound(const std::string& name, const std::string& file_path) {
@@ -96,7 +96,7 @@ namespace Resource {
throw std::runtime_error("Cache: Ja::loadSound failed for " + file_path); throw std::runtime_error("Cache: Ja::loadSound failed for " + file_path);
} }
sounds_.emplace_back(SoundResource{.name = name, .sound = std::unique_ptr<Ja::Sound, SoundDeleter>(raw)}); sounds_.emplace_back(SoundResource{.name = name, .sound = std::unique_ptr<Ja::Sound, SoundDeleter>(raw)});
printWithDots("Sound", getFileName(file_path), "[ LOADED ]"); printStatus("Sound", getFileName(file_path), StatusKind::SUCCESS);
} }
auto Cache::getMusic(const std::string& name) -> Ja::Music* { auto Cache::getMusic(const std::string& name) -> Ja::Music* {
+5
View File
@@ -130,6 +130,11 @@ namespace Log {
SDL_LogMessage(categoryFor(tag), toSDL(lvl), "%s", BODY.c_str()); SDL_LogMessage(categoryFor(tag), toSDL(lvl), "%s", BODY.c_str());
} }
void logPrefixed(Level lvl, std::string_view tag, std::string_view prefix, std::string_view msg) {
const std::string BODY = std::format("{} {}: {}", prefix, tag, msg);
SDL_LogMessage(categoryFor(tag), toSDL(lvl), "%s", BODY.c_str());
}
void raw(Level lvl, std::string_view msg) { void raw(Level lvl, std::string_view msg) {
const std::string TEXT{msg}; const std::string TEXT{msg};
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, toSDL(lvl), "%s", TEXT.c_str()); SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, toSDL(lvl), "%s", TEXT.c_str());
+6
View File
@@ -32,6 +32,12 @@ namespace Log {
// entrega a SDL_LogMessage amb la categoria registrada per al tag. // entrega a SDL_LogMessage amb la categoria registrada per al tag.
void log(Level lvl, std::string_view tag, std::string_view msg); void log(Level lvl, std::string_view tag, std::string_view msg);
// Com `log`, però antepossa un prefix arbitrari abans del tag, donant
// "prefix tag: msg". Pensat per a marcadors d'estat (p. ex. claudàtors
// de càrrega "[ LOADED ]"). El routing per categoria/filtre via AEE_LOG
// continua actiu (es decideix pel `tag`, no pel prefix).
void logPrefixed(Level lvl, std::string_view tag, std::string_view prefix, std::string_view msg);
// Variant sense prefix de tag — ús reservat per a marcadors literals // Variant sense prefix de tag — ús reservat per a marcadors literals
// (p. ex. "Game start" / "Bye!"). Cau a SDL_LOG_CATEGORY_APPLICATION, // (p. ex. "Game start" / "Bye!"). Cau a SDL_LOG_CATEGORY_APPLICATION,
// així AEE_LOG global encara els pot silenciar. // així AEE_LOG global encara els pot silenciar.
+80 -10
View File
@@ -1,7 +1,16 @@
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include <algorithm>
#include <cstdlib>
#include <filesystem> #include <filesystem>
#include <string> #include <string>
#include <string_view>
#ifndef _WIN32
#include <unistd.h>
#include <cstdio>
#endif
#include "utils/log.hpp" #include "utils/log.hpp"
@@ -9,14 +18,75 @@ auto getFileName(const std::string& path) -> std::string {
return std::filesystem::path(path).filename().string(); return std::filesystem::path(path).filename().string();
} }
void printWithDots(const std::string& tag, const std::string& filename, const std::string& status) { namespace {
// Reprodueix l'alineació històrica (amplada total ≈ 50). El logger anteposa
// automàticament "tag: ", per això aquí només componem el cos. constexpr std::size_t BRACKET_INNER_WIDTH = 8;
constexpr std::size_t TOTAL_WIDTH = 50;
const std::size_t PREFIX_LEN = tag.size() + 2; // "{tag}: " auto defaultLabel(StatusKind kind) -> std::string_view {
const std::size_t USED = PREFIX_LEN + status.size(); switch (kind) {
const std::size_t FIELD = (USED < TOTAL_WIDTH) ? (TOTAL_WIDTH - USED) : 0; case StatusKind::SUCCESS:
std::string body = filename; return "LOADED";
if (body.size() < FIELD) { body.resize(FIELD, '.'); } case StatusKind::INFO:
Log::info(tag, "{}{}", body, status); return "INFO";
case StatusKind::ERROR:
return "ERROR";
}
return {};
}
auto colorCode(StatusKind kind) -> std::string_view {
switch (kind) {
case StatusKind::SUCCESS:
return "\033[1;32m";
case StatusKind::INFO:
return "\033[1;34m";
case StatusKind::ERROR:
return "\033[1;31m";
}
return {};
}
// Decideix una sola vegada per execució: stderr ha d'admetre ANSI?
// A Windows només Git Bash (MSYSTEM) el suporta sense habilitar VT.
auto useColor() -> bool {
static const bool ENABLED = [] {
#ifdef _WIN32
return std::getenv("MSYSTEM") != nullptr;
#else
return isatty(fileno(stderr)) != 0;
#endif
}();
return ENABLED;
}
// Construeix "[ <padded label> ]" amb el contingut interior centrat dins
// d'una amplada mínima de BRACKET_INNER_WIDTH. Si `with_color` és true,
// només l'interior porta codis ANSI; els claudàtors queden sense color
// (mateix patró que `mini`: `[<color>...<reset>]`).
auto buildBracket(std::string_view label, StatusKind kind, bool with_color) -> std::string {
const std::size_t INNER = std::max(BRACKET_INNER_WIDTH, label.size());
const std::size_t PAD = INNER - label.size();
const std::size_t LEFT = PAD / 2;
const std::size_t RIGHT = PAD - LEFT;
std::string out;
out.push_back('[');
if (with_color) { out.append(colorCode(kind)); }
out.append(LEFT, ' ');
out.append(label);
out.append(RIGHT, ' ');
if (with_color) { out.append("\033[0m"); }
out.push_back(']');
return out;
}
} // namespace
void printStatus(const std::string& tag,
const std::string& filename,
StatusKind kind,
std::string_view label) {
const std::string_view EFFECTIVE_LABEL = label.empty() ? defaultLabel(kind) : label;
const std::string BRACKET = buildBracket(EFFECTIVE_LABEL, kind, useColor());
const Log::Level LVL = (kind == StatusKind::ERROR) ? Log::Level::ERROR : Log::Level::INFO;
Log::logPrefixed(LVL, tag, BRACKET, filename);
} }
+15 -3
View File
@@ -1,8 +1,20 @@
#pragma once #pragma once
#include <string> #include <string>
#include <string_view>
enum class StatusKind : unsigned char { SUCCESS,
INFO,
ERROR };
auto getFileName(const std::string& path) -> std::string; auto getFileName(const std::string& path) -> std::string;
// Línia de càrrega amb alineació de punts: "{tag}: filename..........{status}".
// Embolcalla `Log::info`, amb la qual cosa respecta `AEE_LOG`. // Línia d'estat amb claudàtor centrat al davant: "{tag}: [ LABEL ] filename".
void printWithDots(const std::string& tag, const std::string& filename, const std::string& status); // Amplada interna del claudàtor fixa a 8; si la `label` supera 8 chars,
// el claudàtor s'allarga per encabir-la. Color del claudàtor (verd/blau/roig)
// quan stderr és un terminal; a Windows només sota Git Bash (MSYSTEM).
// Embolcalla `Log::info`/`Log::error` segons `kind`, respectant `AEE_LOG`.
void printStatus(const std::string& tag,
const std::string& filename,
StatusKind kind,
std::string_view label = {});