Как работает входной конвейер?

8

Я нашел эту статью о реализации конвейера ввода для Android, но я не очень понимаю, как он работает. Я также не совсем понимаю концепцию программирования конвейера или пула. Может ли кто-нибудь объяснить эти концепции и как они работают в качестве входного конвейера?

ВТМ
источник

Ответы:

5

Я не рассматривал код подробно, но основная идея заключается в том, что входные события асинхронны в Android, что означает, что они могут произойти в любое время. Вы не хотите прерывать код основного цикла для обработки входных событий, потому что это может замедлить вашу игру и может неожиданно изменить ее игровое состояние.

Традиционный подход, используемый в образце Lunar Lander, состоит в том, чтобы иметь синхронизированный блок вокруг основного цикла и вокруг каждого из ваших обработчиков ввода, чтобы гарантировать, что они никогда не произойдут в одно и то же время. Это может быть правильным подходом для маленькой игры, но, поскольку ваша игра становится более сложной, вы обнаружите, что она не очень эффективна и может работать неправильно.

В статье предлагается лучший подход для хранения входных событий в очереди и их обработки в известной точке вашего основного цикла. Обработчики ввода просто помещают событие (после помещения их в описывающий их объект InputObject) в конец очереди, а затем они обрабатываются в методе processInput в игровом потоке.

Автор статьи фактически использует две очереди: очередь ввода и пул объектов ввода. Пул объектов ввода в основном действии используется, потому что мы не хотим продолжать создавать новые объекты ввода каждый раз, когда получаем событие ввода. Это плохо, потому что входные события происходят часто, и создание большого количества объектов приведет к частому запуску сборщика мусора, что делает вашу игру прерывистой и не отвечает. Лучше всего создать пул объектов один раз (в основном очередь) и брать объекты из очереди, когда они вам нужны, и возвращать их в очередь, когда вы закончите. Для этого и предназначена очередь в основной деятельности. Другая очередь является входной очередью в игровом потоке, которая фактически содержит полученные входные события и которая обрабатывается игровым циклом с использованием метода processInput.

Очередь пула всегда будет иметь фиксированное количество объектов (заданных константой INPUT_QUEUE_SIZE, например, 30), которые выделяются в методе createInputObjectPool при создании действия, тогда как входная очередь будет иметь переменное число входных событий, которые передаются действием и возвращаются обратно в очередь пула после обработки с использованием метода returnToPool. Эти очереди представляют собой ArrayBlockingQueue, которые представляют собой обычные очереди (сначала в порядке поступления ), реализованные с использованием массива (в отличие от связанного списка, например), который будет блокироваться в ситуациях, когда обычная очередь будет переполнена и опустошена до тех пор, пока очередь не будет готова для операция.

Firas Assaad
источник
Отличный ответ, +2, если бы я мог