Godot Version
4.4.1.stable
Question
Good morning everyone. I’m experimenting with GDExtension to understand how the technology works in general. I’m having trouble with method binding, specifically I can’t seem to override them on the GDScript side, even though I can create my class and Godot sees it without any issues.
When I create a GDScript class that inherits from the one written in C++, which should override the benchmark and log_message methods, I always get the default results, the ones written in the C++ code… Does anyone know where I’m going wrong? Thank you so much.
Header of C++ class
#ifndef GDBENCKMARKWORK_H
#define GDBENCKMARKWORK_H
#include <godot_cpp/classes/node3d.hpp>
#include <godot_cpp/core/binder_common.hpp>
#include <godot_cpp/core/gdvirtual.gen.inc>
namespace godot
{
class GDBenchmarkWork : public Node3D
{
GDCLASS(GDBenchmarkWork, Node3D)
protected:
static void _bind_methods();
uint64_t _benchmark_execute();
public:
GDBenchmarkWork();
~GDBenchmarkWork();
void run();
virtual void benchmark();
virtual String log_message();
GDVIRTUAL0(benchmark);
GDVIRTUAL0R(String, log_message);
};
}
#endif
Implementation of C++ class
#include "gdbenchmarkwork.h"
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/classes/time.hpp>
#include <godot_cpp/classes/os.hpp>
#include <godot_cpp/classes/engine.hpp>
using namespace godot;
// Protected
void GDBenchmarkWork::_bind_methods()
{
ClassDB::bind_method(D_METHOD("run"), &GDBenchmarkWork::run);
GDVIRTUAL_BIND(benchmark);
GDVIRTUAL_BIND(log_message);
ADD_SIGNAL(MethodInfo("job_ended", PropertyInfo(Variant::STRING, "message")));
}
uint64_t GDBenchmarkWork::_benchmark_execute()
{
uint64_t elapsed_time = Time::get_singleton()->get_ticks_msec();
benchmark();
elapsed_time = Time::get_singleton()->get_ticks_msec() - elapsed_time;
return elapsed_time;
}
// Public
GDBenchmarkWork::GDBenchmarkWork() {}
GDBenchmarkWork::~GDBenchmarkWork() {}
void GDBenchmarkWork::run()
{
uint64_t elapsed_time = _benchmark_execute();
String message = vformat(log_message(), elapsed_time);
emit_signal("job_ended", message);
}
void GDBenchmarkWork::benchmark()
{
print_line("Perde 250 msec. di tempo");
OS::get_singleton()->delay_msec(250);
}
String GDBenchmarkWork::log_message()
{
return "Processo sconosciuto. %d msec.";
}
Derived class on GDScript (not working, reporting value from original C++ code)
extends GDBenchmarkWork
class_name Benchmark1000Cubes
func _ready() -> void:
print("Script Benchmark1000Cubes pronto!")
func benchmark() -> void:
print("Non fa nulla")
func log_message() -> String:
return "1000 Cubi su GDScript %d msec."