Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Основные функции и типы
API godot-cpp разработан так, чтобы быть максимально похожим на внутренний API Godot.
Это означает, что в общем случае вы можете использовать раздел Сведения о движке для изучения работы с godot-cpp. Кроме того, часто бывает полезно просмотреть код движка для поиска примеров работы с API Godot.
Тем не менее, есть некоторые различия, о которых следует знать, и они описаны здесь.
Общие функции и макросы
Пожалуйста, обратитесь к Общие методы и макросы движка для получения информации об этом. Функции и макросы, описанные там, также доступны в godot-cpp.
Основные типы
Основные типы Godot также доступны в godot-cpp, и применяются те же рекомендации, что описаны в этой статье. Типы регулярно синхронизируются с кодовой базой Godot.
В вашем собственном коде вы также можете использовать типы C++ STL или типы из любой библиотеки по вашему выбору, но они не будут совместимы с API Godot.
Упакованные массивы
В Godot типы Packed*Array являются псевдонимами Vector, а в godot-cpp они являются собственными типами, использующими привязки Godot. Это связано с тем, что Packed*Array доступны в Godot и ограничены только типами Godot, тогда как Vector может содержать любой тип C++, который Godot может не понимать.
В целом типы Packed*Array работают так же, как их псевдонимы Vector, однако есть некоторые заметные различия.
Доступ к данным
Vector хранит свои данные полностью в GDExtension, тогда как типы Packed*Array хранят свои данные на стороне Godot. Это означает, что при каждом обращении к Packed*Array требуется вызов Godot.
Для эффективного чтения или записи большого объёма данных в Packed*Array следует вызывать .ptr() (для чтения) или .ptrw() (для записи), чтобы получить указатель непосредственно на память массива:
// BAD!
void my_bad_function(const PackedByteArray &p_array) {
for (int i = 0; i < p_array.size(); i++) {
// Each time this runs it needs to call into Godot.
uint8_t byte = p_array[i];
// .. do something with the byte.
}
}
// GOOD :-)
void my_good_function(const PackedByteArray &p_array) {
const uint8_t *array_ptr = p_array.ptr();
for (int i = 0; i < p_array.size(); i++) {
// This directly accesses the memory!
uint8_t byte = array_ptr[i];
// .. do something with the byte.
}
}
Копирование
Обёртки Variant для Packed*Array рассматривают их как передаваемые по ссылке, тогда как сами типы Packed*Array передаются по значению (реализованы как копирование при записи).
Кроме того, может быть интересно, что вызовы GDScript используют интерфейс вызовов Variant: любые аргументы Packed*Array ваших функций будут переданы в Variant и распакованы оттуда. Это может создавать копии типов, поэтому полученный вами аргумент может быть копией аргумента, с которым была вызвана функция. На практике это означает, что вы не можете полагаться на то, что переданный вам аргумент может быть изменён на стороне вызывающего.
Класс Variant
Обратитесь к Класс Variant, чтобы узнать, как работать с Variant.
Самое важное, вы должны знать, что все функции, предоставляемые через API GDExtension, должны быть совместимы с Variant.
Класс Object
Обратитесь к Класс Object, чтобы узнать, как регистрировать и работать с собственными типами Object.
Нам не известно о каких-либо серьёзных различиях между API Object godot-cpp и внутренним API Object Godot, за исключением того, что некоторые методы доступны во внутреннем API Godot, но недоступны в godot-cpp.
Вы должны знать, что указатель на ваш Object godot-cpp отличается от указателя, который Godot использует внутри. Это связано с тем, что версия godot-cpp является экземпляром расширения, выделенным отдельно от исходного Object. Однако на практике это различие обычно незаметно.