Skip to content

Commit f79da6e

Browse files
committed
Uses StringName in GDExtension perf critical instance creation & method/properties setter/getter
1 parent adf4802 commit f79da6e

File tree

4 files changed

+46
-34
lines changed

4 files changed

+46
-34
lines changed

binding_generator.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -687,20 +687,24 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
687687
f"\t_method_bindings.destructor = internal::gdn_interface->variant_get_ptr_destructor({enum_type_name});"
688688
)
689689

690+
result.append(f"StringName __name;")
691+
690692
if "methods" in builtin_api:
691693
for method in builtin_api["methods"]:
692694
# TODO: Add error check for hash mismatch.
695+
result.append(f'\t__name = StringName("{method["name"]}");')
693696
result.append(
694-
f'\t_method_bindings.method_{method["name"]} = internal::gdn_interface->variant_get_ptr_builtin_method({enum_type_name}, "{method["name"]}", {method["hash"]});'
697+
f'\t_method_bindings.method_{method["name"]} = internal::gdn_interface->variant_get_ptr_builtin_method({enum_type_name}, (void *)&__name, {method["hash"]});'
695698
)
696699

697700
if "members" in builtin_api:
698701
for member in builtin_api["members"]:
702+
result.append(f'\t__name = StringName("{member["name"]}");')
699703
result.append(
700-
f'\t_method_bindings.member_{member["name"]}_setter = internal::gdn_interface->variant_get_ptr_setter({enum_type_name}, "{member["name"]}");'
704+
f'\t_method_bindings.member_{member["name"]}_setter = internal::gdn_interface->variant_get_ptr_setter({enum_type_name}, (void *)&__name);'
701705
)
702706
result.append(
703-
f'\t_method_bindings.member_{member["name"]}_getter = internal::gdn_interface->variant_get_ptr_getter({enum_type_name}, "{member["name"]}");'
707+
f'\t_method_bindings.member_{member["name"]}_getter = internal::gdn_interface->variant_get_ptr_getter({enum_type_name}, (void *)&__name);'
704708
)
705709

706710
if "indexing_return_type" in builtin_api:
@@ -1292,8 +1296,9 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
12921296

12931297
if is_singleton:
12941298
result.append(f"{class_name} *{class_name}::get_singleton() {{")
1299+
result.append(f'\tconst StringName __class_name = {class_name}::get_class_static();')
12951300
result.append(
1296-
f'\tstatic GDNativeObjectPtr singleton_obj = internal::gdn_interface->global_get_singleton("{class_name}");'
1301+
f"\tstatic GDNativeObjectPtr singleton_obj = internal::gdn_interface->global_get_singleton((void *)&__class_name);"
12971302
)
12981303
result.append("#ifdef DEBUG_ENABLED")
12991304
result.append("\tERR_FAIL_COND_V(singleton_obj == nullptr, nullptr);")
@@ -1318,8 +1323,10 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
13181323
result.append(method_signature + " {")
13191324

13201325
# Method body.
1326+
result.append(f'\tconst StringName __class_name = {class_name}::get_class_static();')
1327+
result.append(f'\tconst StringName __method_name = "{method["name"]}";')
13211328
result.append(
1322-
f'\tstatic GDNativeMethodBindPtr ___method_bind = internal::gdn_interface->classdb_get_method_bind("{class_name}", "{method["name"]}", {method["hash"]});'
1329+
f'\tstatic GDNativeMethodBindPtr ___method_bind = internal::gdn_interface->classdb_get_method_bind((void *)&__class_name, (void *)&__method_name, {method["hash"]});'
13231330
)
13241331
method_call = "\t"
13251332
has_return = "return_value" in method and method["return_value"]["type"] != "void"
@@ -1566,8 +1573,9 @@ def generate_utility_functions(api, output_dir):
15661573

15671574
# Function body.
15681575

1576+
source.append(f'\tconst StringName __function_name = "{function["name"]}";')
15691577
source.append(
1570-
f'\tstatic GDNativePtrUtilityFunction ___function = internal::gdn_interface->variant_get_ptr_utility_function("{function["name"]}", {function["hash"]});'
1578+
f'\tstatic GDNativePtrUtilityFunction ___function = internal::gdn_interface->variant_get_ptr_utility_function((void *)&__function_name, {function["hash"]});'
15711579
)
15721580
has_return = "return_type" in function and function["return_type"] != "void"
15731581
if has_return:

godot-headers/godot/gdnative_interface.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ typedef struct {
400400
void (*print_warning)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line);
401401
void (*print_script_error)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line);
402402

403-
uint64_t (*get_native_struct_size)(const char *p_name);
403+
uint64_t (*get_native_struct_size)(const GDNativeStringNamePtr p_name);
404404

405405
/* GODOT VARIANT */
406406

