diff options
| author | David Snopek <dsnopek@gmail.com> | 2024-02-12 18:43:12 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-12 18:43:12 -0600 |
| commit | 5fcc43e54d68c45e7875a189e476c5fe7e14237d (patch) | |
| tree | df3b2a092d9981f6f25d1c65dcff249c711a93d9 /src/core | |
| parent | 9a13efa0e30a502d44b0352cb1beee77b81d4112 (diff) | |
| parent | 8fbb7cf79535a2b382d57ce2a094d4cbee316fd1 (diff) | |
| download | redot-cpp-5fcc43e54d68c45e7875a189e476c5fe7e14237d.tar.gz | |
Merge pull request #1377 from dsnopek/gdextension-register-virtual-method
Allow GDExtensions to register virtual methods and call them on scripts (godot-cpp support)
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/class_db.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/core/class_db.cpp b/src/core/class_db.cpp index 1f4b135..acead8b 100644 --- a/src/core/class_db.cpp +++ b/src/core/class_db.cpp @@ -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) { } |
