Porytiles
Loading...
Searching...
No Matches
diagnostic_stencils.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <map>
5#include <ranges>
6#include <string>
7#include <utility>
8#include <vector>
9
21
22namespace porytiles {
23
24constexpr std::string_view diagnostic_separator = "--------";
25
39template <typename T>
40[[nodiscard]] std::vector<std::string> format_config_note(const TextFormatter &format, const ConfigValue<T> &config)
41{
42 std::vector<std::string> lines{};
43 lines.push_back(format.format(
44 "'{}' is '{}' due to configuration:",
45 FormatParam{config.canonical_name(), Style::bold},
46 FormatParam{config.value(), Style::bold}));
47 lines.emplace_back("");
48 lines.append_range(config.prettify(format));
49 return lines;
50}
51
65template <typename T>
66[[nodiscard]] std::vector<std::string>
68{
69 std::vector<std::string> lines{};
70 lines.emplace_back("");
71 lines.emplace_back(diagnostic_separator);
72 lines.emplace_back("");
73 lines.append_range(format_config_note(format, config));
74 return lines;
75}
76
94[[nodiscard]] inline std::vector<std::string> build_global_color_limit_lines(
95 const TextFormatter &format, std::size_t color_count_limit, const ConfigValue<std::size_t> &num_pals)
96{
97 std::vector<std::string> lines;
98 lines.push_back(format.format("Global unique color limit is '{}'.", FormatParam{color_count_limit, Style::bold}));
99 lines.emplace_back("");
100 lines.emplace_back("Color limit definition:");
101 lines.push_back(format.format(
102 "{} * {}:",
103 FormatParam{num_pals.canonical_name(), Style::bold | Style::yellow},
104 FormatParam{"nontransparent_colors_per_pal", Style::bold}));
105 lines.push_back(format.format(
106 "{} * {} = {}",
107 FormatParam{num_pals.value(), Style::bold | Style::yellow},
108 FormatParam{(pal::max_size - 1), Style::bold},
109 FormatParam{color_count_limit, Style::bold}));
110 lines.emplace_back("");
111 lines.append_range(format_config_note(format, num_pals));
112 return lines;
113}
114
131[[nodiscard]] inline std::vector<std::string> build_subtraction_limit_lines(
132 const TextFormatter &format,
133 std::string_view label,
134 std::size_t computed_limit,
135 const ConfigValue<std::size_t> &total_cfg,
136 const ConfigValue<std::size_t> &primary_cfg)
137{
138 std::vector<std::string> lines;
139 lines.push_back(
140 format.format("{} is '{}'.", FormatParam{label, Style::bold}, FormatParam{computed_limit, Style::bold}));
141 lines.emplace_back("");
142 lines.push_back(format.format("{} definition:", FormatParam{label, Style::bold}));
143 lines.push_back(format.format(
144 "{} - {}:",
145 FormatParam{total_cfg.canonical_name(), Style::bold | Style::yellow},
146 FormatParam{primary_cfg.canonical_name(), Style::bold | Style::yellow}));
147 lines.push_back(format.format(
148 "{} - {} = {}",
149 FormatParam{total_cfg.value(), Style::bold},
150 FormatParam{primary_cfg.value(), Style::bold},
151 FormatParam{computed_limit, Style::bold}));
152 lines.emplace_back("");
153 lines.append_range(format_config_note(format, total_cfg));
154 lines.append_range(format_config_note_with_separator(format, primary_cfg));
155 return lines;
156}
157
179template <std::size_t N>
180[[nodiscard]] std::vector<std::string> build_porymap_pal_highlight_lines(
181 const TextFormatter &format,
182 const PalettePrinter &pal_printer,
183 const std::string &message,
184 const Palette<Rgba32, N> &pal,
185 const std::string &pal_label,
186 const std::vector<std::size_t> &violating_slots)
187{
188 std::vector<std::string> lines;
189 lines.emplace_back(
190 format.format("Porymap palette '{}': {}:", FormatParam{pal_label, Style::bold}, FormatParam{message}));
191 lines.emplace_back();
192 lines.append_range(pal_printer.print_rgba_pal_with_highlights(pal, violating_slots));
193 return lines;
194}
195
217template <std::size_t N>
218[[nodiscard]] std::vector<std::string> build_porytiles_pal_highlight_lines(
219 const TextFormatter &format,
220 const PalettePrinter &pal_printer,
221 const std::string &message,
222 const Palette<Rgba32, N> &pal,
223 const std::string &pal_label,
224 const std::vector<std::size_t> &violating_slots)
225{
226 std::vector<std::string> lines;
227 lines.emplace_back(
228 format.format("Porytiles palette '{}': {}:", FormatParam{pal_label, Style::bold}, FormatParam{message}));
229 lines.emplace_back();
230 lines.append_range(pal_printer.print_rgba_pal_with_highlights(pal, violating_slots));
231 return lines;
232}
233
254[[nodiscard]] inline std::vector<std::string> build_pal_hint_highlight_lines(
255 const TextFormatter &format,
256 const PalettePrinter &pal_printer,
257 const std::string &message,
258 const PaletteHint &hint,
259 const std::string &pal_label,
260 const std::vector<std::size_t> &violating_slots)
261{
262 std::vector<std::string> lines;
263 lines.emplace_back(
264 format.format("palette hint '{}': {}:", FormatParam{pal_label, Style::bold}, FormatParam{message}));
265 lines.emplace_back();
266 lines.append_range(pal_printer.print_pal_hint_with_highlights(hint, violating_slots));
267 return lines;
268}
269
284[[nodiscard]] inline std::vector<std::string> build_tile_sharing_color_version_tile_lines(
285 const TextFormatter &format,
286 const TilePrinter &tile_printer,
287 const std::vector<PixelTile<Rgba32>> &pixel_tiles,
288 const Rgba32 &extrinsic_transparency,
289 const std::vector<std::size_t> &color_version_tile_indices)
290{
291 std::vector<std::string> lines;
292 for (std::size_t v = 0; v < color_version_tile_indices.size(); ++v) {
293 const auto tile_index = color_version_tile_indices.at(v);
294 auto [mt_index, layer, subtile] = metatile::from_tile_index(tile_index);
295 lines.emplace_back(format.format(
296 "Color version {} (secondary {}):",
297 FormatParam{v + 1, Style::bold},
298 FormatParam{metatile::message_header(format, mt_index, layer, subtile), Style::bold}));
299 lines.append_range(tile_printer.print_tile(pixel_tiles.at(tile_index), extrinsic_transparency));
300 }
301 return lines;
302}
303
321[[nodiscard]] inline std::vector<std::string> build_primary_tile_color_version_lines(
322 const TextFormatter &format,
323 const TilePrinter &tile_printer,
324 const std::vector<PackingParams::PrimaryTileRef> &primary_tiles,
325 const Rgba32 &extrinsic_transparency,
326 const std::vector<std::pair<std::size_t, std::size_t>> &primary_color_version_entries,
327 std::size_t version_offset)
328{
329 std::vector<std::string> lines;
330 for (std::size_t v = 0; v < primary_color_version_entries.size(); ++v) {
331 const auto &[tile_index, pal_index] = primary_color_version_entries.at(v);
332 const auto &primary_ref = primary_tiles.at(tile_index);
333 lines.emplace_back(format.format(
334 "Color version {} (primary {}, palette '{}'):",
335 FormatParam{version_offset + v + 1, Style::bold},
337 metatile::message_header(format, primary_ref.metatile_index, primary_ref.layer, primary_ref.subtile),
338 Style::bold},
339 FormatParam{pal_filename(pal_index), Style::bold}));
340 lines.append_range(tile_printer.print_tile(primary_ref.tile, extrinsic_transparency));
341 }
342 return lines;
343}
344
357[[nodiscard]] inline std::vector<std::string>
358build_truncated_tile_ref_lines(const TextFormatter &format, const std::vector<std::size_t> &tile_indices)
359{
360 constexpr std::size_t max_displayed_refs = 8;
361 constexpr std::size_t refs_per_line = 2;
362
363 std::vector<std::string> lines;
364 const std::size_t display_count = std::min(tile_indices.size(), max_displayed_refs);
365 std::string current_line;
366 std::size_t count_on_line = 0;
367 for (std::size_t i = 0; i < display_count; i++) {
368 if (count_on_line > 0) {
369 current_line += ", ";
370 }
371 auto [mt_index, layer, subtile] = metatile::from_tile_index(tile_indices.at(i));
372 current_line += "secondary " + metatile::message_header(format, mt_index, layer, subtile);
373 count_on_line++;
374 if (count_on_line == refs_per_line) {
375 lines.emplace_back(current_line);
376 current_line.clear();
377 count_on_line = 0;
378 }
379 }
380 if (tile_indices.size() > max_displayed_refs) {
381 if (!current_line.empty()) {
382 lines.emplace_back(current_line);
383 current_line.clear();
384 }
385 lines.emplace_back(
386 format.format("... and {} more.", FormatParam{tile_indices.size() - max_displayed_refs, Style::bold}));
387 }
388 else if (!current_line.empty()) {
389 lines.emplace_back(current_line);
390 }
391 return lines;
392}
393
406[[nodiscard]] inline std::vector<std::string> build_per_palette_tile_ref_lines(
407 const TextFormatter &format, const std::map<std::size_t, std::vector<std::size_t>> &members_by_pal)
408{
409 std::vector<std::string> lines;
410 for (const auto &[pal_index, tile_indices] : members_by_pal) {
411 lines.emplace_back(format.format(
412 "Palette '{}': '{}' tilemap entries:",
413 FormatParam{pal_filename(pal_index), Style::bold},
414 FormatParam{tile_indices.size(), Style::bold}));
415 lines.append_range(build_truncated_tile_ref_lines(format, tile_indices));
416 }
417 return lines;
418}
419
434[[nodiscard]] inline std::vector<std::string> build_representative_tile_per_palette_lines(
435 const TextFormatter &format,
436 const TilePrinter &tile_printer,
437 const std::vector<PixelTile<Rgba32>> &pixel_tiles,
438 const Rgba32 &extrinsic_transparency,
439 const std::map<std::size_t, std::vector<std::size_t>> &members_by_pal)
440{
441 std::vector<std::string> lines;
442 for (const auto &[pal_index, tile_indices] : members_by_pal) {
443 const auto representative_tile_index = tile_indices.front();
444 auto [mt_index, layer, subtile] = metatile::from_tile_index(representative_tile_index);
445 lines.emplace_back(format.format(
446 "Representative shape for palette '{}' (secondary {}):",
447 FormatParam{pal_filename(pal_index), Style::bold},
448 FormatParam{metatile::message_header(format, mt_index, layer, subtile), Style::bold}));
449 lines.append_range(tile_printer.print_tile(pixel_tiles.at(representative_tile_index), extrinsic_transparency));
450 }
451 return lines;
452}
453
470[[nodiscard]] inline std::vector<std::string> build_primary_representative_tile_per_palette_lines(
471 const TextFormatter &format,
472 const TilePrinter &tile_printer,
473 const std::vector<PackingParams::PrimaryTileRef> &primary_tiles,
474 const Rgba32 &extrinsic_transparency,
475 const std::map<std::size_t, std::vector<std::size_t>> &primary_members_by_pal)
476{
477 std::vector<std::string> lines;
478 for (const auto &[pal_index, tile_indices] : primary_members_by_pal) {
479 const auto representative_tile_index = tile_indices.front();
480 const auto &primary_ref = primary_tiles.at(representative_tile_index);
481 lines.emplace_back(format.format(
482 "Representative shape for palette '{}' (primary {}):",
483 FormatParam{pal_filename(pal_index), Style::bold},
485 metatile::message_header(format, primary_ref.metatile_index, primary_ref.layer, primary_ref.subtile),
486 Style::bold}));
487 lines.append_range(tile_printer.print_tile(primary_ref.tile, extrinsic_transparency));
488 }
489 return lines;
490}
491
492} // namespace porytiles
A container that wraps a configuration value with its name and source information.
std::vector< std::string > prettify(const TextFormatter &formatter) const
Generates a prettified, styled readout of this configuration value.
A text parameter with associated styling for formatted output.
Represents a palette hint for the palette packing algorithm.
A collection of printer functions for the Palette and related types.
virtual std::vector< std::string > print_pal_hint_with_highlights(const PaletteHint &hint, const std::vector< std::size_t > &slots) const =0
virtual std::vector< std::string > print_rgba_pal_with_highlights(const Palette< Rgba32 > &pal, const std::vector< std::size_t > &slots) const =0
A generic palette container for colors that support transparency checking.
Definition palette.hpp:47
An 8x8 tile backed by literal-array-based per-pixel storage of an arbitrary pixel type.
Represents a 32-bit RGBA color.
Definition rgba32.hpp:23
Abstract base class for applying text styling with context-aware formatting.
virtual std::string format(const std::string &format_str, const std::vector< FormatParam > &params) const
Formats a string with styled parameters using fmtlib syntax.
A collection of printer functions for various tile types.
virtual std::vector< std::string > print_tile(const PixelTile< Rgba32 > &tile, const Rgba32 &extrinsic_transparency) const =0
std::tuple< std::size_t, Layer, Subtile > from_tile_index(std::size_t tile_index)
Decomposes a global tile index into its metatile index, layer, and subtile position.
Definition metatile.hpp:90
std::string message_header(const TextFormatter &format, std::size_t index, Layer layer, Subtile subtile, std::size_t subtile_row, std::size_t subtile_col)
Definition metatile.hpp:130
std::vector< std::string > build_pal_hint_highlight_lines(const TextFormatter &format, const PalettePrinter &pal_printer, const std::string &message, const PaletteHint &hint, const std::string &pal_label, const std::vector< std::size_t > &violating_slots)
Builds note lines displaying a palette hint with highlighted violating slots.
std::vector< std::string > build_porytiles_pal_highlight_lines(const TextFormatter &format, const PalettePrinter &pal_printer, const std::string &message, const Palette< Rgba32, N > &pal, const std::string &pal_label, const std::vector< std::size_t > &violating_slots)
Builds note lines displaying a Porytiles palette with highlighted violating slots.
std::vector< std::string > build_representative_tile_per_palette_lines(const TextFormatter &format, const TilePrinter &tile_printer, const std::vector< PixelTile< Rgba32 > > &pixel_tiles, const Rgba32 &extrinsic_transparency, const std::map< std::size_t, std::vector< std::size_t > > &members_by_pal)
Builds note lines showing one representative tile (ASCII art) per palette.
std::vector< std::string > build_subtraction_limit_lines(const TextFormatter &format, std::string_view label, std::size_t computed_limit, const ConfigValue< std::size_t > &total_cfg, const ConfigValue< std::size_t > &primary_cfg)
Builds note lines explaining a derived limit computed as total minus primary.
std::vector< std::string > build_truncated_tile_ref_lines(const TextFormatter &format, const std::vector< std::size_t > &tile_indices)
Builds truncated tile reference lines, displaying up to 8 entries 2-per-line with ellipsis.
std::vector< std::string > build_per_palette_tile_ref_lines(const TextFormatter &format, const std::map< std::size_t, std::vector< std::size_t > > &members_by_pal)
Builds per-palette tile reference lines with a header and truncated listing for each palette.
std::vector< std::string > format_config_note(const TextFormatter &format, const ConfigValue< T > &config)
Format a ConfigValue into diagnostic note lines.
std::vector< std::string > format_config_note_with_separator(const TextFormatter &format, const ConfigValue< T > &config)
Format a ConfigValue into diagnostic note lines with a separator.
std::vector< std::string > build_primary_tile_color_version_lines(const TextFormatter &format, const TilePrinter &tile_printer, const std::vector< PackingParams::PrimaryTileRef > &primary_tiles, const Rgba32 &extrinsic_transparency, const std::vector< std::pair< std::size_t, std::size_t > > &primary_color_version_entries, std::size_t version_offset)
Builds note lines showing ASCII art for each primary tile color version in a sharing group.
std::vector< std::string > build_porymap_pal_highlight_lines(const TextFormatter &format, const PalettePrinter &pal_printer, const std::string &message, const Palette< Rgba32, N > &pal, const std::string &pal_label, const std::vector< std::size_t > &violating_slots)
Builds note lines displaying a Porymap palette with highlighted violating slots.
std::vector< std::string > build_primary_representative_tile_per_palette_lines(const TextFormatter &format, const TilePrinter &tile_printer, const std::vector< PackingParams::PrimaryTileRef > &primary_tiles, const Rgba32 &extrinsic_transparency, const std::map< std::size_t, std::vector< std::size_t > > &primary_members_by_pal)
Builds note lines showing one representative primary tile (ASCII art) per palette.
std::vector< std::string > build_tile_sharing_color_version_tile_lines(const TextFormatter &format, const TilePrinter &tile_printer, const std::vector< PixelTile< Rgba32 > > &pixel_tiles, const Rgba32 &extrinsic_transparency, const std::vector< std::size_t > &color_version_tile_indices)
Builds note lines showing ASCII art for each color version tile in a sharing group.
std::vector< std::string > build_global_color_limit_lines(const TextFormatter &format, std::size_t color_count_limit, const ConfigValue< std::size_t > &num_pals)
Builds note lines explaining the global color count limit for primary tileset compilation.
constexpr std::string_view diagnostic_separator
Utility functions for string manipulation and formatting.