Skip to content

Commit bb63b9c

Browse files
committed
Update the Object class engine details page.
1 parent 4bb75ac commit bb63b9c

File tree

1 file changed

+135
-65
lines changed

1 file changed

+135
-65
lines changed

engine_details/architecture/object_class.rst

Lines changed: 135 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -12,59 +12,73 @@ General definition
1212
------------------
1313

1414
:ref:`Object <class_object>` is the base class for almost everything. Most classes in Godot
15-
inherit directly or indirectly from it. Objects provide reflection and
16-
editable properties, and declaring them is a matter of using a single
15+
inherit directly or indirectly from it. Declaring them is a matter of using a single
1716
macro like this:
1817

1918
.. code-block:: cpp
2019
2120
class CustomObject : public Object {
22-
23-
GDCLASS(CustomObject, Object); // this is required to inherit
21+
GDCLASS(CustomObject, Object); // This is required to inherit from Object.
2422
};
2523
26-
This adds a lot of functionality to Objects. For example:
24+
Objects come with a lot of built-in functionality, like reflection and editable properties:
2725

2826
.. code-block:: cpp
2927
30-
obj = memnew(CustomObject);
28+
CustomObject *obj = memnew(CustomObject);
3129
print_line("Object class: ", obj->get_class()); // print object class
3230
33-
obj2 = Object::cast_to<OtherClass>(obj); // converting between classes, this also works without RTTI enabled.
31+
OtherClass *obj2 = Object::cast_to<OtherClass>(obj); // Converting between classes, similar to dynamic_cast
3432
3533
References:
3634
~~~~~~~~~~~
3735

3836
- `core/object/object.h <https://github.com/godotengine/godot/blob/master/core/object/object.h>`__
3937

40-
Registering an Object
41-
---------------------
42-
43-
ClassDB is a static class that holds the entire list of registered
44-
classes that inherit from Object, as well as dynamic bindings to all
45-
their methods properties and integer constants.
38+
Registering Object classes
39+
--------------------------
4640

47-
Classes are registered by calling:
41+
Most ``Object`` subclasses are registered by calling ``GDREGISTER_CLASS``.
4842

4943
.. code-block:: cpp
5044
51-
ClassDB::register_class<MyCustomClass>()
45+
GDREGISTER_CLASS(MyCustomClass)
5246
53-
Registering it will allow the class to be instanced by scripts, code, or
54-
creating them again when deserializing.
47+
This will register it as a named, public class in the ``ClassDB``, which will allow the class to be instantiated by
48+
scripts, code, or by deserialization. Note that classes registered as ``GDREGISTER_CLASS`` should expect to be
49+
instantiated or freed automatically, like by the editor or the documentation system.
5550

56-
Registering as virtual is the same but it can't be instanced.
51+
Besides ``GDREGISTER_CLASS``, there are a few other modes of privateness:
5752

5853
.. code-block:: cpp
5954
60-
ClassDB::register_virtual_class<MyCustomClass>()
55+
// Registers the class publicly, but prevents automatic instantiation through ClassDB.
56+
GDREGISTER_VIRTUAL_CLASS(MyCustomClass);
57+
58+
// Registers the class publicly, but prevents all instantiation through ClassDB.
59+
GDREGISTER_ABSTRACT_CLASS(MyCustomClass);
60+
61+
// Registers the class in ClassDB, but marks it as private,
62+
// such that it is not visible to scripts or extensions.
63+
// This is the same as not registering the class explicitly at all
64+
// - in this case, the class is registered as internal automatically
65+
// when it is first constructed.
66+
GDREGISTER_INTERNAL_CLASS(MyCustomClass);
67+
68+
// Registers the class such that it is only available at runtime (but not in the editor).
69+
GDREGISTER_RUNTIME_CLASS(MyCustomClass);
70+
71+
It is also possible to use ``GDSOFTCLASS(MyCustomClass, SuperClass)`` instead of ``GDCLASS(MyCustomClass, SuperClass)``.
72+
Classes defined this way are not registered in the ``ClassDB`` at all. This is sometimes used for platform-specific
73+
subclasses.
74+
75+
Registering bindings
76+
~~~~~~~~~~~~~~~~~~~~
6177

6278
Object-derived classes can override the static function
63-
``static void _bind_methods()``. When one class is registered, this
79+
``static void _bind_methods()``. When the class is registered, this
6480
static function is called to register all the object methods,
65-
properties, constants, etc. It's only called once. If an Object derived
66-
class is instanced but has not been registered, it will be registered as
67-
virtual automatically.
81+
properties, constants, etc. It's only called once.
6882

