h-raylib-5.6.0.0: raylib/projects/VS2019-Android/raylib_android/raylib_android.NativeActivity/android_native_app_glue.h
/*
* © 2010 The Android Open Source Project
*
* Лицензировано по лицензии Apache License, версия 2.0 ( "Лицензия");
*этот файл можно использовать только в соответствии с лицензией.
*Копию лицензии можно получить на веб-сайте
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Если только не требуется в соответствии с применимым законодательством или согласовано в письменном виде, программное обеспечение
* распространяется в рамках лицензии на УСЛОВИЯХ "КАК ЕСТЬ",
* БЕЗ ГАРАНТИЙ И УСЛОВИЙ ЛЮБОГО РОДА, явно выраженных и подразумеваемых.
* См. лицензию для получения информации об определенных разрешениях по использованию языка и
* ограничениях в рамках лицензии.
*
*/
#ifndef _ANDROID_NATIVE_APP_GLUE_H
#define _ANDROID_NATIVE_APP_GLUE_H
#include <poll.h>
#include <pthread.h>
#include <sched.h>
#include <android/configuration.h>
#include <android/looper.h>
#include <android/native_activity.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Интерфейс NativeActivity, предоставленный <android/native_activity.h>,
* основан на наборе предоставленных приложением обратных вызовов, которые вызываются
*основным потоком действия при возникновении определенных событий.
*
* Это означает, что ни один из данных обратных вызовов _не_ _должен_ блокироваться, иначе
* существует риск принудительного закрытия приложения системой. Эта модель программирования
* прямая, простая, но имеет ограничения.
*
* Статическая библиотека threaded_native_app используется для обеспечения другой
* модели выполнения, в которой приложение может реализовать свой собственный цикл главного события
* в другом потоке вместо этого. Это работает так:
*
* 1/ Приложение должно предоставить функцию с именем android_main(), которая
* будет вызываться при создании действия в новом потоке,
* отличающемся от основного потока действия.
*
* 2/ android_main() получает указатель на допустимую структуру android_app,
* которая содержит ссылки на другие важные объекты, например экземпляр объекта
* ANativeActivity, где выполняется приложение.
*
* 3/ Объект android_app содержит экземпляр ALooper, который уже
* ожидает две важных вещи:
*
* - событий жизненного цикла действия (например, "pause", "resume"). См. объявления APP_CMD_XXX
* ниже.
*
* - входных событий, поступающих из очереди AInputQueue, присоединенной к действию.
*
* Каждое из этих событий соответствует идентификатору ALooper, возвращенному
* ALooper_pollOnce со значениями LOOPER_ID_MAIN и LOOPER_ID_INPUT,
*, соответственно.
*
* Ваше приложение может использовать тот же ALooper для прослушивания дополнительных
* дескрипторов файла. Они могут быть основаны либо на обратных вызовах, либо поступают с идентификаторами возврата,
* начинающимися с LOOPER_ID_USER.
*
* 4/ При получении события LOOPER_ID_MAIN или LOOPER_ID_INPUT
* возвращенные данные будут указывать на структуру android_poll_source. Для нее
* можно вызвать функцию process() и заполнить android_app->onAppCmd
* и android_app->onInputEvent, для того чтобы они вызывались для вашей собственной обработки
* события.
*
* Вместо этого можно вызвать функции нижнего уровня для чтения и обработки
* данных непосредственно... посмотрите на реализации process_cmd() и process_input()
* в приклеивании, чтобы выяснить, как это делается.
*
* См. пример "native-activity" в NDK с
* полной демонстрацией использования. Также посмотрите JavaDoc в NativeActivity.
*/
struct android_app;
/**
* Данные, связанные с ALooper fd, которые будут возвращаться как outData
* при готовности данных в этом источнике.
*/
struct android_poll_source {
// Идентификатор данного источника. Может быть LOOPER_ID_MAIN или
// LOOPER_ID_INPUT.
int32_t id;
// android_app, с которым связан данный идентификатор.
struct android_app* app;
// Функция, вызываемая для стандартной обработки данных из
// этого источника.
void (*process)(struct android_app* app, struct android_poll_source* source);
};
/**
* Это интерфейс стандартного кода приклеивания поточного
* приложения. В этой модели код приложения выполняется
* в своем собственном потоке, отдельном от основного потока процесса.
* Не требуется связь данного потока с ВМ Java
*, хотя это необходимо для выполнения вызовов JNI любых
* объектов Java.
*/
struct android_app {
// Приложение может поместить указатель на свой собственный объект состояния
// здесь, если нужно.
void* userData;
// Введите здесь код функции для обработки основных команд приложения (APP_CMD_*)
void (*onAppCmd)(struct android_app* app, int32_t cmd);
// Введите здесь код функции для обработки входных событий. Сейчас
// событие уже было предварительно отправлено и будет завершено при
// возврате. Верните 1, если событие обработано, 0 — для любой диспетчеризации
// по умолчанию.
int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event);
// Экземпляр объекта ANativeActivity, в котором выполняется это приложение.
ANativeActivity* activity;
// Текущая конфигурация, в которой выполняется это приложение.
AConfiguration* config;
// Это последнее сохраненное состояние экземпляра, предоставленное во время создания.
// Значение равно NULL, если состояния не было. Можно использовать это по мере необходимости;
// память останется доступной до вызова android_app_exec_cmd() для
// APP_CMD_RESUME, после чего она будет освобождена, а savedState получит значение NULL.
// Эти переменные необходимо изменять только при обработке APP_CMD_SAVE_STATE,
// когда их значения будут инициализироваться в NULL и можно будет выполнить malloc для
// состояния и поместить здесь информацию. В этом случае память будет
// освобождена позднее.
void* savedState;
size_t savedStateSize;
// ALooper, связанный с потоком приложения.
ALooper* looper;
// Если значение не равно NULL, то это входная очередь, из которой приложение будет
// получать входные события пользователя.
AInputQueue* inputQueue;
// Если значение не равно NULL, то это поверхность окна, в котором приложение может рисовать.
ANativeWindow* window;
// Текущий прямоугольник содержимого окна. Это область, в которой
// должно помещаться содержимое окна, чтобы его видел пользователь.
ARect contentRect;
// Текущее состояние действия приложения. Может быть APP_CMD_START,
// APP_CMD_RESUME, APP_CMD_PAUSE или APP_CMD_STOP; см. ниже.
int activityState;
// Значение не равно нулю, когда NativeActivity приложения
// разрушается и ожидает завершения потока приложения.
int destroyRequested;
// -------------------------------------------------
// Ниже показан "частная" реализация кода прилипания.
pthread_mutex_t mutex;
pthread_cond_t cond;
int msgread;
int msgwrite;
pthread_t thread;
struct android_poll_source cmdPollSource;
struct android_poll_source inputPollSource;
int running;
int stateSaved;
int destroyed;
int redrawNeeded;
AInputQueue* pendingInputQueue;
ANativeWindow* pendingWindow;
ARect pendingContentRect;
};
enum {
/**
* Идентификатор данных Looper команд, поступающих из основного потока приложения, который
* возвращается как идентификатор от ALooper_pollOnce(). Данные для этого идентификатора
* являются указателем на структуру android_poll_source.
* Их можно извлечь и обработать с помощью android_app_read_cmd()
* и android_app_exec_cmd().
*/
LOOPER_ID_MAIN = 1,
/**
* Идентификатор данных Looper событий, поступающий из AInputQueue окна
* приложения, который возвращается как идентификатор из
* ALooper_pollOnce(). Данные этого идентификатора являются указателем на структуру
* android_poll_source. Их можно прочитать через объект inputQueue
* приложения android_app.
*/
LOOPER_ID_INPUT = 2,
/**
* Запуск определяемых пользователем идентификаторов ALooper.
*/
LOOPER_ID_USER = 3,
};
enum {
/**
* Команда из основного потока: AInputQueue изменена. После обработки
* этой команды android_app->inputQueue будет обновлена в новую очередь
* (или NULL).
*/
APP_CMD_INPUT_CHANGED,
/**
* Команда из основного потока: новое окно ANativeWindow готово к использованию. После
* получения этой команды окно android_app-> будет содержать новую поверхность
*окна.
*/
APP_CMD_INIT_WINDOW,
/**
* Команда из основного потока: существующее окно ANativeWindow необходимо
* прекратить. После получения этой команды окно android_app->по-прежнему
* содержит существующее окно; после вызова android_app_exec_cmd
* оно получит значение NULL.
*/
APP_CMD_TERM_WINDOW,
/**
* Команда из основного потока: текущее окно ANativeWindow изменило размер.
* Перерисуйте согласно новом размеру.
*/
APP_CMD_WINDOW_RESIZED,
/**
* Команда из основного потока: системе необходимо, чтобы текущее окно ANativeWindow
* было перерисовано. Необходимо перерисовать окно перед ее передачей в
* android_app_exec_cmd(), чтобы избежать переходных сбоев рисования.
*/
APP_CMD_WINDOW_REDRAW_NEEDED,
/**
* Команда из основного потока: область содержимого окна изменена
* таким образом, что из функционального ввода окно показывается или скрывается. Можно
* найти новый прямоугольник содержимого в android_app::contentRect.
*/
APP_CMD_CONTENT_RECT_CHANGED,
/**
* Команда из основного потока: окно действия приложения получило
* фокус ввода.
*/
APP_CMD_GAINED_FOCUS,
/**
* Команда из основного потока: окно действия приложения потеряло
* фокус ввода.
*/
APP_CMD_LOST_FOCUS,
/**
* Команда из основного потока: изменена текущая конфигурация устройства.
*/
APP_CMD_CONFIG_CHANGED,
/**
* Команда из основного потока: системе не хватает памяти.
* Попробуйте уменьшить использование памяти.
*/
APP_CMD_LOW_MEMORY,
/**
* Команда из основного потока: действие приложения было запущено.
*/
APP_CMD_START,
/**
* Команда из основного потока: действие приложения было возобновлено.
*/
APP_CMD_RESUME,
/**
* Команда из основного потока: приложение должно создать новое сохраненное состояние
* для себя, чтобы восстанавливаться из него позднее в случае необходимости. Если вы сохранили состояние,
* выделите его с использованием malloc и поместите в android_app.savedState с
* размером android_app.savedStateSize. Память будет освобождена
* позднее.
*/
APP_CMD_SAVE_STATE,
/**
* Команда из основного потока: пауза в действии приложения.
*/
APP_CMD_PAUSE,
/**
* Команда из основного потока: действие приложения было остановлено.
*/
APP_CMD_STOP,
/**
* Команда из основного потока: действие приложения уничтожается,
* и ожидает очистки потока приложения и выхода перед обработкой.
*/
APP_CMD_DESTROY,
};
/**
* Вызовите, когда ALooper_pollAll() возвращает LOOPER_ID_MAIN, при чтении следующего сообщения команды
*приложения.
*/
int8_t android_app_read_cmd(struct android_app* android_app);
/**
* Вызовите с помощью команды, возвращенной android_app_read_cmd() для выполнения
* начальной предварительной обработки данной команды. Можно выполнить собственные
* действия для команды после вызова этой функции.
*/
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd);
/**
* Вызовите с помощью команды, возвращенной android_app_read_cmd(), для
* окончательной предварительной обработки данной команды. Необходимо завершить собственные
* действия с командой до вызова этой функции.
*/
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd);
/**
* Это функция, которую должен реализовать код приложения, представляет собой
* главный вход в приложение.
*/
extern void android_main(struct android_app* app);
#ifdef __cplusplus
}
#endif
#endif /* _ANDROID_NATIVE_APP_GLUE_H */