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});"
)
result.append(f"StringName __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}, (void *)&__name, {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}, (void *)&__name);'
)
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:
@ -1292,8 +1296,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((void *)&__class_name);"
)
result.append("#ifdef DEBUG_ENABLED")
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 + " {")
# 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((void *)&__class_name, (void *)&__method_name, {method["hash"]});'
)
method_call = "\t"
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.
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((void *)&__function_name, {function["hash"]});'
)
has_return = "return_type" in function and function["return_type"] != "void"
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_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 */
@ -443,19 +443,19 @@ typedef struct {
GDNativeVariantFromTypeConstructorFunc (*get_variant_from_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);
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);
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);
GDNativePtrSetter (*variant_get_ptr_setter)(GDNativeVariantType p_type, const char *p_member);
GDNativePtrGetter (*variant_get_ptr_getter)(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 GDNativeStringNamePtr p_member);
GDNativePtrIndexedSetter (*variant_get_ptr_indexed_setter)(GDNativeVariantType p_type);
GDNativePtrIndexedGetter (*variant_get_ptr_indexed_getter)(GDNativeVariantType p_type);
GDNativePtrKeyedSetter (*variant_get_ptr_keyed_setter)(GDNativeVariantType p_type);
GDNativePtrKeyedGetter (*variant_get_ptr_keyed_getter)(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);
GDNativePtrUtilityFunction (*variant_get_ptr_utility_function)(const char *p_function, GDNativeInt p_hash);
void (*variant_get_constant_value)(GDNativeVariantType p_type, const GDNativeStringNamePtr p_constant, GDNativeVariantPtr r_ret);
GDNativePtrUtilityFunction (*variant_get_ptr_utility_function)(const GDNativeStringNamePtr p_function, GDNativeInt p_hash);
/* 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_ptrcall)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
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_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_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);
/* 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. */
GDNativeMethodBindPtr (*classdb_get_method_bind)(const char *p_classname, const char *p_methodname, GDNativeInt p_hash);
void *(*classdb_get_class_tag)(const char *p_classname);
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 GDNativeStringNamePtr p_classname, const GDNativeStringNamePtr p_methodname, GDNativeInt p_hash);
void *(*classdb_get_class_tag)(const GDNativeStringNamePtr p_classname);
/* CLASSDB EXTENSION */

View File

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

View File

@ -36,20 +36,20 @@
namespace godot {
const char *Wrapped::_get_extension_class() const {
const StringName *Wrapped::_get_extension_class() const {
return nullptr;
}
void Wrapped::_postinitialize() {
const char *extension_class = _get_extension_class();
const StringName *extension_class = _get_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());
}
Wrapped::Wrapped(const char *p_godot_class) {
_owner = godot::internal::gdn_interface->classdb_construct_object(p_godot_class);
Wrapped::Wrapped(const StringName p_godot_class) {
_owner = godot::internal::gdn_interface->classdb_construct_object((void *)&p_godot_class);
}
Wrapped::Wrapped(GodotObject *p_godot_object) {