godotengine / godot-cpp

C++ bindings for the Godot script API
MIT License
1.66k stars 503 forks source link

How to make sort_custom function in GDNative? #559

Open gscoders2 opened 3 years ago

gscoders2 commented 3 years ago

I see that in include/core/Array.hpp there is void sort_custom(Object *obj, const String &func);but not sure how to use it, any body can help me?

Zylann commented 3 years ago

In GDScript, sort_custom expects an object, and a method of that object to be called for comparing elements of the array to sort.

So as it stands in the script API, that function requires you to do the following:

Summary:

class YourClass : public SomeBaseClassThatIsOrInheritsObject {
    GODOT_CLASS(YourClass, SomeBaseClassThatIsOrInheritsObject )
public:
    void _init() {
        //...
    }

    bool compare(Variant a, Variant b) {
        // Let's say for example a and b are vectors (casting is automatic, but we assume it wont fail)
        Vector2 va = a;
        Vector2 vb = b;
        // And you could want to compare their X coordinate
        return a.x < b.x;
    }

    void whatever(Array array) {
        array.sort_custom(this, "compare");
    }

    static void _register_methods() {
        godot::register_method("compare", &YourClass::compare);
    }
};

(I did not test that code, only wrote it from memory of what I think it could be)

If however you can afford not having to use Array, you can use C++ usual sorting methods with an std::vector<T> with the std::sort function. Godot's bound types are nice to communicate with the engine but they aren't efficient to do complex operations on in C++. It might even be a bit faster to do that on large arrays if you first convert the Array, but it depends what you want this for.

gscoders2 commented 3 years ago

@Zylann thanks for answer, I have already tried this but without success, lib is compiling without errors but when I using function (in your case it would be "whatever") in Godot from lib that contain sort_custom inside, game run is crashing

Zylann commented 3 years ago

You would be hitting another problem then, I strongly suggest you use a debugger to see where it's crashing, otherwise none of the C++ errors will tell you anything (not using a C++ debugger is like trying to test GDScripts by exporting the game and run it to see if it passes or breaks^^"). You could seek help about the crash on Discord GDNative channel

edit: added _init to the example because it's always required otherwise it, well, crashes