9#include "yaml-cpp/yaml.h"
26 gsl::not_null<const TextFormatter *> format,
28 const std::filesystem::path &project_root)
29 : format_{format}, diagnostics_{diagnostics}, project_root_{project_root}
36 const std::filesystem::path &project_root)
37 : owned_format_{std::make_unique<
PlainTextFormatter>()}, format_{owned_format_.get()}, diagnostics_{diagnostics},
38 project_root_{project_root}
45 return "YamlFileProvider";
50 return preload_and_validate_yaml_files(format_, diagnostics_, project_root_, type, scope);
55 auto paths_result = get_config_path_chain(project_root_, type, scope);
56 if (!paths_result.has_value()) {
59 return search_config_files<std::size_t>(
62 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
63 [](
const YAML::Node &doc) { return doc[
"fieldmap"][
"num_tiles_in_primary"]; },
65 "fieldmap.num_tiles_in_primary",
66 "fieldmap.num_tiles_in_primary");
71 auto paths_result = get_config_path_chain(project_root_, type, scope);
72 if (!paths_result.has_value()) {
75 return search_config_files<std::size_t>(
78 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
79 [](
const YAML::Node &doc) { return doc[
"fieldmap"][
"num_tiles_total"]; },
81 "fieldmap.num_tiles_total",
82 "fieldmap.num_tiles_total");
87 auto paths_result = get_config_path_chain(project_root_, type, scope);
88 if (!paths_result.has_value()) {
91 return search_config_files<std::size_t>(
94 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
95 [](
const YAML::Node &doc) { return doc[
"fieldmap"][
"num_metatiles_in_primary"]; },
97 "fieldmap.num_metatiles_in_primary",
98 "fieldmap.num_metatiles_in_primary");
103 auto paths_result = get_config_path_chain(project_root_, type, scope);
104 if (!paths_result.has_value()) {
107 return search_config_files<std::size_t>(
109 paths_result.value(),
110 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
111 [](
const YAML::Node &doc) { return doc[
"fieldmap"][
"num_metatiles_total"]; },
113 "fieldmap.num_metatiles_total",
114 "fieldmap.num_metatiles_total");
119 auto paths_result = get_config_path_chain(project_root_, type, scope);
120 if (!paths_result.has_value()) {
123 return search_config_files<std::size_t>(
125 paths_result.value(),
126 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
127 [](
const YAML::Node &doc) { return doc[
"fieldmap"][
"num_pals_in_primary"]; },
129 "fieldmap.num_pals_in_primary",
130 "fieldmap.num_pals_in_primary");
135 auto paths_result = get_config_path_chain(project_root_, type, scope);
136 if (!paths_result.has_value()) {
139 return search_config_files<std::size_t>(
141 paths_result.value(),
142 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
143 [](
const YAML::Node &doc) { return doc[
"fieldmap"][
"num_pals_total"]; },
145 "fieldmap.num_pals_total",
146 "fieldmap.num_pals_total");
151 auto paths_result = get_config_path_chain(project_root_, type, scope);
152 if (!paths_result.has_value()) {
155 return search_config_files<std::size_t>(
157 paths_result.value(),
158 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
159 [](
const YAML::Node &doc) { return doc[
"fieldmap"][
"max_map_data_size"]; },
161 "fieldmap.max_map_data_size",
162 "fieldmap.max_map_data_size");
167 auto paths_result = get_config_path_chain(project_root_, type, scope);
168 if (!paths_result.has_value()) {
171 return search_config_files<std::size_t>(
173 paths_result.value(),
174 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
175 [](
const YAML::Node &doc) { return doc[
"fieldmap"][
"num_tiles_per_metatile"]; },
177 "fieldmap.num_tiles_per_metatile",
178 "fieldmap.num_tiles_per_metatile");
183 auto paths_result = get_config_path_chain(project_root_, type, scope);
184 if (!paths_result.has_value()) {
187 return search_config_files<Rgba32>(
189 paths_result.value(),
190 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
191 [](
const YAML::Node &doc) { return doc[
"tileset"][
"extrinsic_transparency"]; },
193 "tileset.extrinsic_transparency",
194 "tileset.extrinsic_transparency");
199 auto paths_result = get_config_path_chain(project_root_, type, scope);
200 if (!paths_result.has_value()) {
203 return search_config_files<ArtifactEditMode>(
205 paths_result.value(),
206 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
207 [](
const YAML::Node &doc) { return doc[
"tileset"][
"tiles"][
"edit_mode"]; },
208 parse_artifact_edit_mode,
209 "tileset.tiles.edit_mode",
210 "tileset.tiles.edit_mode");
215 auto paths_result = get_config_path_chain(project_root_, type, scope);
216 if (!paths_result.has_value()) {
219 return search_config_files<ArtifactEditMode>(
221 paths_result.value(),
222 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
223 [](
const YAML::Node &doc) { return doc[
"tileset"][
"palettes"][
"edit_mode"]; },
224 parse_artifact_edit_mode,
225 "tileset.palettes.edit_mode",
226 "tileset.palettes.edit_mode");
231 auto paths_result = get_config_path_chain(project_root_, type, scope);
232 if (!paths_result.has_value()) {
235 return search_config_files<bool>(
237 paths_result.value(),
238 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
239 [](
const YAML::Node &doc) { return doc[
"tileset"][
"palettes"][
"packing"][
"hints_enabled"]; },
241 "tileset.palettes.packing.hints_enabled",
242 "tileset.palettes.packing.hints_enabled");
247 auto paths_result = get_config_path_chain(project_root_, type, scope);
248 if (!paths_result.has_value()) {
251 return search_config_files<std::vector<PaletteHint>>(
253 paths_result.value(),
254 [
this](
const std::filesystem::path &p) {
return load_yaml_file(p, format_, diagnostics_); },
255 [](
const YAML::Node &doc) {
return doc[
"tileset"][
"palettes"][
"packing"][
"hints"]; },
257 "tileset.palettes.packing.hints",
258 "tileset.palettes.packing.hints");
263 auto paths_result = get_config_path_chain(project_root_, type, scope);
264 if (!paths_result.has_value()) {
267 return search_config_files<PackingStrategyType>(
269 paths_result.value(),
270 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
271 [](
const YAML::Node &doc) { return doc[
"tileset"][
"palettes"][
"packing"][
"strategy"]; },
272 parse_packing_strategy_type,
273 "tileset.palettes.packing.strategy",
274 "tileset.palettes.packing.strategy");
279 auto paths_result = get_config_path_chain(project_root_, type, scope);
280 if (!paths_result.has_value()) {
283 return search_config_files<PackingStrategyParams>(
285 paths_result.value(),
286 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
287 [](
const YAML::Node &doc) { return doc[
"tileset"][
"palettes"][
"packing"][
"strategy_params"]; },
288 parse_packing_strategy_params,
289 "tileset.palettes.packing.strategy_params",
290 "tileset.palettes.packing.strategy_params");
295 auto paths_result = get_config_path_chain(project_root_, type, scope);
296 if (!paths_result.has_value()) {
299 return search_config_files<TileSharingPacking>(
301 paths_result.value(),
302 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
303 [](
const YAML::Node &doc) { return doc[
"tileset"][
"tiles"][
"sharing"][
"packing"]; },
304 parse_tile_sharing_packing,
305 "tileset.tiles.sharing.packing",
306 "tileset.tiles.sharing.packing");
311 auto paths_result = get_config_path_chain(project_root_, type, scope);
312 if (!paths_result.has_value()) {
315 return search_config_files<TileSharingAlignment>(
317 paths_result.value(),
318 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
319 [](
const YAML::Node &doc) { return doc[
"tileset"][
"tiles"][
"sharing"][
"alignment"]; },
320 parse_tile_sharing_alignment,
321 "tileset.tiles.sharing.alignment",
322 "tileset.tiles.sharing.alignment");
327 auto paths_result = get_config_path_chain(project_root_, type, scope);
328 if (!paths_result.has_value()) {
331 return search_config_files<TilesPalMode>(
333 paths_result.value(),
334 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
335 [](
const YAML::Node &doc) { return doc[
"tileset"][
"tiles"][
"palette_mode"]; },
336 parse_tiles_pal_mode,
337 "tileset.tiles.palette_mode",
338 "tileset.tiles.palette_mode");
343 auto paths_result = get_config_path_chain(project_root_, type, scope);
344 if (!paths_result.has_value()) {
347 return search_config_files<AnimPalResolutionStrategy>(
349 paths_result.value(),
350 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
351 [](
const YAML::Node &doc) { return doc[
"tileset"][
"animations"][
"palette_resolution_strategy"]; },
352 parse_anim_pal_resolution_strategy,
353 "tileset.animations.palette_resolution_strategy",
354 "tileset.animations.palette_resolution_strategy");
359 auto paths_result = get_config_path_chain(project_root_, type, scope);
360 if (!paths_result.has_value()) {
363 return search_config_files<AnimKeyFrameResolutionStrategy>(
365 paths_result.value(),
366 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
367 [](
const YAML::Node &doc) { return doc[
"tileset"][
"animations"][
"key_frame_resolution_strategy"]; },
368 parse_anim_key_frame_resolution_strategy,
369 "tileset.animations.key_frame_resolution_strategy",
370 "tileset.animations.key_frame_resolution_strategy");
375 auto paths_result = get_config_path_chain(project_root_, type, scope);
376 if (!paths_result.has_value()) {
379 return search_config_files<AnimMultiPalSubtileResolutionStrategy>(
381 paths_result.value(),
382 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
383 [](
const YAML::Node &doc) { return doc[
"tileset"][
"animations"][
"multi_palette_subtile_resolution_strategy"]; },
384 parse_anim_multi_pal_subtile_resolution_strategy,
385 "tileset.animations.multi_palette_subtile_resolution_strategy",
386 "tileset.animations.multi_palette_subtile_resolution_strategy");
391 auto paths_result = get_config_path_chain(project_root_, type, scope);
392 if (!paths_result.has_value()) {
395 return search_config_files<FrameLinking>(
397 paths_result.value(),
398 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
399 [](
const YAML::Node &doc) { return doc[
"tileset"][
"animations"][
"frame_linking"]; },
401 "tileset.animations.frame_linking",
402 "tileset.animations.frame_linking");
407 auto paths_result = get_config_path_chain(project_root_, type, scope);
408 if (!paths_result.has_value()) {
411 return search_config_files<PerAnimOverrides>(
413 paths_result.value(),
414 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
415 [](
const YAML::Node &doc) { return doc[
"tileset"][
"animations"][
"per_animation_overrides"]; },
416 parse_per_anim_overrides,
417 "tileset.animations.per_animation_overrides",
418 "tileset.animations.per_animation_overrides");
423 auto paths_result = get_config_path_chain(project_root_, type, scope);
424 if (!paths_result.has_value()) {
427 return search_config_files<bool>(
429 paths_result.value(),
430 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
431 [](
const YAML::Node &doc) { return doc[
"tileset"][
"animations"][
"cross_tileset_linking"]; },
433 "tileset.animations.cross_tileset_linking",
434 "tileset.animations.cross_tileset_linking");
439 auto paths_result = get_config_path_chain(project_root_, type, scope);
440 if (!paths_result.has_value()) {
443 return search_config_files<bool>(
445 paths_result.value(),
446 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
447 [](
const YAML::Node &doc) { return doc[
"verify_checksums"]; },
455 auto paths_result = get_config_path_chain(project_root_, type, scope);
456 if (!paths_result.has_value()) {
459 return search_config_files<PrimaryPairingMode>(
461 paths_result.value(),
462 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
463 [](
const YAML::Node &doc) { return doc[
"tileset"][
"primary_pairing"][
"mode"]; },
464 parse_primary_pairing_mode,
465 "tileset.primary_pairing.mode",
466 "tileset.primary_pairing.mode");
471 auto paths_result = get_config_path_chain(project_root_, type, scope);
472 if (!paths_result.has_value()) {
475 return search_config_files<std::vector<std::string>>(
477 paths_result.value(),
478 [
this](
const std::filesystem::path &p) {
return load_yaml_file(p, format_, diagnostics_); },
479 [](
const YAML::Node &doc) {
return doc[
"tileset"][
"primary_pairing"][
"partners"]; },
481 "tileset.primary_pairing.partners",
482 "tileset.primary_pairing.partners");
487 auto paths_result = get_config_path_chain(project_root_, type, scope);
488 if (!paths_result.has_value()) {
491 return search_config_files<std::vector<std::string>>(
493 paths_result.value(),
494 [
this](
const std::filesystem::path &p) {
return load_yaml_file(p, format_, diagnostics_); },
495 [](
const YAML::Node &doc) {
return doc[
"diagnostics"][
"warnings"][
"exclude"]; },
497 "diagnostics.warnings.exclude",
498 "diagnostics.warnings.exclude");
503 auto paths_result = get_config_path_chain(project_root_, type, scope);
504 if (!paths_result.has_value()) {
507 return search_config_files<std::vector<std::string>>(
509 paths_result.value(),
510 [
this](
const std::filesystem::path &p) {
return load_yaml_file(p, format_, diagnostics_); },
511 [](
const YAML::Node &doc) {
return doc[
"diagnostics"][
"warnings"][
"include"]; },
513 "diagnostics.warnings.include",
514 "diagnostics.warnings.include");
519 auto paths_result = get_config_path_chain(project_root_, type, scope);
520 if (!paths_result.has_value()) {
523 return search_config_files<std::vector<std::string>>(
525 paths_result.value(),
526 [
this](
const std::filesystem::path &p) {
return load_yaml_file(p, format_, diagnostics_); },
527 [](
const YAML::Node &doc) {
return doc[
"diagnostics"][
"remarks"][
"exclude"]; },
529 "diagnostics.remarks.exclude",
530 "diagnostics.remarks.exclude");
535 auto paths_result = get_config_path_chain(project_root_, type, scope);
536 if (!paths_result.has_value()) {
539 return search_config_files<std::vector<std::string>>(
541 paths_result.value(),
542 [
this](
const std::filesystem::path &p) {
return load_yaml_file(p, format_, diagnostics_); },
543 [](
const YAML::Node &doc) {
return doc[
"diagnostics"][
"remarks"][
"include"]; },
545 "diagnostics.remarks.include",
546 "diagnostics.remarks.include");
551 auto paths_result = get_config_path_chain(project_root_, type, scope);
552 if (!paths_result.has_value()) {
555 return search_config_files<std::string>(
557 paths_result.value(),
558 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
559 [](
const YAML::Node &doc) { return doc[
"tileset"][
"paths"][
"primary"][
"src"]; },
561 "tileset.paths.primary.src",
562 "tileset.paths.primary.src");
567 auto paths_result = get_config_path_chain(project_root_, type, scope);
568 if (!paths_result.has_value()) {
571 return search_config_files<std::string>(
573 paths_result.value(),
574 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
575 [](
const YAML::Node &doc) { return doc[
"tileset"][
"paths"][
"primary"][
"bin"]; },
577 "tileset.paths.primary.bin",
578 "tileset.paths.primary.bin");
583 auto paths_result = get_config_path_chain(project_root_, type, scope);
584 if (!paths_result.has_value()) {
587 return search_config_files<std::string>(
589 paths_result.value(),
590 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
591 [](
const YAML::Node &doc) { return doc[
"tileset"][
"paths"][
"secondary"][
"src"]; },
593 "tileset.paths.secondary.src",
594 "tileset.paths.secondary.src");
599 auto paths_result = get_config_path_chain(project_root_, type, scope);
600 if (!paths_result.has_value()) {
603 return search_config_files<std::string>(
605 paths_result.value(),
606 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
607 [](
const YAML::Node &doc) { return doc[
"tileset"][
"paths"][
"secondary"][
"bin"]; },
609 "tileset.paths.secondary.bin",
610 "tileset.paths.secondary.bin");
615 auto paths_result = get_config_path_chain(project_root_, type, scope);
616 if (!paths_result.has_value()) {
619 return search_config_files<std::size_t>(
621 paths_result.value(),
622 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
623 [](
const YAML::Node &doc) { return doc[
"fieldmap"][
"metatile_attribute_size"]; },
625 "fieldmap.metatile_attribute_size",
626 "fieldmap.metatile_attribute_size");
631 auto paths_result = get_config_path_chain(project_root_, type, scope);
632 if (!paths_result.has_value()) {
635 return search_config_files<bool>(
637 paths_result.value(),
638 [
this](
const std::filesystem::path &p) { return load_yaml_file(p, format_, diagnostics_); },
639 [](
const YAML::Node &doc) { return doc[
"tileset"][
"animations"][
"wire_anim_code"]; },
641 "tileset.animations.wire_anim_code",
642 "tileset.animations.wire_anim_code");
TextFormatter implementation that strips all styling from text.
Abstract class for structured error reporting and diagnostic output.
LayerValue< std::size_t > num_tiles_in_primary(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::vector< std::string > > diagnostic_remarks_exclude(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::string > tileset_paths_secondary_bin(ConfigScopeType type, const std::string &scope) const override
LayerValue< Rgba32 > extrinsic_transparency(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::vector< std::string > > primary_pairing_partners(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::size_t > num_pals_in_primary(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::size_t > num_metatiles_in_primary(ConfigScopeType type, const std::string &scope) const override
LayerValue< AnimKeyFrameResolutionStrategy > global_anim_key_frame_resolution_strategy(ConfigScopeType type, const std::string &scope) const override
LayerValue< bool > tileset_animations_wire_anim_code(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::size_t > max_map_data_size(ConfigScopeType type, const std::string &scope) const override
YamlFileProvider(gsl::not_null< const TextFormatter * > format, const UserDiagnostics *diagnostics, const std::filesystem::path &project_root)
Constructs a YamlFileProvider that searches for configuration across multiple YAML files.
LayerValue< std::string > tileset_paths_primary_src(ConfigScopeType type, const std::string &scope) const override
LayerValue< PerAnimOverrides > per_anim_overrides(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::string > tileset_paths_primary_bin(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::string > tileset_paths_secondary_src(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::size_t > metatile_attr_size(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::size_t > num_pals_total(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::vector< std::string > > diagnostic_remarks_include(ConfigScopeType type, const std::string &scope) const override
LayerValue< PrimaryPairingMode > primary_pairing_mode(ConfigScopeType type, const std::string &scope) const override
LayerValue< ArtifactEditMode > tiles_edit_mode(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::vector< PaletteHint > > pal_hints(ConfigScopeType type, const std::string &scope) const override
LayerValue< TilesPalMode > tiles_pal_mode(ConfigScopeType type, const std::string &scope) const override
LayerValue< bool > cross_tileset_anim_linking(ConfigScopeType type, const std::string &scope) const override
LayerValue< bool > verify_checksums(ConfigScopeType type, const std::string &scope) const override
LayerValue< PackingStrategyType > packing_strategy(ConfigScopeType type, const std::string &scope) const override
LayerValue< FrameLinking > global_frame_linking(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::vector< std::string > > diagnostic_warnings_include(ConfigScopeType type, const std::string &scope) const override
LayerValue< ArtifactEditMode > pals_edit_mode(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::size_t > num_tiles_total(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::size_t > num_metatiles_total(ConfigScopeType type, const std::string &scope) const override
bool preload_and_validate(ConfigScopeType type, const std::string &scope) const
Eagerly loads all YAML config files and validates them for unknown keys.
std::string name() const override
Gets the name of this config layer.
LayerValue< bool > pal_hints_enabled(ConfigScopeType type, const std::string &scope) const override
LayerValue< AnimPalResolutionStrategy > global_anim_pal_resolution_strategy(ConfigScopeType type, const std::string &scope) const override
LayerValue< TileSharingPacking > tile_sharing_packing(ConfigScopeType type, const std::string &scope) const override
LayerValue< AnimMultiPalSubtileResolutionStrategy > global_anim_multi_pal_subtile_resolution_strategy(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::size_t > num_tiles_per_metatile(ConfigScopeType type, const std::string &scope) const override
LayerValue< std::vector< std::string > > diagnostic_warnings_exclude(ConfigScopeType type, const std::string &scope) const override
LayerValue< PackingStrategyParams > packing_strategy_params(ConfigScopeType type, const std::string &scope) const override
LayerValue< TileSharingAlignment > tile_sharing_alignment(ConfigScopeType type, const std::string &scope) const override
ConfigScopeType
Specifies the scope type for configuration value lookups.
Utility functions for string manipulation and formatting.
A small container that holds an optional-wrapped value, validation state, and metadata about the valu...
static LayerValue invalid(std::string error, std::string source_info)
Creates a LayerValue representing an invalid configuration value.