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
37template <typename T>
38[[nodiscard]] std::vector<std::string> format_config_note(const TextFormatter &format, const ConfigValue<T> &config)
39{
40 std::vector<std::string> lines{};
41 lines.push_back(format.format(
42 "'{}' is '{}' due to configuration:",
43 FormatParam{config.canonical_name(), Style::bold},
44 FormatParam{config.value(), Style::bold}));
45 lines.emplace_back("");
46 lines.append_range(config.prettify(format));
47 return lines;
48}
49
61template <typename T>
62[[nodiscard]] std::vector<std::string>
64{
65 std::vector<std::string> lines{};
66 lines.emplace_back("");
67 lines.emplace_back(diagnostic_separator);
68 lines.emplace_back("");
69 lines.append_range(format_config_note(format, config));
70 return lines;
71}
72
88[[nodiscard]] inline std::vector<std::string> build_global_color_limit_lines(
89 const TextFormatter &format, std::size_t color_count_limit, const ConfigValue<std::size_t> &num_palettes)
90{
91 std::vector<std::string> lines;
92 lines.push_back(format.format("Global unique color limit is '{}'.", FormatParam{color_count_limit, Style::bold}));
93 lines.emplace_back("");
94 lines.emplace_back("Color limit definition:");
95 lines.push_back(format.format(
96 "{} * {}:",
97 FormatParam{num_palettes.canonical_name(), Style::bold | Style::yellow},
98 FormatParam{"nontransparent_colors_per_palette", Style::bold}));
99 lines.push_back(format.format(
100 "{} * {} = {}",
101 FormatParam{num_palettes.value(), Style::bold | Style::yellow},
102 FormatParam{(palette::max_size - 1), Style::bold},
103 FormatParam{color_count_limit, Style::bold}));
104 lines.emplace_back("");
105 lines.append_range(format_config_note(format, num_palettes));
106 return lines;
107}
108
123[[nodiscard]] inline std::vector<std::string> build_subtraction_limit_lines(
124 const TextFormatter &format,
125 std::string_view label,
126 std::size_t computed_limit,
127 const ConfigValue<std::size_t> &total_cfg,
128 const ConfigValue<std::size_t> &primary_cfg)
129{
130 std::vector<std::string> lines;
131 lines.push_back(
132 format.format("{} is '{}'.", FormatParam{label, Style::bold}, FormatParam{computed_limit, Style::bold}));
133 lines.emplace_back("");
134 lines.push_back(format.format("{} definition:", FormatParam{label, Style::bold}));
135 lines.push_back(format.format(
136 "{} - {}:",
137 FormatParam{total_cfg.canonical_name(), Style::bold | Style::yellow},
138 FormatParam{primary_cfg.canonical_name(), Style::bold | Style::yellow}));
139 lines.push_back(format.format(
140 "{} - {} = {}",
141 FormatParam{total_cfg.value(), Style::bold},
142 FormatParam{primary_cfg.value(), Style::bold},
143 FormatParam{computed_limit, Style::bold}));
144 lines.emplace_back("");
145 lines.append_range(format_config_note(format, total_cfg));
146 lines.append_range(format_config_note_with_separator(format, primary_cfg));
147 return lines;
148}
149
169template <std::size_t N>
170[[nodiscard]] std::vector<std::string> build_porymap_palette_highlight_lines(
171 const TextFormatter &format,
172 const PalettePrinter &palette_printer,
173 const std::string &message,
174 const Palette<Rgba32, N> &palette,
175 const std::string &palette_label,
176 const std::vector<std::size_t> &violating_slots)
177{
178 std::vector<std::string> lines;
179 lines.emplace_back(
180 format.format("Porymap palette '{}': {}:", FormatParam{palette_label, Style::bold}, FormatParam{message}));
181 lines.emplace_back();
182 lines.append_range(palette_printer.print_rgba_palette_with_highlights(palette, violating_slots));
183 return lines;
184}
185
205template <std::size_t N>
206[[nodiscard]] std::vector<std::string> build_porytiles_palette_highlight_lines(
207 const TextFormatter &format,
208 const PalettePrinter &palette_printer,
209 const std::string &message,
210 const Palette<Rgba32, N> &palette,
211 const std::string &palette_label,
212 const std::vector<std::size_t> &violating_slots)
213{
214 std::vector<std::string> lines;
215 lines.emplace_back(
216 format.format("Porytiles palette '{}': {}:", FormatParam{palette_label, Style::bold}, FormatParam{message}));
217 lines.emplace_back();
218 lines.append_range(palette_printer.print_rgba_palette_with_highlights(palette, violating_slots));
219 return lines;
220}
221
240[[nodiscard]] inline std::vector<std::string> build_palette_hint_highlight_lines(
241 const TextFormatter &format,
242 const PalettePrinter &palette_printer,
243 const std::string &message,
244 const PaletteHint &hint,
245 const std::string &palette_label,
246 const std::vector<std::size_t> &violating_slots)
247{
248 std::vector<std::string> lines;
249 lines.emplace_back(
250 format.format("palette hint '{}': {}:", FormatParam{palette_label, Style::bold}, FormatParam{message}));
251 lines.emplace_back();
252 lines.append_range(palette_printer.print_palette_hint_with_highlights(hint, violating_slots));
253 return lines;
254}
255
268[[nodiscard]] inline std::vector<std::string> build_tile_sharing_color_version_tile_lines(
269 const TextFormatter &format,
270 const TilePrinter &tile_printer,
271 const std::vector<PixelTile<Rgba32>> &pixel_tiles,
272 const Rgba32 &extrinsic_transparency,
273 const std::vector<std::size_t> &color_version_tile_indices)
274{
275 std::vector<std::string> lines;
276 for (std::size_t v = 0; v < color_version_tile_indices.size(); ++v) {
277 const auto tile_index = color_version_tile_indices.at(v);
278 auto [mt_index, layer, subtile] = metatile::from_tile_index(tile_index);
279 lines.emplace_back(format.format(
280 "Color version {} (secondary {}):",
281 FormatParam{v + 1, Style::bold},
282 FormatParam{metatile::message_header(format, mt_index, layer, subtile), Style::bold}));
283 lines.append_range(tile_printer.print_tile(pixel_tiles.at(tile_index), extrinsic_transparency));
284 }
285 return lines;
286}
287
303[[nodiscard]] inline std::vector<std::string> build_primary_tile_color_version_lines(
304 const TextFormatter &format,
305 const TilePrinter &tile_printer,
306 const std::vector<PackingParams::PrimaryTileRef> &primary_tiles,
307 const Rgba32 &extrinsic_transparency,
308 const std::vector<std::pair<std::size_t, std::size_t>> &primary_color_version_entries,
309 std::size_t version_offset)
310{
311 std::vector<std::string> lines;
312 for (std::size_t v = 0; v < primary_color_version_entries.size(); ++v) {
313 const auto &[tile_index, palette_index] = primary_color_version_entries.at(v);
314 const auto &primary_ref = primary_tiles.at(tile_index);
315 lines.emplace_back(format.format(
316 "Color version {} (primary {}, palette '{}'):",
317 FormatParam{version_offset + v + 1, Style::bold},
319 metatile::message_header(format, primary_ref.metatile_index, primary_ref.layer, primary_ref.subtile),
320 Style::bold},
321 FormatParam{palette_filename(palette_index), Style::bold}));
322 lines.append_range(tile_printer.print_tile(primary_ref.tile, extrinsic_transparency));
323 }
324 return lines;
325}
326
338[[nodiscard]] inline std::vector<std::string>
339build_truncated_tile_ref_lines(const TextFormatter &format, const std::vector<std::size_t> &tile_indices)
340{
341 constexpr std::size_t max_displayed_refs = 8;
342
343 std::vector<std::string> lines;
344 const std::size_t display_count = std::min(tile_indices.size(), max_displayed_refs);
345 std::string joined;
346 for (std::size_t i = 0; i < display_count; i++) {
347 if (i > 0) {
348 joined += ", ";
349 }
350 auto [mt_index, layer, subtile] = metatile::from_tile_index(tile_indices.at(i));
351 joined += "secondary " + metatile::message_header(format, mt_index, layer, subtile);
352 }
353 if (!joined.empty()) {
354 lines.emplace_back(joined);
355 }
356 if (tile_indices.size() > max_displayed_refs) {
357 lines.emplace_back(
358 format.format("... and {} more.", FormatParam{tile_indices.size() - max_displayed_refs, Style::bold}));
359 }
360 return lines;
361}
362
373[[nodiscard]] inline std::vector<std::string> build_per_palette_tile_ref_lines(
374 const TextFormatter &format, const std::map<std::size_t, std::vector<std::size_t>> &members_by_palette)
375{
376 std::vector<std::string> lines;
377 for (const auto &[palette_index, tile_indices] : members_by_palette) {
378 lines.emplace_back(format.format(
379 "Palette '{}': '{}' tilemap entries:",
380 FormatParam{palette_filename(palette_index), Style::bold},
381 FormatParam{tile_indices.size(), Style::bold}));
382 lines.append_range(build_truncated_tile_ref_lines(format, tile_indices));
383 }
384 return lines;
385}
386
399[[nodiscard]] inline std::vector<std::string> build_representative_tile_per_palette_lines(
400 const TextFormatter &format,
401 const TilePrinter &tile_printer,
402 const std::vector<PixelTile<Rgba32>> &pixel_tiles,
403 const Rgba32 &extrinsic_transparency,
404 const std::map<std::size_t, std::vector<std::size_t>> &members_by_palette)
405{
406 std::vector<std::string> lines;
407 for (const auto &[palette_index, tile_indices] : members_by_palette) {
408 const auto representative_tile_index = tile_indices.front();
409 auto [mt_index, layer, subtile] = metatile::from_tile_index(representative_tile_index);
410 lines.emplace_back(format.format(
411 "Representative shape for palette '{}' (secondary {}):",
412 FormatParam{palette_filename(palette_index), Style::bold},
413 FormatParam{metatile::message_header(format, mt_index, layer, subtile), Style::bold}));
414 lines.append_range(tile_printer.print_tile(pixel_tiles.at(representative_tile_index), extrinsic_transparency));
415 }
416 return lines;
417}
418
433[[nodiscard]] inline std::vector<std::string> build_primary_representative_tile_per_palette_lines(
434 const TextFormatter &format,
435 const TilePrinter &tile_printer,
436 const std::vector<PackingParams::PrimaryTileRef> &primary_tiles,
437 const Rgba32 &extrinsic_transparency,
438 const std::map<std::size_t, std::vector<std::size_t>> &primary_members_by_palette)
439{
440 std::vector<std::string> lines;
441 for (const auto &[palette_index, tile_indices] : primary_members_by_palette) {
442 const auto representative_tile_index = tile_indices.front();
443 const auto &primary_ref = primary_tiles.at(representative_tile_index);
444 lines.emplace_back(format.format(
445 "Representative shape for palette '{}' (primary {}):",
446 FormatParam{palette_filename(palette_index), Style::bold},
448 metatile::message_header(format, primary_ref.metatile_index, primary_ref.layer, primary_ref.subtile),
449 Style::bold}));
450 lines.append_range(tile_printer.print_tile(primary_ref.tile, extrinsic_transparency));
451 }
452 return lines;
453}
454
455} // 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_rgba_palette_with_highlights(const Palette< Rgba32 > &palette, const std::vector< std::size_t > &slots) const =0
virtual std::vector< std::string > print_palette_hint_with_highlights(const PaletteHint &hint, const std::vector< std::size_t > &slots) const =0
A generic palette container for colors that support transparency checking.
Definition palette.hpp:45
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:21
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:132
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:170
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_palette)
Builds note lines showing one representative tile (ASCII art) per palette.
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_palette)
Builds note lines showing one representative primary 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, listing up to 8 entries comma-joined with ellipsis.
std::vector< std::string > build_global_color_limit_lines(const TextFormatter &format, std::size_t color_count_limit, const ConfigValue< std::size_t > &num_palettes)
Builds note lines explaining the global color count limit for primary tileset compilation.
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 > build_per_palette_tile_ref_lines(const TextFormatter &format, const std::map< std::size_t, std::vector< std::size_t > > &members_by_palette)
Builds per-palette tile reference lines with a header and truncated listing for each palette.
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_palette_highlight_lines(const TextFormatter &format, const PalettePrinter &palette_printer, const std::string &message, const Palette< Rgba32, N > &palette, const std::string &palette_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_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.
constexpr std::string_view diagnostic_separator
std::vector< std::string > build_palette_hint_highlight_lines(const TextFormatter &format, const PalettePrinter &palette_printer, const std::string &message, const PaletteHint &hint, const std::string &palette_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_palette_highlight_lines(const TextFormatter &format, const PalettePrinter &palette_printer, const std::string &message, const Palette< Rgba32, N > &palette, const std::string &palette_label, const std::vector< std::size_t > &violating_slots)
Builds note lines displaying a Porytiles palette with highlighted violating slots.
Utility functions for string manipulation and formatting.