Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mention rules for using Godot classes in the readme #358

Closed
sheepandshepherd opened this issue Dec 13, 2019 · 2 comments · Fixed by #363
Closed

Mention rules for using Godot classes in the readme #358

sheepandshepherd opened this issue Dec 13, 2019 · 2 comments · Fixed by #363

Comments

@sheepandshepherd
Copy link
Contributor

I've seen a lot of new users of the C++ bindings get stuck on unhelpful/non-obvious errors caused by using Godot classes like normal C++ classes. There are certain "rules" for how they should be used that aren't clearly mentioned in the readme or official docs. The examples follow them, of course, but it's not obvious from there that the "normal" C++ ways don't work.

I would suggest adding this section to the bottom of the readme:

Using Godot classes

  • Create instances that inherit Object (including your own registered classes) using _new(), not C++'s new operator.
Sprite *sprite = Sprite::_new();
  • Destroy nodes using queue_free(), not C++'s delete operator.
some_old_node->queue_free();
  • Wrap instances that inherit Reference in Ref instead of passing around raw pointers. They are ref-counted and do not need to be freed manually.
Ref<Texture> texture = resource_loader->load("res://icon.png");
  • Pass the core types that do not inherit Object by value. The containers (Array, Dictionary, PoolArrays) manage their own memory and do not need to be explicitly initialized.
Array ints;
ints.append(123);
return ints;
  • Initialize your classes in their _init() method, not their constructor. The constructor does not yet have access to the base class's methods.
  • Cast objects using Object::cast_to, not unsafe C-style casts or static_cast.
MeshInstance *m = Object::cast_to<MeshInstance>(get_node("ChildNode"));
// m will be null if it's not a MeshInstance
if (m) { ... }

 
 
 
Let me know if there are more non-obvious rules missing from the list, or if I can improve/condense any of the phrasing.

@Mantarri
Copy link

As a user who has struggled with GDNative, (SheepAndShepard has been a big help with using it), I wholeheartedly support having a list of "common pitfalls", including examples on the right way to go about things.

I myself don't have much C++ experience, so I can't really suggest much, but it would be nice if future users interested in GDNative C++ don't need to come on the Discord, and ask on there about every little thing, which is what I've had to do due to how lacking documentation is.

@sheepandshepherd
Copy link
Contributor Author

I'll add one more before I make a PR for this:

  • Never use Godot value types in static or global variables. These will crash because the Godot API is not loaded until after their constructors are called.
String s; // crashes
class SomeClass {
    static Dictionary d; // crashes
    static Node *singleton; // fine, pointer doesn't call a constructor
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants