Add %v for formatting vectors
This commit is contained in:
parent
0c5f254956
commit
dbc165715b
@ -4664,6 +4664,71 @@ String String::sprintf(const Array &values, bool *error) const {
|
|||||||
in_format = false;
|
in_format = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'v': { // Vector2/3/4/2i/3i/4i
|
||||||
|
if (value_index >= values.size()) {
|
||||||
|
return "not enough arguments for format string";
|
||||||
|
}
|
||||||
|
|
||||||
|
int count;
|
||||||
|
switch (values[value_index].get_type()) {
|
||||||
|
case Variant::VECTOR2:
|
||||||
|
case Variant::VECTOR2I: {
|
||||||
|
count = 2;
|
||||||
|
} break;
|
||||||
|
case Variant::VECTOR3:
|
||||||
|
case Variant::VECTOR3I: {
|
||||||
|
count = 3;
|
||||||
|
} break;
|
||||||
|
case Variant::VECTOR4:
|
||||||
|
case Variant::VECTOR4I: {
|
||||||
|
count = 4;
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
return "%v requires a vector type (Vector2/3/4/2i/3i/4i)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector4 vec = values[value_index];
|
||||||
|
String str = "(";
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
double val = vec[i];
|
||||||
|
// Pad decimals out.
|
||||||
|
String number_str = String::num(ABS(val), min_decimals).pad_decimals(min_decimals);
|
||||||
|
|
||||||
|
int initial_len = number_str.length();
|
||||||
|
|
||||||
|
// Padding. Leave room for sign later if required.
|
||||||
|
int pad_chars_count = val < 0 ? min_chars - 1 : min_chars;
|
||||||
|
String pad_char = pad_with_zeros ? String("0") : String(" ");
|
||||||
|
if (left_justified) {
|
||||||
|
number_str = number_str.rpad(pad_chars_count, pad_char);
|
||||||
|
} else {
|
||||||
|
number_str = number_str.lpad(pad_chars_count, pad_char);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add sign if needed.
|
||||||
|
if (val < 0) {
|
||||||
|
if (left_justified) {
|
||||||
|
number_str = number_str.insert(0, "-");
|
||||||
|
} else {
|
||||||
|
number_str = number_str.insert(pad_with_zeros ? 0 : number_str.length() - initial_len, "-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add number to combined string
|
||||||
|
str += number_str;
|
||||||
|
|
||||||
|
if (i < count - 1) {
|
||||||
|
str += ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str += ")";
|
||||||
|
|
||||||
|
formatted += str;
|
||||||
|
++value_index;
|
||||||
|
in_format = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 's': { // String
|
case 's': { // String
|
||||||
if (value_index >= values.size()) {
|
if (value_index >= values.size()) {
|
||||||
return "not enough arguments for format string";
|
return "not enough arguments for format string";
|
||||||
@ -4756,7 +4821,7 @@ String String::sprintf(const Array &values, bool *error) const {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '.': { // Float separator.
|
case '.': { // Float/Vector separator.
|
||||||
if (in_decimals) {
|
if (in_decimals) {
|
||||||
return "too many decimal points in format";
|
return "too many decimal points in format";
|
||||||
}
|
}
|
||||||
@ -4770,8 +4835,12 @@ String String::sprintf(const Array &values, bool *error) const {
|
|||||||
return "not enough arguments for format string";
|
return "not enough arguments for format string";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!values[value_index].is_num()) {
|
Variant::Type value_type = values[value_index].get_type();
|
||||||
return "* wants number";
|
if (!values[value_index].is_num() &&
|
||||||
|
value_type != Variant::VECTOR2 && value_type != Variant::VECTOR2I &&
|
||||||
|
value_type != Variant::VECTOR3 && value_type != Variant::VECTOR3I &&
|
||||||
|
value_type != Variant::VECTOR4 && value_type != Variant::VECTOR4I) {
|
||||||
|
return "* wants number or vector";
|
||||||
}
|
}
|
||||||
|
|
||||||
int size = values[value_index];
|
int size = values[value_index];
|
||||||
|
@ -803,6 +803,96 @@ TEST_CASE("[String] sprintf") {
|
|||||||
REQUIRE(error == false);
|
REQUIRE(error == false);
|
||||||
CHECK(output == String("fish -99.990000 frog"));
|
CHECK(output == String("fish -99.990000 frog"));
|
||||||
|
|
||||||
|
////// VECTORS
|
||||||
|
|
||||||
|
// Vector2
|
||||||
|
format = "fish %v frog";
|
||||||
|
args.clear();
|
||||||
|
args.push_back(Variant(Vector2(19.99, 1.00)));
|
||||||
|
output = format.sprintf(args, &error);
|
||||||
|
REQUIRE(error == false);
|
||||||
|
CHECK(output == String("fish (19.990000, 1.000000) frog"));
|
||||||
|
|
||||||
|
// Vector3
|
||||||
|
format = "fish %v frog";
|
||||||
|
args.clear();
|
||||||
|
args.push_back(Variant(Vector3(19.99, 1.00, -2.05)));
|
||||||
|
output = format.sprintf(args, &error);
|
||||||
|
REQUIRE(error == false);
|
||||||
|
CHECK(output == String("fish (19.990000, 1.000000, -2.050000) frog"));
|
||||||
|
|
||||||
|
// Vector4
|
||||||
|
format = "fish %v frog";
|
||||||
|
args.clear();
|
||||||
|
args.push_back(Variant(Vector4(19.99, 1.00, -2.05, 5.5)));
|
||||||
|
output = format.sprintf(args, &error);
|
||||||
|
REQUIRE(error == false);
|
||||||
|
CHECK(output == String("fish (19.990000, 1.000000, -2.050000, 5.500000) frog"));
|
||||||
|
|
||||||
|
// Vector with negative values
|
||||||
|
format = "fish %v frog";
|
||||||
|
args.clear();
|
||||||
|
args.push_back(Variant(Vector2(-19.99, -1.00)));
|
||||||
|
output = format.sprintf(args, &error);
|
||||||
|
REQUIRE(error == false);
|
||||||
|
CHECK(output == String("fish (-19.990000, -1.000000) frog"));
|
||||||
|
|
||||||
|
// Vector left-padded
|
||||||
|
format = "fish %11v frog";
|
||||||
|
args.clear();
|
||||||
|
args.push_back(Variant(Vector3(19.99, 1.00, -2.05)));
|
||||||
|
output = format.sprintf(args, &error);
|
||||||
|
REQUIRE(error == false);
|
||||||
|
CHECK(output == String("fish ( 19.990000, 1.000000, -2.050000) frog"));
|
||||||
|
|
||||||
|
// Vector right-padded
|
||||||
|
format = "fish %-11v frog";
|
||||||
|
args.clear();
|
||||||
|
args.push_back(Variant(Vector3(19.99, 1.00, -2.05)));
|
||||||
|
output = format.sprintf(args, &error);
|
||||||
|
REQUIRE(error == false);
|
||||||
|
CHECK(output == String("fish (19.990000 , 1.000000 , -2.050000 ) frog"));
|
||||||
|
|
||||||
|
// Vector left-padded with zeros
|
||||||
|
format = "fish %011v frog";
|
||||||
|
args.clear();
|
||||||
|
args.push_back(Variant(Vector3(19.99, 1.00, -2.05)));
|
||||||
|
output = format.sprintf(args, &error);
|
||||||
|
REQUIRE(error == false);
|
||||||
|
CHECK(output == String("fish (0019.990000, 0001.000000, -002.050000) frog"));
|
||||||
|
|
||||||
|
// Vector given Vector3i.
|
||||||
|
format = "fish %v frog";
|
||||||
|
args.clear();
|
||||||
|
args.push_back(Variant(Vector3i(19, 1, -2)));
|
||||||
|
output = format.sprintf(args, &error);
|
||||||
|
REQUIRE(error == false);
|
||||||
|
CHECK(output == String("fish (19.000000, 1.000000, -2.000000) frog"));
|
||||||
|
|
||||||
|
// Vector with 1 decimals.
|
||||||
|
format = "fish %.1v frog";
|
||||||
|
args.clear();
|
||||||
|
args.push_back(Variant(Vector3(19.99, 1.00, -2.05)));
|
||||||
|
output = format.sprintf(args, &error);
|
||||||
|
REQUIRE(error == false);
|
||||||
|
CHECK(output == String("fish (20.0, 1.0, -2.0) frog"));
|
||||||
|
|
||||||
|
// Vector with 12 decimals.
|
||||||
|
format = "fish %.12v frog";
|
||||||
|
args.clear();
|
||||||
|
args.push_back(Variant(Vector3(19.00, 1.00, -2.00)));
|
||||||
|
output = format.sprintf(args, &error);
|
||||||
|
REQUIRE(error == false);
|
||||||
|
CHECK(output == String("fish (19.000000000000, 1.000000000000, -2.000000000000) frog"));
|
||||||
|
|
||||||
|
// Vector with no decimals.
|
||||||
|
format = "fish %.v frog";
|
||||||
|
args.clear();
|
||||||
|
args.push_back(Variant(Vector3(19.99, 1.00, -2.05)));
|
||||||
|
output = format.sprintf(args, &error);
|
||||||
|
REQUIRE(error == false);
|
||||||
|
CHECK(output == String("fish (20, 1, -2) frog"));
|
||||||
|
|
||||||
/////// Strings.
|
/////// Strings.
|
||||||
|
|
||||||
// String
|
// String
|
||||||
@ -920,14 +1010,14 @@ TEST_CASE("[String] sprintf") {
|
|||||||
REQUIRE(error);
|
REQUIRE(error);
|
||||||
CHECK(output == "too many decimal points in format");
|
CHECK(output == "too many decimal points in format");
|
||||||
|
|
||||||
// * not a number
|
// * not a number or vector
|
||||||
format = "fish %*f frog";
|
format = "fish %*f frog";
|
||||||
args.clear();
|
args.clear();
|
||||||
args.push_back("cheese");
|
args.push_back("cheese");
|
||||||
args.push_back(99.99);
|
args.push_back(99.99);
|
||||||
output = format.sprintf(args, &error);
|
output = format.sprintf(args, &error);
|
||||||
REQUIRE(error);
|
REQUIRE(error);
|
||||||
CHECK(output == "* wants number");
|
CHECK(output == "* wants number or vector");
|
||||||
|
|
||||||
// Character too long.
|
// Character too long.
|
||||||
format = "fish %c frog";
|
format = "fish %c frog";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user