Skip to content

General info

IvanInventor edited this page Feb 2, 2024 · 18 revisions

How to use it

When configured, created target takes care of generating proper class bindings completely, from class registration, to methods/enums/RPC configuration, automatically or via implemented macros.

Start with simple class extending Label node

in src/example.hpp

// include to extend Label
#include <godot_cpp/classes/label.hpp>

// include to use cppscript macros
#include <cppscript.h>

class Example : public godot::Label {
	GCLASS(Example, godot::Label);
};

When rebuilding, Example class will be registered and available in editor's node list, no manual registering needed.

image


Add a method to class and implement it

in src/example.hpp

class Example : public godot::Label {

public:

	void do_something();

	GCLASS(Example, godot::Label);
};

in src/example.cpp

#include <godot_cpp/variant/utility_functions.hpp>

#include "example.hpp"

using namespace godot;

void Example::do_something() {
	UtilityFunctions::print("GDExtension working!");
}

Add node to scene, and attach this script

extends Example

func _ready():
	do_something()

Rebuild, run scene, and check console

image

Again, no manual bindings, method was registered automatically.


Add an int property

class Example : public godot::Label {

	GPROPERTY(set_intprop, get_intprop);
	int intprop = 100;

public:

	void do_something();

	GCLASS(Example, godot::Label);
};

Rebuild, reload project, and check the result

image

This time, it's not just auto-registered property, it's also auto-generated setter/getter. No time wasted on methods, similar in 90% of use cases.

What it does automatically

By default, all public enums are registered:

  • Enums with names register as enums
  • Enums without name register as constants
  • Enums with GBITFIELD macro register as bitfields.

By default, if auto_methods on cppscript configuration stage is True/ON, public methods are registered automatically. See GMETHOD macro to force register method.

By default, all registered classes are initialized on SCENE stage. See GINIT_LEVEL macro to change init level.

In GPROPERTY macro, if you specify non-existent setter or getter, it will be generated automatically, and it will even be available in C++ code.

What it doesn't do automatically

See Macros reference for all available macros.

How does it work?

  • Python script parses .hpp headers and generates code to corresponding .gen/<header_name>.gen.cpp file
  • After that, it also generates 3 files to src/ directory:
    • properties.gen.h

      Contains generated setter/getter methods and symbols that get replaced by them in class declaration

    • scripts.gen.h

      Contains inline functions that register_types.cpp uses to register classes

    • cppscript.h - or your custom name

      Small header that you need to include in headers to use cppscript macros.

  • Then, your configuration, added to existing SCons/CMake scripts, adds needed paths and sources to targets, and builders compile as usual

Why unique header name over cppscript.h is preferred?

Theoretically, with how i implemented it, it's possible for multiple subprojects of main project to use it, and if some of them need headers of another one, single cppscript.h name will cause errors, because it's made to include headers specific to this project. Just renaming your header to unique name will help to avoid future errors.

Clone this wiki locally