This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
Писати кросплатформний код буває складно, але є кілька способів полегшити як його розробку, так і супровід.
Під час створення розширення варто врахувати кілька речей, які допоможуть і в розробці, і в супроводі.
Має бути лише один API Lua та одна його реалізація. Так значно легше забезпечити однакову поведінку на всіх платформах.
Якщо певна платформа не має підтримувати розширення, рекомендуємо взагалі не реєструвати модуль Lua. Тоді наявність підтримки можна визначити перевіркою на nil:
if myextension ~= nil then
myextension.do_something()
end
Для розширень часто використовують таку структуру папок:
/root
/input
/main -- All the files for the actual example project
/...
/myextension -- The actual root folder of the extension
ext.manifest
/include -- External includes, used by other extensions
/libs
/<platform> -- External libraries for all supported platforms
/src
myextension.cpp -- The extension Lua api and the extension life cycle functions
Also contains generic implementations of your Lua api functions.
myextension_private.h -- Your internal api that each platform will implement (I.e. `myextension_Init` etc)
myextension.mm -- If native calls are needed for iOS/macOS. Implements `myextension_Init` etc for iOS/macOS
myextension_android.cpp -- If JNI calls are needed for Android. Implements `myextension_Init` etc for Android
/java
/<platform> -- Any java files needed for Android
/res -- Any resources needed for a platform
/external
README.md -- Notes/scripts on how to build or package any external libraries
/bundleres -- Resources that should be bundles for (see game.project and the [bundle_resources setting]([physics scale setting](/uk/manuals/project-settings/#project))
/<platform>
game.project
game.appmanifest -- Any extra app configuration info
Зауважте, що файли myextension.mm і myextension_android.cpp потрібні лише тоді, коли ви робите нативні виклики, специфічні для відповідної платформи.
У певних місцях архітектура платформи використовується як назва папки, щоб визначити, які файли використовувати під час компіляції та пакування застосунку. Такі назви мають вигляд:
<architecture>-<platform>
Поточний список:
arm64-ios, armv7-ios, x86_64-ios, arm64-android, armv7-android, x86_64-android, x86_64-linux, x86_64-osx, x86_64-win32, x86-win32
Наприклад, розміщуйте бібліотеки для окремих платформ у таких папках:
/libs
/arm64-ios
/libFoo.a
/arm64-android
/libFoo.a
У вихідному коді Defold можливості C++ використовуються дуже стримано, і більшість коду нагадує C. Шаблонів майже немає, за винятком кількох класів контейнерів, оскільки шаблони збільшують час компіляції та розмір виконуваного файлу.
Для збирання ядра рушія ми використовуємо C++11, а у Windows — C++14. Для консольних збірок тепер зазвичай потрібна версія C++14 або новіша.
Для нативних розширень ми не фіксуємо версію C++, а покладаємося на типову версію набору інструментів платформи.
У вихідному коді Defold ми уникаємо найновіших можливостей і версій C++. Переважно тому, що під час розробки ігрового рушія немає потреби в нових можливостях, а також тому, що відстеження найновіших можливостей C++ потребує часу, а їх ґрунтовне опанування — ще більше дорогоцінного часу.
Для розробників розширень це має додаткову перевагу: Defold зберігає стабільний ABI. Також варто зазначити, що використання найновіших можливостей C++ може перешкоджати компіляції коду на різних платформах через відмінності в їх підтримці.
Defold не використовує винятків у рушії. В ігрових рушіях їх зазвичай уникають, оскільки дані (здебільшого) відомі заздалегідь, ще під час розробки. Вилучення підтримки винятків C++ зменшує розмір виконуваного файлу та підвищує продуктивність під час виконання.
Оскільки рушій Defold не використовує коду STL, окрім деяких алгоритмів і математичних функцій (std::sort, std::upper_bound тощо), використання STL у вашому розширенні може працювати.
Однак пам’ятайте, що несумісність ABI може завадити використанню вашого розширення разом з іншими розширеннями або сторонніми бібліотеками.
Відмова від бібліотек STL, які активно використовують шаблони, також скорочує час збирання і, що важливіше, зменшує розмір виконуваного файлу.
У рушії Defold замість std::string використовується const char*. Використання std::string — поширене джерело проблем при поєднанні різних версій C++ або компілятора, оскільки це може призвести до невідповідності ABI. Використання const char* і кількох допоміжних функцій дає змогу цього уникнути.
За можливості використовуйте ключове слово static для функцій, локальних для вашої одиниці компіляції. Це дає компілятору змогу виконати певні оптимізації, що можуть як підвищити продуктивність, так і зменшити розмір виконуваного файлу.
Вибираючи сторонню бібліотеку (незалежно від мови), враховуйте таке:
Завжди переконуйтеся, що маєте доступ до своїх залежностей. Наприклад, якщо ви залежите від чогось на GitHub, ніщо не заважає видалити цей репозиторій або раптово змінити напрям його розвитку чи власника. Ви можете зменшити цей ризик, створивши форк репозиторію та використовуючи його замість оригінального проєкту.
Пам’ятайте, що код бібліотеки буде додано до вашої гри, тож переконайтеся, що бібліотека робить саме те, що повинна, і нічого зайвого!