Porytiles
Loading...
Searching...
No Matches
lazy_layered_config.cpp
Go to the documentation of this file.
2
3#include <any>
4#include <functional>
5#include <ranges>
6#include <string>
7
8#include "fmt/format.h"
9
15
16namespace porytiles2 {
17
18/*
19 * NOTE: DO NOT EDIT THIS FILE DIRECTLY. It is AUTO-GENERATED from config_schema.yaml.
20 * To add new config values or make other changes, edit config_schema.yaml and regenerate using
21 * Scripts/generate_config.py.
22 */
23
24template <typename T>
25ChainableResult<ConfigValue<T>> LazyLayeredConfig::resolve_config_value(
26 const std::string &cache_key, std::function<LayerValue<T>(const ConfigProvider &)> provider_call) const
27{
28 /*
29 * WARNING! HACK ALERT! WARNING!
30 * DO NOT DELETE THIS USING STATEMENT.
31 *
32 * We need to declare this here so that the to_string call below can resolve to either the std:: version or one of
33 * our custom versions automagically.
34 */
35 using std::to_string;
36
37 // Check if already cached
38 if (cache_.contains(cache_key)) {
39 // TODO: catch bad_any_cast here and panic
40 T cached_value = std::any_cast<T>(cache_.at(cache_key));
41 std::string source = source_.at(cache_key);
42 std::vector<std::string> source_details = source_details_.at(cache_key);
43 return ConfigValue<T>{cached_value, cache_key, source, source_details};
44 }
45
46 // Search through providers in priority order
47 for (const auto &provider : providers_) {
48 LayerValue<T> layer_value = provider_call(*provider);
49
50 // Check if provider found an invalid value - stop immediately and return error
51 if (layer_value.state == ValidationState::invalid) {
52 const auto source_info = format_->format("{}", layer_value.source_info);
53 std::vector<std::string> error_lines;
54 error_lines.push_back(format_->format("{}: invalid: {}", source_info, layer_value.error_message));
55
56 if (!layer_value.source_details.empty()) {
57 error_lines.emplace_back(""); // Blank line separator
58 for (const auto &detail : layer_value.source_details) {
59 error_lines.push_back(detail);
60 }
61 }
62
63 return FormattableError{error_lines};
64 }
65
66 // Check if provider has a valid value
67 if (layer_value.state == ValidationState::valid) {
68 T resolved_value = layer_value.value.value();
69 cache_[cache_key] = resolved_value;
70 cache_value_strings_[cache_key] = to_string(resolved_value);
71 std::string source = format_->format("{}", layer_value.source_info);
72 source_[cache_key] = source;
73 source_details_[cache_key] = layer_value.source_details;
74 return ConfigValue<T>{resolved_value, cache_key, source, layer_value.source_details};
75 }
76
77 // Otherwise, state is not_provided - continue to next provider
78 }
79
80 // No value found in any layer - this is a programmer error
81 panic(format_->format("no value found for '{}' in any config layer", cache_key));
82}
83
85{
86 const auto name = extract_function_name();
87 // Strip the _raw suffix from the function name for cache key
88 const auto base_name = name.substr(0, name.size() - 4);
89 const auto key = tileset + ":" + base_name;
90 return resolve_config_value<std::size_t>(
91 key, [&tileset](const ConfigProvider &provider) { return provider.num_tiles_primary(tileset); });
92}
93
95{
96 const auto name = extract_function_name();
97 // Strip the _raw suffix from the function name for cache key
98 const auto base_name = name.substr(0, name.size() - 4);
99 const auto key = tileset + ":" + base_name;
100 return resolve_config_value<std::size_t>(
101 key, [&tileset](const ConfigProvider &provider) { return provider.num_tiles_total(tileset); });
102}
103
105{
106 const auto name = extract_function_name();
107 // Strip the _raw suffix from the function name for cache key
108 const auto base_name = name.substr(0, name.size() - 4);
109 const auto key = tileset + ":" + base_name;
110 return resolve_config_value<std::size_t>(
111 key, [&tileset](const ConfigProvider &provider) { return provider.num_metatiles_primary(tileset); });
112}
113
115{
116 const auto name = extract_function_name();
117 // Strip the _raw suffix from the function name for cache key
118 const auto base_name = name.substr(0, name.size() - 4);
119 const auto key = tileset + ":" + base_name;
120 return resolve_config_value<std::size_t>(
121 key, [&tileset](const ConfigProvider &provider) { return provider.num_metatiles_total(tileset); });
122}
123
125{
126 const auto name = extract_function_name();
127 // Strip the _raw suffix from the function name for cache key
128 const auto base_name = name.substr(0, name.size() - 4);
129 const auto key = tileset + ":" + base_name;
130 return resolve_config_value<std::size_t>(
131 key, [&tileset](const ConfigProvider &provider) { return provider.num_pals_primary(tileset); });
132}
133
135{
136 const auto name = extract_function_name();
137 // Strip the _raw suffix from the function name for cache key
138 const auto base_name = name.substr(0, name.size() - 4);
139 const auto key = tileset + ":" + base_name;
140 return resolve_config_value<std::size_t>(
141 key, [&tileset](const ConfigProvider &provider) { return provider.num_pals_total(tileset); });
142}
143
145{
146 const auto name = extract_function_name();
147 // Strip the _raw suffix from the function name for cache key
148 const auto base_name = name.substr(0, name.size() - 4);
149 const auto key = tileset + ":" + base_name;
150 return resolve_config_value<std::size_t>(
151 key, [&tileset](const ConfigProvider &provider) { return provider.max_map_data_size(tileset); });
152}
153
155{
156 const auto name = extract_function_name();
157 // Strip the _raw suffix from the function name for cache key
158 const auto base_name = name.substr(0, name.size() - 4);
159 const auto key = tileset + ":" + base_name;
160 return resolve_config_value<std::size_t>(
161 key, [&tileset](const ConfigProvider &provider) { return provider.num_tiles_per_metatile(tileset); });
162}
163
165{
166 const auto name = extract_function_name();
167 // Strip the _raw suffix from the function name for cache key
168 const auto base_name = name.substr(0, name.size() - 4);
169 const auto key = tileset + ":" + base_name;
170 return resolve_config_value<Rgba32>(
171 key, [&tileset](const ConfigProvider &provider) { return provider.extrinsic_transparency(tileset); });
172}
173
175{
176 const auto name = extract_function_name();
177 // Strip the _raw suffix from the function name for cache key
178 const auto base_name = name.substr(0, name.size() - 4);
179 const auto key = tileset + ":" + base_name;
180 return resolve_config_value<bool>(
181 key, [&tileset](const ConfigProvider &provider) { return provider.patch_build_enabled(tileset); });
182}
183
185{
186 const auto name = extract_function_name();
187 // Strip the _raw suffix from the function name for cache key
188 const auto base_name = name.substr(0, name.size() - 4);
189 const auto key = tileset + ":" + base_name;
190 return resolve_config_value<TilesPalMode>(
191 key, [&tileset](const ConfigProvider &provider) { return provider.tiles_pal_mode(tileset); });
192}
193
194std::string LazyLayeredConfig::dump() const
195{
196 if (cache_.empty()) {
197 return "LazyLayeredConfig {}";
198 }
199
200 std::string result = "LazyLayeredConfig {\n";
201 for (const auto &key : cache_ | std::views::keys) {
202 const auto provenance_it = source_.find(key);
203 const std::string provenance_info =
204 (provenance_it != source_.end()) ? provenance_it->second : "<unknown source>";
205
206 const auto value_it = cache_value_strings_.find(key);
207 const std::string value_str = (value_it != cache_value_strings_.end()) ? value_it->second : "<unknown value>";
208
209 result += format_->format(" {} = {} [{}]\n", key, value_str, provenance_info);
210 }
211 result += "}\n";
212
213 return result;
214}
215
216void LazyLayeredConfig::warmup_cache(const std::vector<std::string> &tileset_names) const
217{
218 for (const auto &tileset_name : tileset_names) {
219 // Note: These calls now return ChainableResult, but we ignore both success and error cases
220 // This is intentional for warmup - we just want to populate the cache
221 // If you want to validate config at startup, call these and check has_value()
222
223 // Domain config
224 std::ignore = num_tiles_primary(tileset_name);
225 std::ignore = num_tiles_total(tileset_name);
226 std::ignore = num_metatiles_primary(tileset_name);
227 std::ignore = num_metatiles_total(tileset_name);
228 std::ignore = num_pals_primary(tileset_name);
229 std::ignore = num_pals_total(tileset_name);
230 std::ignore = max_map_data_size(tileset_name);
231 std::ignore = num_tiles_per_metatile(tileset_name);
232 std::ignore = extrinsic_transparency(tileset_name);
233 std::ignore = patch_build_enabled(tileset_name);
234
235 // App config
236
237 // Infra config
238 std::ignore = tiles_pal_mode(tileset_name);
239 }
240}
241
242} // namespace porytiles2
A result type that maintains a chainable sequence of errors for debugging and error reporting.
An interface which config implementations can use to load config values.
virtual LayerValue< std::size_t > num_pals_primary(const std::string &tileset) const
virtual LayerValue< std::size_t > num_metatiles_primary(const std::string &tileset) const
virtual LayerValue< std::size_t > num_pals_total(const std::string &tileset) const
virtual LayerValue< std::size_t > num_tiles_primary(const std::string &tileset) const
virtual LayerValue< Rgba32 > extrinsic_transparency(const std::string &tileset) const
virtual LayerValue< bool > patch_build_enabled(const std::string &tileset) const
virtual LayerValue< std::size_t > num_tiles_total(const std::string &tileset) const
virtual LayerValue< std::size_t > max_map_data_size(const std::string &tileset) const
virtual LayerValue< TilesPalMode > tiles_pal_mode(const std::string &tileset) const
virtual LayerValue< std::size_t > num_tiles_per_metatile(const std::string &tileset) const
virtual LayerValue< std::size_t > num_metatiles_total(const std::string &tileset) const
ChainableResult< ConfigValue< std::size_t > > num_pals_primary(const std::string &tileset) const
ChainableResult< ConfigValue< std::size_t > > max_map_data_size(const std::string &tileset) const
ChainableResult< ConfigValue< std::size_t > > num_pals_total(const std::string &tileset) const
ChainableResult< ConfigValue< Rgba32 > > extrinsic_transparency(const std::string &tileset) const
ChainableResult< ConfigValue< std::size_t > > num_tiles_per_metatile(const std::string &tileset) const
ChainableResult< ConfigValue< std::size_t > > num_metatiles_total(const std::string &tileset) const
ChainableResult< ConfigValue< std::size_t > > num_tiles_primary(const std::string &tileset) const
ChainableResult< ConfigValue< std::size_t > > num_tiles_total(const std::string &tileset) const
ChainableResult< ConfigValue< std::size_t > > num_metatiles_primary(const std::string &tileset) const
ChainableResult< ConfigValue< bool > > patch_build_enabled(const std::string &tileset) const
ChainableResult< ConfigValue< TilesPalMode > > tiles_pal_mode(const std::string &tileset) const
ChainableResult< ConfigValue< std::size_t > > num_tiles_total_raw(const std::string &tileset) const override
ChainableResult< ConfigValue< Rgba32 > > extrinsic_transparency_raw(const std::string &tileset) const override
ChainableResult< ConfigValue< TilesPalMode > > tiles_pal_mode_raw(const std::string &tileset) const override
ChainableResult< ConfigValue< std::size_t > > num_tiles_per_metatile_raw(const std::string &tileset) const override
ChainableResult< ConfigValue< std::size_t > > num_metatiles_total_raw(const std::string &tileset) const override
ChainableResult< ConfigValue< bool > > patch_build_enabled_raw(const std::string &tileset) const override
ChainableResult< ConfigValue< std::size_t > > max_map_data_size_raw(const std::string &tileset) const override
ChainableResult< ConfigValue< std::size_t > > num_tiles_primary_raw(const std::string &tileset) const override
std::string dump() const
Dumps the current state of the config for debugging purposes.
ChainableResult< ConfigValue< std::size_t > > num_metatiles_primary_raw(const std::string &tileset) const override
ChainableResult< ConfigValue< std::size_t > > num_pals_primary_raw(const std::string &tileset) const override
void warmup_cache(const std::vector< std::string > &tileset_names) const
Forces all configuration values to be cached immediately for all known tilesets.
ChainableResult< ConfigValue< std::size_t > > num_pals_total_raw(const std::string &tileset) const override
virtual std::string format(const std::string &format_str, const std::vector< FormatParam > &params) const
Formats a string with styled parameters using fmtlib syntax.
void panic(const StringViewSourceLoc &s)
Unconditionally terminates the program with a panic message.
Definition panic.hpp:53
std::string extract_function_name(const std::source_location &location=std::source_location::current())
Extracts the function name from a source location.
std::string to_string(const IncrementalBuildMode &value)