mirror of
https://github.com/godotengine/godot-cpp.git
synced 2026-01-07 10:10:08 +03:00
Allow GDExtensions to register virtual methods and call them on scripts
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <godot_cpp/core/error_macros.hpp>
|
||||
#include <godot_cpp/godot.hpp>
|
||||
#include <godot_cpp/templates/vector.hpp>
|
||||
|
||||
#include <godot_cpp/core/memory.hpp>
|
||||
|
||||
@@ -337,6 +338,46 @@ void ClassDB::bind_virtual_method(const StringName &p_class, const StringName &p
|
||||
type.virtual_methods[p_method] = p_call;
|
||||
}
|
||||
|
||||
void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, const Vector<StringName> &p_arg_names) {
|
||||
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(p_class);
|
||||
ERR_FAIL_COND_MSG(type_it == classes.end(), String("Class '{0}' doesn't exist.").format(Array::make(p_class)));
|
||||
|
||||
GDExtensionClassVirtualMethodInfo mi;
|
||||
mi.name = (GDExtensionStringNamePtr)&p_method.name;
|
||||
mi.method_flags = p_method.flags;
|
||||
mi.return_value = p_method.return_val._to_gdextension();
|
||||
mi.return_value_metadata = p_method.return_val_metadata;
|
||||
mi.argument_count = p_method.arguments.size();
|
||||
if (mi.argument_count > 0) {
|
||||
mi.arguments = (GDExtensionPropertyInfo *)memalloc(sizeof(GDExtensionPropertyInfo) * mi.argument_count);
|
||||
mi.arguments_metadata = (GDExtensionClassMethodArgumentMetadata *)memalloc(sizeof(GDExtensionClassMethodArgumentMetadata) * mi.argument_count);
|
||||
for (int i = 0; i < mi.argument_count; i++) {
|
||||
mi.arguments[i] = p_method.arguments[i]._to_gdextension();
|
||||
mi.arguments_metadata[i] = p_method.arguments_metadata[i];
|
||||
}
|
||||
} else {
|
||||
mi.arguments = nullptr;
|
||||
mi.arguments_metadata = nullptr;
|
||||
}
|
||||
|
||||
if (p_arg_names.size() != mi.argument_count) {
|
||||
WARN_PRINT("Mismatch argument name count for virtual method: " + String(p_class) + "::" + p_method.name);
|
||||
} else {
|
||||
for (int i = 0; i < p_arg_names.size(); i++) {
|
||||
mi.arguments[i].name = (GDExtensionStringNamePtr)&p_arg_names[i];
|
||||
}
|
||||
}
|
||||
|
||||
internal::gdextension_interface_classdb_register_extension_class_virtual_method(internal::library, &p_class, &mi);
|
||||
|
||||
if (mi.arguments) {
|
||||
memfree(mi.arguments);
|
||||
}
|
||||
if (mi.arguments_metadata) {
|
||||
memfree(mi.arguments_metadata);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassDB::initialize_class(const ClassInfo &p_cl) {
|
||||
}
|
||||
|
||||
|
||||
@@ -171,6 +171,8 @@ GDExtensionInterfaceObjectGetClassName gdextension_interface_object_get_class_na
|
||||
GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to = nullptr;
|
||||
GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id = nullptr;
|
||||
GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id = nullptr;
|
||||
GDExtensionInterfaceObjectHasScriptMethod gdextension_interface_object_has_script_method = nullptr;
|
||||
GDExtensionInterfaceObjectCallScriptMethod gdextension_interface_object_call_script_method = nullptr;
|
||||
GDExtensionInterfaceCallableCustomCreate gdextension_interface_callable_custom_create = nullptr;
|
||||
GDExtensionInterfaceCallableCustomGetUserData gdextension_interface_callable_custom_get_userdata = nullptr;
|
||||
GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object = nullptr;
|
||||
@@ -183,6 +185,7 @@ GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_metho
|
||||
GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2 = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed = nullptr;
|
||||
@@ -408,6 +411,8 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
LOAD_PROC_ADDRESS(object_cast_to, GDExtensionInterfaceObjectCastTo);
|
||||
LOAD_PROC_ADDRESS(object_get_instance_from_id, GDExtensionInterfaceObjectGetInstanceFromId);
|
||||
LOAD_PROC_ADDRESS(object_get_instance_id, GDExtensionInterfaceObjectGetInstanceId);
|
||||
LOAD_PROC_ADDRESS(object_has_script_method, GDExtensionInterfaceObjectHasScriptMethod);
|
||||
LOAD_PROC_ADDRESS(object_call_script_method, GDExtensionInterfaceObjectCallScriptMethod);
|
||||
LOAD_PROC_ADDRESS(callable_custom_create, GDExtensionInterfaceCallableCustomCreate);
|
||||
LOAD_PROC_ADDRESS(callable_custom_get_userdata, GDExtensionInterfaceCallableCustomGetUserData);
|
||||
LOAD_PROC_ADDRESS(ref_get_object, GDExtensionInterfaceRefGetObject);
|
||||
@@ -420,6 +425,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
LOAD_PROC_ADDRESS(classdb_get_class_tag, GDExtensionInterfaceClassdbGetClassTag);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class2, GDExtensionInterfaceClassdbRegisterExtensionClass2);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_method, GDExtensionInterfaceClassdbRegisterExtensionClassMethod);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_virtual_method, GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_integer_constant, GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property, GDExtensionInterfaceClassdbRegisterExtensionClassProperty);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_indexed, GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed);
|
||||
|
||||
Reference in New Issue
Block a user