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
Написание кроссплатформенного кода может быть сложным, но есть способы упростить как его разработку, так и сопровождение.
При создании расширения есть несколько вещей, которые помогают как в разработке, так и в поддержке.
Должен быть только один Lua API и одна его реализация. Это значительно облегчает обеспечение одинакового поведения на всех платформах.
Если платформа не должна поддерживать расширение, рекомендуется вообще не регистрировать модуль Lua. Таким образом, можно определить поддержку, проверив значение на nil
:
if myextension ~= nil then
myextension.do_something()
end
Следующая структура папок часто используется для расширений:
/root
/input
/main -- Все файлы для примера проекта
/...
/myextension -- Корневая папка самого расширения
ext.manifest
/include -- Внешние заголовочные файлы, используемые другими расширениями
/libs
/<platform> -- Внешние библиотеки для всех поддерживаемых платформ
/src
myextension.cpp -- Lua API расширения и функции жизненного цикла
Также содержит универсальные реализации Lua-функций
myextension_private.h -- Внутренний API, который реализуется для каждой платформы (например, `myextension_Init`)
myextension.mm -- Для нативных вызовов на iOS/macOS. Реализует `myextension_Init` для iOS/macOS
myextension_android.cpp -- Для JNI вызовов на Android. Реализует `myextension_Init` для Android
/java
/<platform> -- Любые Java-файлы, необходимые для Android
/res -- Ресурсы, необходимые для платформы
/external
README.md -- Заметки/скрипты о сборке/упаковке внешних библиотек
/bundleres -- Ресурсы, которые должны быть включены в бандл (см. game.project и [bundle_resources setting]([physics scale setting](/ru/manuals/project-settings/#project)))
/<platform>
game.project
game.appmanifest -- Дополнительная информация о конфигурации приложения
Обратите внимание, что myextension.mm
и myextension_android.cpp
нужны только при использовании нативных вызовов для соответствующих платформ.
В некоторых случаях архитектура платформы используется в качестве имени папки, чтобы определить, какие файлы использовать при компиляции/упаковке приложения. Формат:
<architecture>-<platform>
Текущий список:
arm64-ios, armv7-ios, x86_64-ios, arm64-android, armv7-android, x86_64-linux, x86_64-osx, x86_64-win32, x86-win32
Например, для платформоспецифичных библиотек:
/libs
/arm64-ios
/libFoo.a
/arm64-android
/libFoo.a
В исходном коде Defold C++ используется очень ограниченно и преимущественно в C-стиле. Шаблоны почти не используются (за исключением некоторых контейнерных классов), так как они увеличивают время компиляции и размер исполняемого файла.
Исходники Defold собираются с использованием версии C++ по умолчанию для каждого компилятора. Сам движок не использует возможности C++ новее, чем C++98. Хотя использовать более новую версию для расширения возможно, это может вызвать проблемы с ABI. Это может привести к невозможности использования расширения совместно с другими расширениями движка или из портала ассетов.
Исходный код Defold избегает использования последних возможностей или версий C++. В основном потому, что при разработке игрового движка нет необходимости в новых возможностях, а также потому, что отслеживание последних изменений в C++ — это трудоёмкая задача, а для полного освоения этих возможностей потребуется много драгоценного времени.
Дополнительным плюсом является поддержание стабильного ABI, что важно для разработчиков расширений. Использование новейших возможностей C++ также может затруднить сборку под разные платформы из-за различий в поддержке.
Defold не использует исключения в движке. Исключения, как правило, не применяются в игровых движках, так как большинство данных известно на этапе разработки. Отключение поддержки исключений C++ уменьшает размер исполняемого файла и повышает производительность.
В движке Defold не используется STL, за исключением некоторых алгоритмов и математических функций (std::sort
, std::upper_bound
и т.д.). Однако, при необходимости, вы можете использовать STL в расширении.
Следует помнить, что несовместимости ABI могут помешать использованию расширений совместно с другими расширениями или сторонними библиотеками.
Избегание STL (из-за его обширного использования шаблонов) помогает ускорить сборку и уменьшить размер исполняемого файла.
В Defold используется const char*
вместо std::string
. Использование std::string
часто вызывает проблемы ABI при смешивании разных версий C++ или компиляторов. Применение const char*
и вспомогательных функций позволяет избежать этих проблем.
Если возможно, используйте ключевое слово static
для функций, локальных для единицы трансляции. Это позволяет компилятору выполнять оптимизации, улучшает производительность и уменьшает размер исполняемого файла.
При выборе сторонней библиотеки (вне зависимости от языка), учитывайте:
Убедитесь, что у вас есть доступ к зависимостям. Например, если вы полагаетесь на библиотеку из GitHub, ничто не мешает её удалению или смене владельца/направления. Чтобы снизить риск, рекомендуется создать форк и использовать его вместо оригинала.
Помните, код из этой библиотеки будет встроен в вашу игру. Убедитесь, что библиотека делает именно то, что вы от неё ожидаете — и ничего лишнего.
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB