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

pull/896/head
Emmanuel Leblond 2022-10-22 13:46:59 +02:00
parent 73ad6717e9
commit 0e81f89dd3
No known key found for this signature in database
GPG Key ID: C360860E645EFFC0
4 changed files with 46 additions and 34 deletions

View File

@ -687,20 +687,24 @@ 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});" f"\t_method_bindings.destructor = internal::gdn_interface->variant_get_ptr_destructor({enum_type_name});"
) )
result.append(f"StringName __name;")
if "methods" in builtin_api: if "methods" in builtin_api:
for method in builtin_api["methods"]: for method in builtin_api["methods"]:
# TODO: Add error check for hash mismatch. # TODO: Add error check for hash mismatch.
result.append(f'\t__name = StringName("{method["name"]}");')
result.append( 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}, (void *)&__name, {method["hash"]});'
) )
if "members" in builtin_api: if "members" in builtin_api:
for member in builtin_api["members"]: for member in builtin_api["members"]:
result.append(f'\t__name = StringName("{member["name"]}");')
result.append( 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}, (void *)&__name);'
) )
result.append( 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}, (void *)&__name);'
) )
if "indexing_return_type" in builtin_api: if "indexing_return_type" in builtin_api:
@ -1292,8 +1296,9 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
if is_singleton: if is_singleton:
result.append(f"{class_name} *{class_name}::get_singleton() {{") result.append(f"{class_name} *{class_name}::get_singleton() {{")
result.append(f'\tconst StringName __class_name = {class_name}::get_class_static();')
result.append( 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((void *)&__class_name);"
) )
result.append("#ifdef DEBUG_ENABLED") result.append("#ifdef DEBUG_ENABLED")
result.append("\tERR_FAIL_COND_V(singleton_obj == nullptr, nullptr);") 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
result.append(method_signature + " {") result.append(method_signature + " {")
# Method body. # 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( 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((void *)&__class_name, (void *)&__method_name, {method["hash"]});'
) )
method_call = "\t" method_call = "\t"
has_return = "return_value" in method and method["return_value"]["type"] != "void" has_return = "return_value" in method and method["return_value"]["type"] != "void"
@ -1566,8 +1573,9 @@ def generate_utility_functions(api, output_dir):
# Function body. # Function body.
source.append(f'\tconst StringName __function_name = "{function["name"]}";')
source.append( 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((void *)&__function_name, {function["hash"]});'
) )
has_return = "return_type" in function and function["return_type"] != "void" has_return = "return_type" in function and function["return_type"] != "void"
if has_return: if has_return:

View File

@ -400,7 +400,7 @@ typedef struct {
void (*print_warning)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line); void (*print_warning)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line);
void (*print_script_error)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line); void (*print_script_error)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line);
uint64_t (*get_native_struct_size)(const char *p_name); uint64_t (*get_native_struct_size)(const GDNativeStringNamePtr p_name);
/* GODOT VARIANT */ /* GODOT VARIANT */
@ -443,19 +443,19 @@ typedef struct {
GDNativeVariantFromTypeConstructorFunc (*get_variant_from_type_constructor)(GDNativeVariantType p_type); GDNativeVariantFromTypeConstructorFunc (*get_variant_from_type_constructor)(GDNativeVariantType p_type);
GDNativeTypeFromVariantConstructorFunc (*get_variant_to_type_constructor)(GDNativeVariantType p_type); GDNativeTypeFromVariantConstructorFunc (*get_variant_to_type_constructor)(GDNativeVariantType p_type);
GDNativePtrOperatorEvaluator (*variant_get_ptr_operator_evaluator)(GDNativeVariantOperator p_operator, GDNativeVariantType p_type_a, GDNativeVariantType p_type_b); GDNativePtrOperatorEvaluator (*variant_get_ptr_operator_evaluator)(GDNativeVariantOperator p_operator, GDNativeVariantType p_type_a, GDNativeVariantType p_type_b);
GDNativePtrBuiltInMethod (*variant_get_ptr_builtin_method)(GDNativeVariantType p_type, const char *p_method, GDNativeInt p_hash); GDNativePtrBuiltInMethod (*variant_get_ptr_builtin_method)(GDNativeVariantType p_type, const GDNativeStringNamePtr p_method, GDNativeInt p_hash);
GDNativePtrConstructor (*variant_get_ptr_constructor)(GDNativeVariantType p_type, int32_t p_constructor); GDNativePtrConstructor (*variant_get_ptr_constructor)(GDNativeVariantType p_type, int32_t p_constructor);
GDNativePtrDestructor (*variant_get_ptr_destructor)(GDNativeVariantType p_type); GDNativePtrDestructor (*variant_get_ptr_destructor)(GDNativeVariantType p_type);
void (*variant_construct)(GDNativeVariantType p_type, GDNativeVariantPtr p_base, const GDNativeVariantPtr *p_args, int32_t p_argument_count, GDNativeCallError *r_error); void (*variant_construct)(GDNativeVariantType p_type, GDNativeVariantPtr p_base, const GDNativeVariantPtr *p_args, int32_t p_argument_count, GDNativeCallError *r_error);
GDNativePtrSetter (*variant_get_ptr_setter)(GDNativeVariantType p_type, const char *p_member); GDNativePtrSetter (*variant_get_ptr_setter)(GDNativeVariantType p_type, const GDNativeStringNamePtr p_member);
GDNativePtrGetter (*variant_get_ptr_getter)(GDNativeVariantType p_type, const char *p_member); GDNativePtrGetter (*variant_get_ptr_getter)(GDNativeVariantType p_type, const GDNativeStringNamePtr p_member);
GDNativePtrIndexedSetter (*variant_get_ptr_indexed_setter)(GDNativeVariantType p_type); GDNativePtrIndexedSetter (*variant_get_ptr_indexed_setter)(GDNativeVariantType p_type);
GDNativePtrIndexedGetter (*variant_get_ptr_indexed_getter)(GDNativeVariantType p_type); GDNativePtrIndexedGetter (*variant_get_ptr_indexed_getter)(GDNativeVariantType p_type);
GDNativePtrKeyedSetter (*variant_get_ptr_keyed_setter)(GDNativeVariantType p_type); GDNativePtrKeyedSetter (*variant_get_ptr_keyed_setter)(GDNativeVariantType p_type);
GDNativePtrKeyedGetter (*variant_get_ptr_keyed_getter)(GDNativeVariantType p_type); GDNativePtrKeyedGetter (*variant_get_ptr_keyed_getter)(GDNativeVariantType p_type);
GDNativePtrKeyedChecker (*variant_get_ptr_keyed_checker)(GDNativeVariantType p_type); GDNativePtrKeyedChecker (*variant_get_ptr_keyed_checker)(GDNativeVariantType p_type);
void (*variant_get_constant_value)(GDNativeVariantType p_type, const char *p_constant, GDNativeVariantPtr r_ret); void (*variant_get_constant_value)(GDNativeVariantType p_type, const GDNativeStringNamePtr p_constant, GDNativeVariantPtr r_ret);
GDNativePtrUtilityFunction (*variant_get_ptr_utility_function)(const char *p_function, GDNativeInt p_hash); GDNativePtrUtilityFunction (*variant_get_ptr_utility_function)(const GDNativeStringNamePtr p_function, GDNativeInt p_hash);
/* extra utilities */ /* extra utilities */
@ -524,12 +524,12 @@ typedef struct {
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); 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);
void (*object_method_bind_ptrcall)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret); void (*object_method_bind_ptrcall)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
void (*object_destroy)(GDNativeObjectPtr p_o); void (*object_destroy)(GDNativeObjectPtr p_o);
GDNativeObjectPtr (*global_get_singleton)(const char *p_name); GDNativeObjectPtr (*global_get_singleton)(const GDNativeStringNamePtr p_name);
void *(*object_get_instance_binding)(GDNativeObjectPtr p_o, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks); void *(*object_get_instance_binding)(GDNativeObjectPtr p_o, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks);
void (*object_set_instance_binding)(GDNativeObjectPtr p_o, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks); void (*object_set_instance_binding)(GDNativeObjectPtr p_o, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks);
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. */ 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. */
GDNativeObjectPtr (*object_cast_to)(const GDNativeObjectPtr p_object, void *p_class_tag); GDNativeObjectPtr (*object_cast_to)(const GDNativeObjectPtr p_object, void *p_class_tag);
GDNativeObjectPtr (*object_get_instance_from_id)(GDObjectInstanceID p_instance_id); GDNativeObjectPtr (*object_get_instance_from_id)(GDObjectInstanceID p_instance_id);
@ -540,9 +540,9 @@ typedef struct {
GDNativeScriptInstancePtr (*script_instance_create)(const GDNativeExtensionScriptInstanceInfo *p_info, GDNativeExtensionScriptInstanceDataPtr p_instance_data); GDNativeScriptInstancePtr (*script_instance_create)(const GDNativeExtensionScriptInstanceInfo *p_info, GDNativeExtensionScriptInstanceDataPtr p_instance_data);
/* CLASSDB */ /* CLASSDB */
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. */ 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. */
GDNativeMethodBindPtr (*classdb_get_method_bind)(const char *p_classname, const char *p_methodname, GDNativeInt p_hash); GDNativeMethodBindPtr (*classdb_get_method_bind)(const GDNativeStringNamePtr p_classname, const GDNativeStringNamePtr p_methodname, GDNativeInt p_hash);
void *(*classdb_get_class_tag)(const char *p_classname); void *(*classdb_get_class_tag)(const GDNativeStringNamePtr p_classname);
/* CLASSDB EXTENSION */ /* CLASSDB EXTENSION */

View File

@ -49,7 +49,7 @@ class Wrapped {
friend void postinitialize_handler(Wrapped *); friend void postinitialize_handler(Wrapped *);
protected: protected:
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. 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.
virtual const GDNativeInstanceBindingCallbacks *_get_bindings_callbacks() const = 0; virtual const GDNativeInstanceBindingCallbacks *_get_bindings_callbacks() const = 0;
void _notification(int p_what){}; void _notification(int p_what){};
@ -74,12 +74,13 @@ protected:
void _postinitialize(); void _postinitialize();
Wrapped(const char *p_godot_class); Wrapped(const StringName p_godot_class);
Wrapped(GodotObject *p_godot_object); Wrapped(GodotObject *p_godot_object);
public: public:
static const char *get_class_static() { static StringName get_class_static() {
return "Wrapped"; static StringName string_name = StringName("Wrapped");
return string_name;
} }
uint64_t get_instance_id() const { uint64_t get_instance_id() const {
@ -105,8 +106,9 @@ private:
friend class ::godot::ClassDB; \ friend class ::godot::ClassDB; \
\ \
protected: \ protected: \
virtual const char *_get_extension_class() const override { \ virtual const StringName *_get_extension_class() const override { \
return get_class_static(); \ static StringName string_name = get_class_static(); \
return &string_name; \
} \ } \
\ \
virtual const GDNativeInstanceBindingCallbacks *_get_bindings_callbacks() const override { \ virtual const GDNativeInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
@ -164,11 +166,12 @@ public:
initialized = true; \ initialized = true; \
} \ } \
\ \
static const char *get_class_static() { \ static StringName get_class_static() { \
return #m_class; \ static StringName string_name = StringName(#m_class); \
return string_name; \
} \ } \
\ \
static const char *get_parent_class_static() { \ static StringName *get_parent_class_static() { \
return m_inherits::get_class_static(); \ return m_inherits::get_class_static(); \
} \ } \
\ \
@ -357,11 +360,12 @@ protected:
public: \ public: \
static void initialize_class() {} \ static void initialize_class() {} \
\ \
static const char *get_class_static() { \ static StringName get_class_static() { \
return #m_class; \ static StringName string_name = StringName(#m_class); \
return string_name; \
} \ } \
\ \
static const char *get_parent_class_static() { \ static StringName get_parent_class_static() { \
return m_inherits::get_class_static(); \ return m_inherits::get_class_static(); \
} \ } \
\ \

View File

@ -36,20 +36,20 @@
namespace godot { namespace godot {
const char *Wrapped::_get_extension_class() const { const StringName *Wrapped::_get_extension_class() const {
return nullptr; return nullptr;
} }
void Wrapped::_postinitialize() { void Wrapped::_postinitialize() {
const char *extension_class = _get_extension_class(); const StringName *extension_class = _get_extension_class();
if (extension_class) { if (extension_class) {
godot::internal::gdn_interface->object_set_instance(_owner, extension_class, this); godot::internal::gdn_interface->object_set_instance(_owner, (void *)extension_class, this);
} }
godot::internal::gdn_interface->object_set_instance_binding(_owner, godot::internal::token, this, _get_bindings_callbacks()); godot::internal::gdn_interface->object_set_instance_binding(_owner, godot::internal::token, this, _get_bindings_callbacks());
} }
Wrapped::Wrapped(const char *p_godot_class) { Wrapped::Wrapped(const StringName p_godot_class) {
_owner = godot::internal::gdn_interface->classdb_construct_object(p_godot_class); _owner = godot::internal::gdn_interface->classdb_construct_object((void *)&p_godot_class);
} }
Wrapped::Wrapped(GodotObject *p_godot_object) { Wrapped::Wrapped(GodotObject *p_godot_object) {