14constexpr std::string_view kSeedKey =
"seed";
15constexpr std::string_view kWidthKey =
"width";
16constexpr std::string_view kHeightKey =
"height";
18void appendLength(std::string&
output, std::string_view
value) {
24std::string doubleToken(
double value) {
25 if (std::isnan(
value))
return "nan";
26 if (std::isinf(
value))
return std::signbit(
value) ?
"-inf" :
"+inf";
28 std::ostringstream stream;
29 stream.imbue(std::locale::classic());
30 stream.precision(std::numeric_limits<double>::max_digits10);
36 switch (
value.type()) {
42 const std::string&
text =
value.asString();
43 std::string result =
"string:";
44 appendLength(result,
text);
48 std::string result =
"array:";
50 result += std::to_string(array ? array->size() : 0);
51 result.push_back(
':');
54 const std::string encoded = canonicalValue(
element);
55 appendLength(result, encoded);
61 std::string result =
"object:";
63 result += std::to_string(
object ?
object->size() : 0);
64 result.push_back(
':');
67 appendLength(result,
key);
68 const std::string encoded = canonicalValue(
member);
69 appendLength(result, encoded);
80 return it ==
values.end() ? nullptr : &it->second;
84 if (
const auto* integer =
value.getIf<std::int64_t>()) {
85 if (*integer < std::numeric_limits<int>::lowest() || *integer > std::numeric_limits<int>::max())
87 return static_cast<int>(*integer);
89 if (
const auto*
boolean =
value.getIf<
bool>())
return *
boolean ? 1 : 0;
92 *
number <
static_cast<double>(std::numeric_limits<int>::lowest()) ||
93 *
number >
static_cast<double>(std::numeric_limits<int>::max()))
95 return static_cast<int>(*number);
101 if (
const auto*
boolean =
value.getIf<
bool>())
return *
boolean ? 1.f : 0.f;
102 if (
const auto* integer =
value.getIf<std::int64_t>()) {
103 const float converted =
static_cast<float>(*integer);
104 return std::isfinite(converted) ? std::optional<float>(converted) :
std::nullopt;
107 if (!std::isfinite(*
number))
return std::nullopt;
108 const float converted =
static_cast<float>(*number);
109 return std::isfinite(converted) ? std::optional<float>(converted) :
std::nullopt;
115 if (
const auto*
boolean =
value.getIf<
bool>())
return *
boolean;
116 if (
const auto* integer =
value.getIf<std::int64_t>()) {
117 if (*integer == 0)
return false;
118 if (*integer == 1)
return true;
122 if (!std::isfinite(*
number))
return std::nullopt;
123 if (*
number == 0.0)
return false;
124 if (*
number == 1.0)
return true;
130 appendLength(
output, domain);
132 const std::string encoded = canonicalValue(
value);
133 appendLength(
output, encoded);
150 if (
key == kSeedKey) {
151 seed_ =
static_cast<uint32_t
>(std::max(0,
value));
154 if (
key == kWidthKey) {
158 if (
key == kHeightKey) {
172 if (
key == kSeedKey ||
key == kWidthKey ||
key == kHeightKey)
return true;
173 return values_.find(
key) != values_.end();
177 if (
key == kSeedKey) {
178 return seed_ <= static_cast<uint32_t>(std::numeric_limits<int>::max()) ?
static_cast<int>(seed_) :
defaultValue;
180 if (
key == kWidthKey)
return width_;
181 if (
key == kHeightKey)
return height_;
184 const auto converted = asInt(*
value);
191 const auto converted = asFloat(*
value);
198 const auto converted = asBool(*
value);
205 const auto*
text =
value->getIf<std::string>();
210 std::string result =
"params:v2;";
213 appendField(result,
"dimension", kHeightKey,
eve::Value(
static_cast<std::int64_t
>(height_)));
214 appendField(result,
"dimension", kSeedKey,
eve::Value(
static_cast<std::int64_t
>(seed_)));
215 appendField(result,
"dimension", kWidthKey,
eve::Value(
static_cast<std::int64_t
>(width_)));
216 for (
const auto& [
key,
value] : values_) appendField(result,
"parameter",
key,
value);
std::map< std::string, Var > values
float(ui::Theme::* member)[4]
The canonical owning dynamic value used by data-facing protocols.
std::map< std::string, Value > Object
std::vector< Value > Array
Value * find(const std::string &key) noexcept
Return an object member, or nullptr when absent.
uint32_t getSeed() const
Return the deterministic generation seed.
void setSize(int width, int height)
Set the generation dimensions, clamping each non-positive value to one.
bool getBool(const std::string &key, bool defaultValue) const
Read a boolean parameter without parsing text.
void setInt(const std::string &key, int value)
Store an Int64 parameter, preserving its numeric Value kind.
int getHeight() const
Return the generation height.
int getWidth() const
Return the generation width.
void setBool(const std::string &key, bool value)
Stores a boolean generation parameter.
bool has(const std::string &key) const
Return whether a parameter or one of the three dimensions exists.
float getFloat(const std::string &key, float defaultValue) const
Read a floating parameter with explicit numeric conversion rules.
std::string canonicalString() const
Return a deterministic serialization of all generation parameters.
void setSeed(uint32_t seed)
Set the deterministic seed used by generation.
void setFloat(const std::string &key, float value)
Store a finite or non-finite floating parameter as Value::Double without text conversion.
std::string getString(const std::string &key, const std::string &defaultValue) const
Read only a Value::String parameter; numeric/bool values are not stringified.
int getInt(const std::string &key, int defaultValue) const
Read an integer parameter with explicit numeric conversion rules.
void setString(const std::string &key, const std::string &value)
Store an owning string parameter as Value::String.
const char * defaultValue