Wie funktioniert eine Input Pipeline?

8

Ich habe diesen Artikel über die Implementierung einer Eingabepipeline für Android gefunden, aber ich verstehe nicht wirklich, wie es funktioniert. Ich verstehe auch das Programmierkonzept einer Pipeline oder eines Pools nicht vollständig. Könnte jemand diese Konzepte erklären und wie sie als Eingabepipeline funktionieren?

TMV
quelle

Antworten:

5

Ich habe mir den Code nicht eingehend angesehen, aber die Grundidee ist, dass Eingabeereignisse in Android asynchron sind, was bedeutet, dass sie jederzeit auftreten können. Sie möchten Ihren Hauptschleifencode nicht unterbrechen, um Eingabeereignisse zu verarbeiten, da dies Ihr Spiel verlangsamen und Ihren Spielstatus auf unerwartete Weise ändern kann.

Der traditionelle Ansatz, der im Lunar Lander- Beispiel verwendet wird, besteht darin, einen synchronisierten Block um die Hauptschleife und um jeden Ihrer Eingabe-Handler zu haben, um sicherzustellen, dass sie niemals gleichzeitig auftreten. Dies mag ein gültiger Ansatz für ein kleines Spiel sein, aber wenn Ihr Spiel komplizierter wird, werden Sie feststellen, dass es nicht sehr effizient ist und möglicherweise nicht richtig funktioniert.

Der Artikel schlägt einen besseren Ansatz vor, um die Eingabeereignisse in einer Warteschlange zu speichern und an einem bekannten Punkt in Ihrer Hauptschleife zu verarbeiten. Eingabehandler verschieben das Ereignis einfach (nachdem sie in ein InputObject eingeschlossen wurden, das sie beschreibt) an das Ende der Warteschlange, und sie werden später in der processInput-Methode im Spielthread verarbeitet.

Der Autor des Artikels verwendet tatsächlich zwei Warteschlangen, eine Eingabewarteschlange und einen Eingabeobjektpool. Der Eingabeobjektpool in der Hauptaktivität wird verwendet, da wir nicht jedes Mal, wenn wir ein Eingabeereignis erhalten, neue Eingabeobjekte erstellen möchten. Dies ist schlecht, da Eingabeereignisse häufig auftreten und das Erstellen vieler Objekte dazu führt, dass der Garbage Collector häufig ausgeführt wird, wodurch Ihr Spiel abgehackt und nicht mehr reagiert. Der bessere Ansatz besteht darin, einmal einen Objektpool zu erstellen (im Grunde genommen eine Warteschlange) und Objekte aus der Warteschlange zu nehmen, wenn Sie sie benötigen, und sie in die Warteschlange zurückzugeben, wenn Sie fertig sind. Dafür ist die Warteschlange in der Hauptaktivität gedacht. Die andere Warteschlange ist eine Eingabewarteschlange im Spielthread, die tatsächlich die empfangenen Eingabeereignisse enthält und die Spielschleife mit der processInput-Methode verarbeitet.

Die Poolwarteschlange hat immer eine feste Anzahl von Objekten (angegeben durch die Konstante INPUT_QUEUE_SIZE, die beispielsweise 30 sein kann), die beim Erstellen der Aktivität in der Methode createInputObjectPool zugewiesen werden, während die Eingabewarteschlange eine variable Anzahl von Eingabeereignissen hat, die werden von der Aktivität gespeist und an die Poolwarteschlange zurückgegeben, sobald sie mit der returnToPool-Methode verarbeitet wurden. Bei diesen Warteschlangen handelt es sich um ArrayBlockingQueue- Warteschlangen, bei denen es sich um normale Warteschlangen handelt (first in first out), die mithilfe eines Arrays (im Gegensatz zu einer verknüpften Liste) implementiert werden, das unter Umständen blockiert wird, unter denen eine normale Warteschlange über- und unterläuft, bis die Warteschlange für die Warteschlange bereit ist Betrieb.

Firas Assaad
quelle
Tolle Antwort, +2 wenn ich könnte