Porytiles
Loading...
Searching...
No Matches
metatile_attribute_field_definition.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <filesystem>
5#include <format>
6#include <map>
7#include <optional>
8#include <ostream>
9#include <string>
10#include <unordered_set>
11#include <vector>
12
14
15namespace porytiles {
16
29 std::string name;
30 std::optional<std::uint32_t> mask;
31 std::optional<std::uint32_t> default_value;
32 std::optional<ProviderDefinition> provider;
33 std::optional<FieldRole> role;
34
35 bool operator==(const MetatileAttributeFieldDefinition &) const = default;
36};
37
39using MetatileAttributeFieldDefinitions = std::vector<MetatileAttributeFieldDefinition>;
40
49 bool remove{false};
50 std::optional<std::filesystem::path> header;
51 std::optional<std::string> prefix;
52 std::optional<std::unordered_set<std::string>> skipped;
53 std::optional<HeaderFormat> format;
54
55 bool operator==(const ProviderDefinitionOverride &) const = default;
56};
57
67 std::optional<std::uint32_t> mask;
68 std::optional<std::uint32_t> default_value;
69 std::optional<ProviderDefinitionOverride> provider;
70 std::optional<std::optional<FieldRole>> role;
71
72 bool operator==(const MetatileAttributeFieldOverride &) const = default;
73};
74
76using MetatileAttributeFieldOverrides = std::map<std::string, MetatileAttributeFieldOverride>;
77
78namespace detail {
79
80[[nodiscard]] inline std::string format_optional_mask(const std::optional<std::uint32_t> &mask)
81{
82 return mask.has_value() ? std::format("0x{:X}", mask.value()) : "none";
83}
84
85[[nodiscard]] inline std::string format_provider_definition(const ProviderDefinition &provider)
86{
87 return std::format(
88 "{{header={}, prefix={}, skip_count={}, format={}}}",
89 provider.header.string(),
90 provider.prefix,
91 provider.skipped.size(),
92 to_string(provider.format));
93}
94
95} // namespace detail
96
98[[nodiscard]] inline std::string to_string(const MetatileAttributeFieldDefinition &definition)
99{
100 std::string result = std::format(
101 "{}={{mask={}, default={}",
102 definition.name,
105 if (definition.provider.has_value()) {
106 result += ", provider=" + detail::format_provider_definition(definition.provider.value());
107 }
108 if (definition.role.has_value()) {
109 result += ", role=" + to_string(definition.role.value());
110 }
111 result += "}";
112 return result;
113}
114
116[[nodiscard]] inline std::string to_string(const MetatileAttributeFieldDefinitions &definitions)
117{
118 if (definitions.empty()) {
119 return "[]";
120 }
121 std::string result = "[";
122 bool first = true;
123 for (const auto &definition : definitions) {
124 if (!first) {
125 result += ", ";
126 }
127 result += to_string(definition);
128 first = false;
129 }
130 result += "]";
131 return result;
132}
133
134inline std::ostream &operator<<(std::ostream &os, const MetatileAttributeFieldDefinitions &definitions)
135{
136 return os << to_string(definitions);
137}
138
140[[nodiscard]] inline std::string to_string(const MetatileAttributeFieldOverride &override_value)
141{
142 std::string result = std::format(
143 "{{mask={}, default={}",
144 detail::format_optional_mask(override_value.mask),
146 if (override_value.provider.has_value()) {
147 if (override_value.provider->remove) {
148 result += ", provider=removed";
149 }
150 else {
151 result += ", provider=adjusted";
152 }
153 }
154 if (override_value.role.has_value()) {
155 if (override_value.role->has_value()) {
156 result += ", role=" + to_string(override_value.role->value());
157 }
158 else {
159 result += ", role=removed";
160 }
161 }
162 result += "}";
163 return result;
164}
165
167[[nodiscard]] inline std::string to_string(const MetatileAttributeFieldOverrides &overrides)
168{
169 if (overrides.empty()) {
170 return "{}";
171 }
172 std::string result = "{";
173 bool first = true;
174 for (const auto &[name, override_value] : overrides) {
175 if (!first) {
176 result += ", ";
177 }
178 result += name + "=" + to_string(override_value);
179 first = false;
180 }
181 result += "}";
182 return result;
183}
184
185inline std::ostream &operator<<(std::ostream &os, const MetatileAttributeFieldOverrides &overrides)
186{
187 return os << to_string(overrides);
188}
189
190} // namespace porytiles
191
192template <>
193struct std::formatter<porytiles::MetatileAttributeFieldDefinitions> {
194 constexpr auto parse(std::format_parse_context &ctx)
195 {
196 return ctx.begin();
197 }
198
199 auto format(const porytiles::MetatileAttributeFieldDefinitions &value, auto &ctx) const
200 {
201 return std::format_to(ctx.out(), "{}", porytiles::to_string(value));
202 }
203};
204
205template <>
206struct std::formatter<porytiles::MetatileAttributeFieldOverrides> {
207 constexpr auto parse(std::format_parse_context &ctx)
208 {
209 return ctx.begin();
210 }
211
212 auto format(const porytiles::MetatileAttributeFieldOverrides &value, auto &ctx) const
213 {
214 return std::format_to(ctx.out(), "{}", porytiles::to_string(value));
215 }
216};
std::string name
std::optional< ProviderDefinition > provider
std::string format_provider_definition(const ProviderDefinition &provider)
std::string format_optional_mask(const std::optional< std::uint32_t > &mask)
std::map< std::string, MetatileAttributeFieldOverride > MetatileAttributeFieldOverrides
A map from field name to its override; applied at schema load time.
std::vector< MetatileAttributeFieldDefinition > MetatileAttributeFieldDefinitions
An ordered list of metatile attribute field definitions; order is display/declaration order.
std::ostream & operator<<(std::ostream &os, const PrimaryPairingMode m)
Stream insertion operator for PrimaryPairingMode.
std::string to_string(const PrimaryPairingMode m)
Converts a PrimaryPairingMode to its canonical string representation.
A user-authored (or inferred) description of one metatile attribute field.
bool operator==(const MetatileAttributeFieldDefinition &) const =default
A partial override of a single field, merged additively onto a baseline definition.
bool operator==(const MetatileAttributeFieldOverride &) const =default
std::optional< ProviderDefinitionOverride > provider
A partial override of a field's provider definition.
std::optional< std::unordered_set< std::string > > skipped
bool operator==(const ProviderDefinitionOverride &) const =default
Describes where and how a field's named values are declared.
auto format(const porytiles::MetatileAttributeFieldDefinitions &value, auto &ctx) const
auto format(const porytiles::MetatileAttributeFieldOverrides &value, auto &ctx) const