Como funciona um pipeline de entrada?

8

Encontrei este artigo sobre a implementação de um pipeline de entrada para o Android, mas realmente não entendo como ele funciona. Também não entendo completamente o conceito de programação de um pipeline ou pool. Alguém poderia explicar esses conceitos e como eles funcionam como esse pipeline de entrada?

TMV
fonte

Respostas:

5

Não analisei o código em profundidade, mas a idéia básica é que os eventos de entrada são assíncronos no Android, o que significa que podem acontecer a qualquer momento. Você não deseja interromper o código principal do loop para processar eventos de entrada, pois isso pode tornar o jogo mais lento e alterar seu estado de maneira inesperada.

A abordagem tradicional usada na amostra Lunar Lander é ter um bloco sincronizado em torno do loop principal e em torno de cada um de seus manipuladores de entrada para garantir que eles nunca aconteçam ao mesmo tempo. Essa pode ser uma abordagem válida para um jogo pequeno, mas, à medida que o jogo se torna mais complicado, você descobre que não é muito eficiente e pode não funcionar corretamente.

O artigo sugere uma abordagem melhor para armazenar os eventos de entrada em uma fila e processá-los em um ponto conhecido no loop principal. Os manipuladores de entrada simplesmente enviam o evento (depois de agrupá-los em um InputObject que os descreve) até o final da fila e depois são processados ​​no método processInput no segmento do jogo.

O autor do artigo realmente usa duas filas, uma fila de entrada e um pool de objetos de entrada. O pool de objetos de entrada na atividade principal é usado porque não queremos continuar criando novos objetos de entrada toda vez que obtemos um evento de entrada. Isso é ruim porque os eventos de entrada acontecem com freqüência e a criação de muitos objetos fará com que o coletor de lixo seja executado com freqüência, o que torna o jogo instável e sem resposta. A melhor abordagem é criar um pool de objetos uma vez (basicamente uma fila) e pegar objetos da fila quando você precisar deles e devolvê-los à fila quando terminar. É para isso que serve a fila na atividade principal. A outra fila é uma fila de entrada no encadeamento do jogo que realmente contém os eventos de entrada recebidos e que é processado no loop do jogo usando o método processInput.

A fila do pool sempre terá um número fixo de objetos (especificados pela constante INPUT_QUEUE_SIZE, que pode ser 30, por exemplo) que são alocados no método createInputObjectPool quando a atividade é criada, enquanto a fila de entrada terá um número variável de eventos de entrada que são alimentados pela atividade e retornados à fila do pool depois que são processados ​​usando o método returnToPool. Essas filas são ArrayBlockingQueue s, que são filas normais (primeiro a entrar, primeiro a sair) implementadas usando uma matriz (em oposição à lista vinculada, por exemplo) que bloquearia, nas circunstâncias em que uma fila normal seria estourada e estourada, até que a fila esteja pronta para o evento. Operação.

Firas Assaad
fonte
Grande resposta, +2 se eu pudesse