Skip to content

Uses StringName in GDExtension perf critical instance creation & method/properties setter/getter #896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
41 changes: 31 additions & 10 deletions binding_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,12 +394,11 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append(f"class {class_name} {{")
result.append(f"\tstatic constexpr size_t {snake_class_name}_SIZE = {size};")
result.append(f"\tuint8_t opaque[{snake_class_name}_SIZE] = {{}};")
result.append(
f"\t_FORCE_INLINE_ GDNativeTypePtr _native_ptr() const {{ return const_cast<uint8_t (*)[{snake_class_name}_SIZE]>(&opaque); }}"
)

result.append("")
result.append("\tfriend class Variant;")
if class_name == "String":
result.append("\tfriend class StringName;")

result.append("")
result.append("\tstatic struct _MethodBindings {")
Expand Down Expand Up @@ -442,10 +441,15 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl

result.append("")
result.append("\tstatic void init_bindings();")
result.append("\tstatic void _init_bindings_constructors_destructor();")

result.append("")
result.append("public:")

result.append(
f"\t_FORCE_INLINE_ GDNativeTypePtr _native_ptr() const {{ return const_cast<uint8_t (*)[{snake_class_name}_SIZE]>(&opaque); }}"
)

copy_constructor_index = -1

if "constructors" in builtin_api:
Expand Down Expand Up @@ -674,7 +678,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append(f"{class_name}::_MethodBindings {class_name}::_method_bindings;")
result.append("")

result.append(f"void {class_name}::init_bindings() {{")
result.append(f"void {class_name}::_init_bindings_constructors_destructor() {{")

if "constructors" in builtin_api:
for constructor in builtin_api["constructors"]:
Expand All @@ -687,20 +691,33 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
f"\t_method_bindings.destructor = internal::gdn_interface->variant_get_ptr_destructor({enum_type_name});"
)

result.append("}")

result.append(f"void {class_name}::init_bindings() {{")

# StringName's constructor internally uses String, so it constructor must be ready !
if class_name == "StringName":
result.append(f"\tString::_init_bindings_constructors_destructor();")
result.append(f"\t{class_name}::_init_bindings_constructors_destructor();")

result.append(f"\tStringName __name;")

if "methods" in builtin_api:
for method in builtin_api["methods"]:
# TODO: Add error check for hash mismatch.
result.append(f'\t__name = StringName("{method["name"]}");')
result.append(
f'\t_method_bindings.method_{method["name"]} = internal::gdn_interface->variant_get_ptr_builtin_method({enum_type_name}, "{method["name"]}", {method["hash"]});'
f'\t_method_bindings.method_{method["name"]} = internal::gdn_interface->variant_get_ptr_builtin_method({enum_type_name}, __name._native_ptr(), {method["hash"]});'
)

if "members" in builtin_api:
for member in builtin_api["members"]:
result.append(f'\t__name = StringName("{member["name"]}");')
result.append(
f'\t_method_bindings.member_{member["name"]}_setter = internal::gdn_interface->variant_get_ptr_setter({enum_type_name}, "{member["name"]}");'
f'\t_method_bindings.member_{member["name"]}_setter = internal::gdn_interface->variant_get_ptr_setter({enum_type_name}, __name._native_ptr());'
)
result.append(
f'\t_method_bindings.member_{member["name"]}_getter = internal::gdn_interface->variant_get_ptr_getter({enum_type_name}, "{member["name"]}");'
f'\t_method_bindings.member_{member["name"]}_getter = internal::gdn_interface->variant_get_ptr_getter({enum_type_name}, __name._native_ptr());'
)

if "indexing_return_type" in builtin_api:
Expand Down Expand Up @@ -1292,8 +1309,9 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us

if is_singleton:
result.append(f"{class_name} *{class_name}::get_singleton() {{")
result.append(f"\tconst StringName __class_name = {class_name}::get_class_static();")
result.append(
f'\tstatic GDNativeObjectPtr singleton_obj = internal::gdn_interface->global_get_singleton("{class_name}");'
f"\tstatic GDNativeObjectPtr singleton_obj = internal::gdn_interface->global_get_singleton(__class_name._native_ptr());"
)
result.append("#ifdef DEBUG_ENABLED")
result.append("\tERR_FAIL_COND_V(singleton_obj == nullptr, nullptr);")
Expand All @@ -1318,8 +1336,10 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result.append(method_signature + " {")

# Method body.
result.append(f"\tconst StringName __class_name = {class_name}::get_class_static();")
result.append(f'\tconst StringName __method_name = "{method["name"]}";')
result.append(
f'\tstatic GDNativeMethodBindPtr ___method_bind = internal::gdn_interface->classdb_get_method_bind("{class_name}", "{method["name"]}", {method["hash"]});'
f'\tstatic GDNativeMethodBindPtr ___method_bind = internal::gdn_interface->classdb_get_method_bind(__class_name._native_ptr(), __method_name._native_ptr(), {method["hash"]});'
)
method_call = "\t"
has_return = "return_value" in method and method["return_value"]["type"] != "void"
Expand Down Expand Up @@ -1566,8 +1586,9 @@ def generate_utility_functions(api, output_dir):

# Function body.

source.append(f'\tconst StringName __function_name = "{function["name"]}";')
source.append(
f'\tstatic GDNativePtrUtilityFunction ___function = internal::gdn_interface->variant_get_ptr_utility_function("{function["name"]}", {function["hash"]});'
f'\tstatic GDNativePtrUtilityFunction ___function = internal::gdn_interface->variant_get_ptr_utility_function(__function_name._native_ptr(), {function["hash"]});'
)
has_return = "return_type" in function and function["return_type"] != "void"
if has_return:
Expand Down
2 changes: 1 addition & 1 deletion godot-headers/extension_api.json
Original file line number Diff line number Diff line change
Expand Up @@ -264388,4 +264388,4 @@
"format": "StringName signature;uint64_t call_count;uint64_t total_time;uint64_t self_time"
}
]
}
}
Loading