1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-10 13:00:37 +00:00

Allow indexing of String values in scripting languages

This commit is contained in:
George Marques
2021-09-17 16:02:21 -03:00
parent 424ddcba37
commit 262d9397fb
3 changed files with 165 additions and 0 deletions

View File

@@ -661,6 +661,91 @@ struct VariantIndexedSetGet_Array {
static uint64_t get_indexed_size(const Variant *base) { return 0; }
};
struct VariantIndexedSetGet_String {
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) {
int64_t length = VariantGetInternalPtr<String>::get_ptr(base)->length();
if (index < 0) {
index += length;
}
if (index < 0 || index >= length) {
*oob = true;
return;
}
char32_t result = (*VariantGetInternalPtr<String>::get_ptr(base))[index];
*value = String(&result, 1);
*oob = false;
}
static void ptr_get(const void *base, int64_t index, void *member) {
/* avoid ptrconvert for performance*/
const String &v = *reinterpret_cast<const String *>(base);
if (index < 0) {
index += v.length();
}
OOB_TEST(index, v.length());
char32_t c = v[index];
PtrToArg<String>::encode(String(&c, 1), member);
}
static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) {
if (value->get_type() != Variant::STRING) {
*oob = false;
*valid = false;
return;
}
int64_t length = VariantGetInternalPtr<String>::get_ptr(base)->length();
if (index < 0) {
index += length;
}
if (index < 0 || index >= length) {
*oob = true;
*valid = false;
return;
}
String *b = VariantGetInternalPtr<String>::get_ptr(base);
const String *v = VariantInternal::get_string(value);
if (v->length() == 0) {
b->remove(index);
} else {
b->set(index, v->get(0));
}
*oob = false;
*valid = true;
}
static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) {
int64_t length = VariantGetInternalPtr<String>::get_ptr(base)->length();
if (index < 0) {
index += length;
}
if (index < 0 || index >= length) {
*oob = true;
return;
}
String *b = VariantGetInternalPtr<String>::get_ptr(base);
const String *v = VariantInternal::get_string(value);
if (v->length() == 0) {
b->remove(index);
} else {
b->set(index, v->get(0));
}
*oob = false;
}
static void ptr_set(void *base, int64_t index, const void *member) {
/* avoid ptrconvert for performance*/
String &v = *reinterpret_cast<String *>(base);
if (index < 0) {
index += v.length();
}
OOB_TEST(index, v.length());
const String &m = *reinterpret_cast<const String *>(member);
if (unlikely(m.length() == 0)) {
v.remove(index);
} else {
v.set(index, m.unicode_at(0));
}
}
static Variant::Type get_index_type() { return Variant::STRING; }
static uint64_t get_indexed_size(const Variant *base) { return VariantInternal::get_string(base)->length(); }
};
#define INDEXED_SETGET_STRUCT_DICT(m_base_type) \
struct VariantIndexedSetGet_##m_base_type { \
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \
@@ -758,6 +843,7 @@ static void register_indexed_member(Variant::Type p_type) {
void register_indexed_setters_getters() {
#define REGISTER_INDEXED_MEMBER(m_base_type) register_indexed_member<VariantIndexedSetGet_##m_base_type>(GetTypeInfo<m_base_type>::VARIANT_TYPE)
REGISTER_INDEXED_MEMBER(String);
REGISTER_INDEXED_MEMBER(Vector2);
REGISTER_INDEXED_MEMBER(Vector2i);
REGISTER_INDEXED_MEMBER(Vector3);