From 8bc1c1dbeb0342ae593c46c97e7032bbc664194c Mon Sep 17 00:00:00 2001 From: David Snopek Date: Fri, 7 Jul 2023 08:26:55 -0500 Subject: [PATCH] Implement `String::resize()` --- binding_generator.py | 2 ++ gdextension/gdextension_interface.h | 19 +++++++++++++++++++ include/godot_cpp/godot.hpp | 1 + src/godot.cpp | 2 ++ src/variant/char_string.cpp | 4 ++++ test/project/main.gd | 3 +++ test/src/example.cpp | 11 +++++++++++ test/src/example.h | 1 + 8 files changed, 43 insertions(+) diff --git a/binding_generator.py b/binding_generator.py index 6e47e7bc..0a6580ed 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -366,6 +366,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl if class_name == "String": result.append("#include ") result.append("#include ") + result.append("#include ") if class_name == "PackedStringArray": result.append("#include ") @@ -552,6 +553,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl result.append("\tChar32String utf32() const;") result.append("\tCharWideString wide_string() const;") result.append("\tstatic String num_real(double p_num, bool p_trailing = true);") + result.append("\tError resize(int p_size);") if "members" in builtin_api: for member in builtin_api["members"]: diff --git a/gdextension/gdextension_interface.h b/gdextension/gdextension_interface.h index 43931cc8..6c05f398 100644 --- a/gdextension/gdextension_interface.h +++ b/gdextension/gdextension_interface.h @@ -1526,6 +1526,25 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqWcstr)(GDExtensionStringP */ typedef void (*GDExtensionInterfaceStringOperatorPlusEqC32str)(GDExtensionStringPtr p_self, const char32_t *p_b); +/** + * @name string_resize + * @since 4.2 + * + * Resizes the underlying string data to the given number of characters. + * + * Space needs to be allocated for the null terminating character ('\0') which + * also must be added manually, in order for all string functions to work correctly. + * + * Warning: This is an error-prone operation - only use it if there's no other + * efficient way to accomplish your goal. + * + * @param p_self A pointer to the String. + * @param p_resize The new length for the String. + * + * @return Error code signifying if the operation successful. + */ +typedef GDExtensionInt (*GDExtensionInterfaceStringResize)(GDExtensionStringPtr p_self, GDExtensionInt p_resize); + /* INTERFACE: XMLParser Utilities */ /** diff --git a/include/godot_cpp/godot.hpp b/include/godot_cpp/godot.hpp index 59aa1504..fb89b556 100644 --- a/include/godot_cpp/godot.hpp +++ b/include/godot_cpp/godot.hpp @@ -123,6 +123,7 @@ extern "C" GDExtensionInterfaceStringOperatorPlusEqChar gdextension_interface_st extern "C" GDExtensionInterfaceStringOperatorPlusEqCstr gdextension_interface_string_operator_plus_eq_cstr; extern "C" GDExtensionInterfaceStringOperatorPlusEqWcstr gdextension_interface_string_operator_plus_eq_wcstr; extern "C" GDExtensionInterfaceStringOperatorPlusEqC32str gdextension_interface_string_operator_plus_eq_c32str; +extern "C" GDExtensionInterfaceStringResize gdextension_interface_string_resize; extern "C" GDExtensionInterfaceXmlParserOpenBuffer gdextension_interface_xml_parser_open_buffer; extern "C" GDExtensionInterfaceFileAccessStoreBuffer gdextension_interface_file_access_store_buffer; extern "C" GDExtensionInterfaceFileAccessGetBuffer gdextension_interface_file_access_get_buffer; diff --git a/src/godot.cpp b/src/godot.cpp index c85667f3..4a92fad9 100644 --- a/src/godot.cpp +++ b/src/godot.cpp @@ -128,6 +128,7 @@ GDExtensionInterfaceStringOperatorPlusEqChar gdextension_interface_string_operat GDExtensionInterfaceStringOperatorPlusEqCstr gdextension_interface_string_operator_plus_eq_cstr = nullptr; GDExtensionInterfaceStringOperatorPlusEqWcstr gdextension_interface_string_operator_plus_eq_wcstr = nullptr; GDExtensionInterfaceStringOperatorPlusEqC32str gdextension_interface_string_operator_plus_eq_c32str = nullptr; +GDExtensionInterfaceStringResize gdextension_interface_string_resize = nullptr; GDExtensionInterfaceXmlParserOpenBuffer gdextension_interface_xml_parser_open_buffer = nullptr; GDExtensionInterfaceFileAccessStoreBuffer gdextension_interface_file_access_store_buffer = nullptr; GDExtensionInterfaceFileAccessGetBuffer gdextension_interface_file_access_get_buffer = nullptr; @@ -311,6 +312,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge LOAD_PROC_ADDRESS(string_operator_plus_eq_cstr, GDExtensionInterfaceStringOperatorPlusEqCstr); LOAD_PROC_ADDRESS(string_operator_plus_eq_wcstr, GDExtensionInterfaceStringOperatorPlusEqWcstr); LOAD_PROC_ADDRESS(string_operator_plus_eq_c32str, GDExtensionInterfaceStringOperatorPlusEqC32str); + LOAD_PROC_ADDRESS(string_resize, GDExtensionInterfaceStringResize); LOAD_PROC_ADDRESS(xml_parser_open_buffer, GDExtensionInterfaceXmlParserOpenBuffer); LOAD_PROC_ADDRESS(file_access_store_buffer, GDExtensionInterfaceFileAccessStoreBuffer); LOAD_PROC_ADDRESS(file_access_get_buffer, GDExtensionInterfaceFileAccessGetBuffer); diff --git a/src/variant/char_string.cpp b/src/variant/char_string.cpp index 856037c4..fc8845e8 100644 --- a/src/variant/char_string.cpp +++ b/src/variant/char_string.cpp @@ -289,6 +289,10 @@ CharWideString String::wide_string() const { return str; } +Error String::resize(int p_size) { + return (Error)internal::gdextension_interface_string_resize(_native_ptr(), p_size); +} + String &String::operator=(const char *p_str) { *this = String(p_str); return *this; diff --git a/test/project/main.gd b/test/project/main.gd index cedd5124..9716bc06 100644 --- a/test/project/main.gd +++ b/test/project/main.gd @@ -86,6 +86,9 @@ func _ready(): assert_equal(example.test_string_is_fourty_two("blah"), false) assert_equal(example.test_string_is_fourty_two("fourty two"), true) + # String::resize(). + assert_equal(example.test_string_resize("What"), "What!?") + # PackedArray iterators assert_equal(example.test_vector_ops(), 105) diff --git a/test/src/example.cpp b/test/src/example.cpp index fb47dd8d..af3837a1 100644 --- a/test/src/example.cpp +++ b/test/src/example.cpp @@ -139,6 +139,7 @@ void Example::_bind_methods() { ClassDB::bind_method(D_METHOD("test_string_ops"), &Example::test_string_ops); ClassDB::bind_method(D_METHOD("test_str_utility"), &Example::test_str_utility); ClassDB::bind_method(D_METHOD("test_string_is_fourty_two"), &Example::test_string_is_fourty_two); + ClassDB::bind_method(D_METHOD("test_string_resize"), &Example::test_string_resize); ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_ops); ClassDB::bind_method(D_METHOD("test_bitfield", "flags"), &Example::test_bitfield); @@ -304,6 +305,16 @@ bool Example::test_string_is_fourty_two(const String &p_string) const { return strcmp(p_string.utf8().ptr(), "fourty two") == 0; } +String Example::test_string_resize(String p_string) const { + int orig_len = p_string.length(); + p_string.resize(orig_len + 3); + char32_t *data = p_string.ptrw(); + data[orig_len + 0] = '!'; + data[orig_len + 1] = '?'; + data[orig_len + 2] = '\0'; + return p_string; +} + int Example::test_vector_ops() const { PackedInt32Array arr; arr.push_back(10); diff --git a/test/src/example.h b/test/src/example.h index a84efedc..ce64c31f 100644 --- a/test/src/example.h +++ b/test/src/example.h @@ -118,6 +118,7 @@ public: String test_string_ops() const; String test_str_utility() const; bool test_string_is_fourty_two(const String &p_str) const; + String test_string_resize(String p_original) const; int test_vector_ops() const; BitField test_bitfield(BitField flags);