6983
Inside ``_bind_methods``, there are a couple of things that can be done.
7084
Registering functions is one:
@@ -95,12 +109,12 @@ documented as thoroughly, the ``D_METHOD()`` macro can safely be ignored and a
95109
string passing the name can be passed for brevity.
96110

97111
References:
98-
~~~~~~~~~~~
112+
^^^^^^^^^^^
99113

100114
- `core/object/class_db.h <https://github.com/godotengine/godot/blob/master/core/object/class_db.h>`__
101115

102116
Constants
103-
---------
117+
~~~~~~~~~
104118

105119
Classes often have enums such as:
106120

@@ -126,7 +140,7 @@ The constants can also be bound inside ``_bind_methods``, by using:
126140
BIND_CONSTANT(MODE_SECOND);
127141
128142
Properties (set/get)
129-
--------------------
143+
~~~~~~~~~~~~~~~~~~~~
130144

131145
Objects export properties, properties are useful for the following:
132146

@@ -181,7 +195,7 @@ This creates the property using the setter and the getter.
181195
.. _doc_binding_properties_using_set_get_property_list:
182196

183197
Binding properties using ``_set``/``_get``/``_get_property_list``
184-
-----------------------------------------------------------------
198+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185199

186200
An additional method of creating properties exists when more flexibility
187201
is desired (i.e. adding or removing properties on context).
@@ -201,26 +215,9 @@ call).
201215
This is also a little less efficient since ``p_property`` must be
202216
compared against the desired names in serial order.
203217

204-
Dynamic casting
205-
---------------
206-
207-
Godot provides dynamic casting between Object-derived classes, for
208-
example:
209-
210-
.. code-block:: cpp
211-
212-
void somefunc(Object *some_obj) {
213-
214-
Button *button = Object::cast_to<Button>(some_obj);
215-
}
216-
217-
If cast fails, NULL is returned. This system uses RTTI, but it also
218-
works fine (although a bit slower) when RTTI is disabled. This is useful
219-
on platforms where a small binary size is ideal, such as HTML5 or
220-
consoles (with low memory footprint).
221218

222219
Signals
223-
-------
220+
~~~~~~~
224221

225222
Objects can have a set of signals defined (similar to Delegates in other
226223
languages). This example shows how to connect to them:
@@ -244,35 +241,108 @@ Adding signals to a class is done in ``_bind_methods``, using the
244241
245242
ADD_SIGNAL(MethodInfo("been_killed"))
246243
247-
Notifications
248-
-------------
244+
Object ownership and casting
245+
----------------------------
249246

250-
All objects in Godot have a :ref:`_notification <class_Object_private_method__notification>`
251-
method that allows it to respond to engine level callbacks that may relate to it.
252-
More information can be found on the :ref:`doc_godot_notifications` page.
247+
Objects are allocated on the heap. There are two different ownership models:
253248

254-
References
255-
----------
249+
- Objects derived from ``RefCounted`` are reference counted.
250+
- All other objects are manually memory managed.
251+
252+
The ownership models are fundamentally different. Refer to the section for each respectively to learn how to
253+
create, store, and free the object.
254+
255+
When you do not know whether an object passed to you (via ``Object *``) is ``RefCounted``, and you need to store it,
256+
you should store its ``ObjectID`` rather than a pointer (as explained below, in the manual memory management section).
256257

257-
:ref:`RefCounted <class_RefCounted>` inherits from Object and holds a
258-
reference count. It is the base for reference counted object types.
259-
Declaring them must be done using Ref<> template. For example:
258+
When an object is passed to you via :ref:`Variant<class_Variant>`, especially when using deferred callbacks, it is
259+
possible that the contained ``Object *`` was already freed by the time your function runs.
260+
Instead of converting directly to ``Object *``, you should use ``get_validated_object``:
260261

261262
.. code-block:: cpp
262263
263-
class MyReference: public RefCounted {
264+
void do_something(Variant p_variant) {
265+
Object *object = p_variant.get_validated_object();
266+
ERR_FAIL_NULL(object);
267+
}
268+
269+
Manual memory management
270+
~~~~~~~~~~~~~~~~~~~~~~~~
271+
272+
Manually memory managed objects are created using ``memnew`` and freed using ``memdelete``:
273+
274+
.. code-block:: cpp
275+
276+
Node *node = memnew(Node);
277+
// ...
278+
memdelete(node);
279+
node = nullptr;
280+
281+
When you are not the sole owner of an object, storing a pointer to it is dangerous: Any other references to the object
282+
may call ``memdelete`` at any time, causing your pointer to become a dangling pointer, which will eventually result in a
283+
crash.
284+
285+
When storing objects you are not the only owner of, you should store its ``ObjectID`` rather than a pointer:
286+
287+
.. code-block:: cpp
288+
289+
Node *node = memnew(Node);
290+
ObjectID node_id = node.get_instance_id();
291+
// ...
292+
Object *maybe_node = ObjectDB::get_instance(node_id);
293+
ERR_FAIL_NULL(maybe_node); // The node may have been freed between calls.
294+
295+
``RefCounted`` memory management
296+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
297+
298+
:ref:`RefCounted <class_RefCounted>` subclasses are memory managed with
299+
`reference counting semantics <https://en.wikipedia.org/wiki/Reference_counting>`__.
300+
301+
They are constructed using ``memnew``, and should be stored in ``Ref`` instances. When the last ``Ref`` instance is
302+
dropped, the object automatically self-destructs.
303+
304+
.. code-block:: cpp
305+
306+
class MyRefCounted: public RefCounted {
264307
GDCLASS(MyReference, RefCounted);
265308
};
266309
267-
Ref<MyReference> myref(memnew(MyReference));
310+
Ref<MyRefCounted> my_ref = memnew(MyRefCounted);
311+
// ...
312+
my_ref->get_class_name(); // Calls to Ref are always safe because of shared ownership.
268313
269-
``myref`` is reference counted. It will be freed when no more Ref<>
270-
templates point to it.
314+
You should never call ``memdelete`` for ``RefCounted`` subclasses, because there may be other owners of it.
315+
316+
You should also never store ``RefCounted`` subclasses using raw pointers, for example
317+
``RefCounted *object = memnew(RefCounted)``. This is unsafe because other owners may destruct the object, leaving you
318+
with a dangling pointer, which will eventually result in a crash.
271319

272320
References:
273-
~~~~~~~~~~~
321+
^^^^^^^^^^^
322+
323+
- `core/object/ref_counted.h <https://github.com/godotengine/godot/blob/master/core/object/ref_counted.h>`__
324+
325+
Dynamic casting
326+
~~~~~~~~~~~~~~~
327+
328+
Godot provides dynamic casting between Object-derived classes, for example:
329+
330+
.. code-block:: cpp
331+
332+
void some_func(Object *p_object) {
333+
Button *button = Object::cast_to<Button>(p_object);
334+
}
335+
336+
If the cast fails, ``nullptr`` is returned. This works the same as ``dynamic_cast``, but does not use
337+
`C++ .RTTI <https://en.wikipedia.org/wiki/Run-time_type_information>`__.
338+
339+
Notifications
340+
-------------
341+
342+
All objects in Godot have a :ref:`_notification <class_Object_private_method__notification>`
343+
method that allows it to respond to engine level callbacks that may relate to it.
344+
More information can be found on the :ref:`doc_godot_notifications` page.
274345

275-
- `core/object/reference.h <https://github.com/godotengine/godot/blob/master/core/object/ref_counted.h>`__
276346

277347
Resources
278348
----------
@@ -291,7 +361,7 @@ References:
291361
- `core/io/resource.h <https://github.com/godotengine/godot/blob/master/core/io/resource.h>`__
292362

293363
Resource loading
294-
----------------
364+
~~~~~~~~~~~~~~~~
295365

296366
Resources can be loaded with the ResourceLoader API, like this:
297367

@@ -307,12 +377,12 @@ the same time.
307377
- resourceinteractiveloader (TODO)
308378

309379
References:
310-
~~~~~~~~~~~
380+
^^^^^^^^^^^
311381

312382
- `core/io/resource_loader.h <https://github.com/godotengine/godot/blob/master/core/io/resource_loader.h>`__
313383

314384
Resource saving
315-
---------------
385+
~~~~~~~~~~~~~~~
316386

317387
Saving a resource can be done with the resource saver API:
318388

@@ -326,6 +396,6 @@ be bundled with the saved resource and assigned sub-IDs, like
326396
``res://someresource.res::1``. This also helps to cache them when loaded.
327397

328398
References:
329-
~~~~~~~~~~~
399+
^^^^^^^^^^^
330400

331401
- `core/io/resource_saver.h <https://github.com/godotengine/godot/blob/master/core/io/resource_saver.h>`__

0 commit comments

Comments
 (0)