@@ -443,19 +443,19 @@ typedef struct {
443443
GDNativeVariantFromTypeConstructorFunc (*get_variant_from_type_constructor)(GDNativeVariantType p_type);
444444
GDNativeTypeFromVariantConstructorFunc (*get_variant_to_type_constructor)(GDNativeVariantType p_type);
445445
GDNativePtrOperatorEvaluator (*variant_get_ptr_operator_evaluator)(GDNativeVariantOperator p_operator, GDNativeVariantType p_type_a, GDNativeVariantType p_type_b);
446-
GDNativePtrBuiltInMethod (*variant_get_ptr_builtin_method)(GDNativeVariantType p_type, const char *p_method, GDNativeInt p_hash);
446+
GDNativePtrBuiltInMethod (*variant_get_ptr_builtin_method)(GDNativeVariantType p_type, const GDNativeStringNamePtr p_method, GDNativeInt p_hash);
447447
GDNativePtrConstructor (*variant_get_ptr_constructor)(GDNativeVariantType p_type, int32_t p_constructor);
448448
GDNativePtrDestructor (*variant_get_ptr_destructor)(GDNativeVariantType p_type);
449449
void (*variant_construct)(GDNativeVariantType p_type, GDNativeVariantPtr p_base, const GDNativeVariantPtr *p_args, int32_t p_argument_count, GDNativeCallError *r_error);
450-
GDNativePtrSetter (*variant_get_ptr_setter)(GDNativeVariantType p_type, const char *p_member);
451-
GDNativePtrGetter (*variant_get_ptr_getter)(GDNativeVariantType p_type, const char *p_member);
450+
GDNativePtrSetter (*variant_get_ptr_setter)(GDNativeVariantType p_type, const GDNativeStringNamePtr p_member);
451+
GDNativePtrGetter (*variant_get_ptr_getter)(GDNativeVariantType p_type, const GDNativeStringNamePtr p_member);
452452
GDNativePtrIndexedSetter (*variant_get_ptr_indexed_setter)(GDNativeVariantType p_type);
453453
GDNativePtrIndexedGetter (*variant_get_ptr_indexed_getter)(GDNativeVariantType p_type);
454454
GDNativePtrKeyedSetter (*variant_get_ptr_keyed_setter)(GDNativeVariantType p_type);
455455
GDNativePtrKeyedGetter (*variant_get_ptr_keyed_getter)(GDNativeVariantType p_type);
456456
GDNativePtrKeyedChecker (*variant_get_ptr_keyed_checker)(GDNativeVariantType p_type);
457-
void (*variant_get_constant_value)(GDNativeVariantType p_type, const char *p_constant, GDNativeVariantPtr r_ret);
458-
GDNativePtrUtilityFunction (*variant_get_ptr_utility_function)(const char *p_function, GDNativeInt p_hash);
457+
void (*variant_get_constant_value)(GDNativeVariantType p_type, const GDNativeStringNamePtr p_constant, GDNativeVariantPtr r_ret);
458+
GDNativePtrUtilityFunction (*variant_get_ptr_utility_function)(const GDNativeStringNamePtr p_function, GDNativeInt p_hash);
459459

460460
/* extra utilities */
461461

@@ -524,12 +524,12 @@ typedef struct {
524524
void (*object_method_bind_call)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeVariantPtr *p_args, GDNativeInt p_arg_count, GDNativeVariantPtr r_ret, GDNativeCallError *r_error);
525525
void (*object_method_bind_ptrcall)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
526526
void (*object_destroy)(GDNativeObjectPtr p_o);
527-
GDNativeObjectPtr (*global_get_singleton)(const char *p_name);
527+
GDNativeObjectPtr (*global_get_singleton)(const GDNativeStringNamePtr p_name);
528528

529529
void *(*object_get_instance_binding)(GDNativeObjectPtr p_o, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks);
530530
void (*object_set_instance_binding)(GDNativeObjectPtr p_o, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks);
531531

532-
void (*object_set_instance)(GDNativeObjectPtr p_o, const char *p_classname, GDExtensionClassInstancePtr p_instance); /* p_classname should be a registered extension class and should extend the p_o object's class. */
532+
void (*object_set_instance)(GDNativeObjectPtr p_o, const GDNativeStringNamePtr p_classname, GDExtensionClassInstancePtr p_instance); /* p_classname should be a registered extension class and should extend the p_o object's class. */
533533

534534
GDNativeObjectPtr (*object_cast_to)(const GDNativeObjectPtr p_object, void *p_class_tag);
535535
GDNativeObjectPtr (*object_get_instance_from_id)(GDObjectInstanceID p_instance_id);
@@ -540,9 +540,9 @@ typedef struct {
540540
GDNativeScriptInstancePtr (*script_instance_create)(const GDNativeExtensionScriptInstanceInfo *p_info, GDNativeExtensionScriptInstanceDataPtr p_instance_data);
541541

542542
/* CLASSDB */
543-
GDNativeObjectPtr (*classdb_construct_object)(const char *p_classname); /* The passed class must be a built-in godot class, or an already-registered extension class. In both case, object_set_instance should be called to fully initialize the object. */
544-
GDNativeMethodBindPtr (*classdb_get_method_bind)(const char *p_classname, const char *p_methodname, GDNativeInt p_hash);
545-
void *(*classdb_get_class_tag)(const char *p_classname);
543+
GDNativeObjectPtr (*classdb_construct_object)(const GDNativeStringNamePtr p_classname); /* The passed class must be a built-in godot class, or an already-registered extension class. In both case, object_set_instance should be called to fully initialize the object. */
544+
GDNativeMethodBindPtr (*classdb_get_method_bind)(const GDNativeStringNamePtr p_classname, const GDNativeStringNamePtr p_methodname, GDNativeInt p_hash);
545+
void *(*classdb_get_class_tag)(const GDNativeStringNamePtr p_classname);
546546

547547
/* CLASSDB EXTENSION */
548548

include/godot_cpp/classes/wrapped.hpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class Wrapped {
4949
friend void postinitialize_handler(Wrapped *);
5050

5151
protected:
52-
virtual const char *_get_extension_class() const; // This is needed to retrieve the class name before the godot object has its _extension and _extension_instance members assigned.
52+
virtual const StringName *_get_extension_class() const; // This is needed to retrieve the class name before the godot object has its _extension and _extension_instance members assigned.
5353
virtual const GDNativeInstanceBindingCallbacks *_get_bindings_callbacks() const = 0;
5454

5555
void _notification(int p_what){};
@@ -74,12 +74,13 @@ class Wrapped {
7474

7575
void _postinitialize();
7676

77-
Wrapped(const char *p_godot_class);
77+
Wrapped(const StringName p_godot_class);
7878
Wrapped(GodotObject *p_godot_object);
7979

8080
public:
81-
static const char *get_class_static() {
82-
return "Wrapped";
81+
static StringName get_class_static() {
82+
static StringName string_name = StringName("Wrapped");
83+
return string_name;
8384
}
8485

8586
uint64_t get_instance_id() const {
@@ -105,8 +106,9 @@ private:
105106
friend class ::godot::ClassDB; \
106107
\
107108
protected: \
108-
virtual const char *_get_extension_class() const override { \
109-
return get_class_static(); \
109+
virtual const StringName *_get_extension_class() const override { \
110+
static StringName string_name = get_class_static(); \
111+
return &string_name; \
110112
} \
111113
\
112114
virtual const GDNativeInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
@@ -164,11 +166,12 @@ public:
164166
initialized = true; \
165167
} \
166168
\
167-
static const char *get_class_static() { \
168-
return #m_class; \
169+
static StringName get_class_static() { \
170+
static StringName string_name = StringName(#m_class); \
171+
return string_name; \
169172
} \
170173
\
171-
static const char *get_parent_class_static() { \
174+
static StringName *get_parent_class_static() { \
172175
return m_inherits::get_class_static(); \
173176
} \
174177
\
@@ -357,11 +360,12 @@ protected:
357360
public: \
358361
static void initialize_class() {} \
359362
\
360-
static const char *get_class_static() { \
361-
return #m_class; \
363+
static StringName get_class_static() { \
364+
static StringName string_name = StringName(#m_class); \
365+
return string_name; \
362366
} \
363367
\
364-
static const char *get_parent_class_static() { \
368+
static StringName get_parent_class_static() { \
365369
return m_inherits::get_class_static(); \
366370
} \
367371
\

src/classes/wrapped.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,20 @@
3636

3737
namespace godot {
3838

39-
const char *Wrapped::_get_extension_class() const {
39+
const StringName *Wrapped::_get_extension_class() const {
4040
return nullptr;
4141
}
4242

4343
void Wrapped::_postinitialize() {
44-
const char *extension_class = _get_extension_class();
44+
const StringName *extension_class = _get_extension_class();
4545
if (extension_class) {
46-
godot::internal::gdn_interface->object_set_instance(_owner, extension_class, this);
46+
godot::internal::gdn_interface->object_set_instance(_owner, (void *)extension_class, this);
4747
}
4848
godot::internal::gdn_interface->object_set_instance_binding(_owner, godot::internal::token, this, _get_bindings_callbacks());
4949
}
5050

51-
Wrapped::Wrapped(const char *p_godot_class) {
52-
_owner = godot::internal::gdn_interface->classdb_construct_object(p_godot_class);
51+
Wrapped::Wrapped(const StringName p_godot_class) {
52+
_owner = godot::internal::gdn_interface->classdb_construct_object((void *)&p_godot_class);
5353
}
5454

5555
Wrapped::Wrapped(GodotObject *p_godot_object) {

0 commit comments

Comments
 (0)