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.
Нам невідомі жодні суттєві відмінності між API godot-cpp Object та внутрішнім API Godot Object, окрім того, що деякі методи доступні у внутрішньому API Godot, але недоступні в godot-cpp.
Ви повинні знати, що вказівник на ваш Object godot-cpp відрізняється від вказівника, який Godot використовує внутрішньо. Це тому, що версія godot-cpp є екземпляром розширення, що виділяється окремо від оригінального Object. Однак на практиці ця різниця зазвичай не помітна.