Dienstag, 10. September 2013

Ausblick auf Version 0.5 und Technische Spielereien

Seit unserem letzten Update ist einige Zeit vergangen. Das liegt auch daran, dass wir für Version 0.5 des Musikplayers einige grundlegende Teile der Architektur über den Haufen werfen mussten um viele Funktionen für smartSound möglich zu machen, die wir als besonders sinnvoll ansehen.  Was euch hoffentlich zur DreieichCon erwartet, worüber sich Smartphone-Nutzer und Teamspeak-Spieler freuen werden und welche Technik hinter alldem steht, das erfahrt ihr in diesem Post.

Im Folgenden werde ich versuchen vereinfacht darzulegen, wie unser Musikplayer bisher aufgebaut war und wie er bald funktionieren wird. Die Programmierer unter euch werden mit Sicherheit einiges wiedererkennen, aber es mag auch für andere interessant sein zu sehen, mit welchen Problemen man sich so herumschlägt, wenn man eine Software entwickelt.

Der traditionelle Aufbau

Um überhaupt einen Überblick über die Bestandteile der Software zu behalten, werden die unterschiedlichen Programmteile in der Regel nach einem festen Schema gruppiert, das sehr häufig so aussieht:


Die Informatiker kennen diesen Aufbau als Model-View-Controler (MVC) und auch die derzeitige Version des smartSound Players ist nach dieser Struktur aufgebaut. Die Benutzerschnittstelle enthält alle Schaltflächen und Regler, in der Programmlogik wird entschieden, was eigentlich passieren soll, wenn ein bestimmter Knopf gedrückt wird und zu den Daten zählen im smartSound Player zum Beispiel die Playlisten, deren Lautstärke und welcher Eintrag mit welchem anderen verkettet ist. Ändern sich diese Daten, muss die Benutzerschnittstelle auch darüber informiert werden um die Veränderung anzeigen. Im smartSound Player etwa wird immer das Musikstück hervorgehoben, das gerade auch abgespielt wird - das funktioniert über genau diesen Mechanismus.

Nachdem wir letztes Jahr aber viel Feedback gesammelt hatten, haben wir gemerkt, dass wir mit dieser Struktur viele Dinge nicht umsetzen können, die den smartSound Player zu einem richtig guten Stück Software machen könnten. Ein Beispiel ist der Punkt Fernsteuerung, also zum Beispiel einen anderen Computer oder ein Smartphone dazu zu verwenden, um das Abspielen eines Liedes zu starten. Denn: Es gibt viele Funktionen im Player, wie etwa die Anordnung der Playlisten, die sich nicht ganz so klar der Benutzerschnittstelle oder den Daten zuordnen lassen. Auf einmal reicht die obige Dreiteilung nicht mehr und die Grobstruktur wird nicht nur unübersichtlich, sondern damit auch fehleranfällig. Dies und viele andere, kleine Probleme haben dafür gesorgt, dass wir umdenken mussten - und wir haben einen guten Weg gefunden.

Alles gleichbehandeln: Der EventBus

Wenn wir uns jetzige und zukünftige Funktionen des smartSound Players anschauen, dann haben wir eine Vielzahl von einzelnen Funktionseinheiten, wie Benutzeroberfläche, Sound abspielen, Playlisten anordnen, Hotkeys und Bibliothek. Außerdem hatten wir angekündigt Plugins, also Erweiterungen, so einfach wie möglich zu machen. Es wäre also schön, wenn wir alle diese Funktionseinheiten vollkommen gleich behandeln könnten, egal welche Funktion genau sie erfüllen oder ob sie andere Funktionseinheiten verwenden möchten. Und tatsächlich: So ein Aufbau existiert.


Die Lösung ist, dass ausnahmslos alle Nachrichten, Kommandos und Ereignisse über einen zentralen Kanal kommuniziert werden, der EventBus genannt wird. Die einzelnen Funktionseinheiten horchen auf diesem Kanal auf die Nachrichten, die sie interessieren und reagieren darauf. Die obige Abbildung ist zwar reichlich vereinfacht, aber sie taugt trotzdem für ein Beispiel. Sagen wir, es gäbe in der Benutzerschnittstelle einen Knopf, um ein bestimmtes Lied abzuspielen. Der Ablauf wäre dann wie folgt:
  1. Die Benutzerschnittstelle meldet ein Kommando der Form Spiel das Musikstück mit der Bezeichnung <x>.
  2. Die Komponente, die für das Sound abspielen zuständig ist, liest das Kommando. Sie kennt nur die Bezeichnung <x>, weiß aber nicht, welche Datei dazugehört. Um den Speicherort zu erfragen, wird ein Kommando der Form Gib mir alle Informationen zum Musikstück <x> erzeugt.
  3. Die Bibliothek liest dieses Kommando und legt diese Informationen als Antwort wiederum auf den EventBus.
  4. Sound abspielen liest die Antwort und kann mit diesen Informationen das Abspielen starten. Daraufhin wird ein Ereignis der Art Ich habe mit dem Abspielen von <x> begonnen erzeugt
  5. Die Benutzerschnittstelle liest das Ereignis und zeigt nun an, dass das Lied auch tatsächlich abgespielt wird.
Zugegeben, das wirkt alles etwas kompliziert für so eine einfache Aufgabe. Warum dieser Aufbau dennoch sinnvoll ist, wird klarer, wenn wir zum Beispiel die Funktionseinheit Hotkeys mit aufnehmen. Wenn wir ein Tastenkürzel definieren, welches das Musikstück <x> abspielen soll, wird auf einmal alles ganz einfach: Die Benutzerschnittstelle meldet, das eine Tastenkombination gedrückt wurde. Das wird von der Hotkey-Komponente gelesen und daraufhin das Kommando Spiel das Musikstück mit der Bezeichnung <x> erzeugt. Ab da ist der Ablauf genau der gleiche wie oben. Der Sound abspielen-Komponente ist es gleich, von wem das Kommando kam und auch die Benutzerschnittstelle zeigt am Ende an, dass das Musikstück abgespielt wird - egal, ob dies direkt von ihr selbst ausgelöst wurde oder nicht.

Seine wahre Macht zeigt diese Struktur aber dann, wenn der ganze Bereich Fernsteuerung betrachtet wird. Wir fügen eine weitere Komponente hinzu, die einfach alles liest, was ihr auf dem EventBus in die Finger kommt und all das über das Netzwerk verschickt. Am anderen Ende werden diese Nachrichten wieder auf einen EventBus gelegt, aber wir nehmen uns die Freiheit  hier nicht alle Komponenten anzumelden. Die Struktur sähe dann z.B. so aus:


Et voilà: Nur durch das Übertragen sämtlicher Ereignisse auf einen anderen Computer haben wir es möglich gemacht, dass wir von diesem Computer 2 aus die Soundausgabe von Computer 1 steuern können. Wir erinnern uns: Sound abspielen ist es gleich, von wem der Befehl kommt, er kann also auch von der Komponente Netzwerk stammen. Da auch das Ereignis Ich habe mit dem Abspielen von <x> begonnen an Computer 2 übermittelt wird, wird in beiden Benutzerschnittstellen das aktuell abgespielte Lied korrekt angezeigt.

Aber wir können das Ganze noch weiter treiben. Was kommt wohl bei diesem Aufbau heraus:


Ganz einfach: Computer 2 hat keine Benutzerschnittstelle, um die Abläufe zu steuern. Wird auf Computer 1 das Kommando zum Abspielen gegeben, passiert dies nicht nur auf Computer 1, wie zuvor, sondern auch auf Computer 2 (vorausgesetzt, Computer 2 besitzt das entsprechende Musikstück in seiner Bibliothek). Damit ist es für den Spielleiter beim Rollenspiel über Voicechat also ganz einfach möglich, Hintergrundmusik und Soundeffekte auf den Computern der Spieler abzuspielen - und das nahezu ohne Verzögerung.

Wer im letzten Beispiel aufgepasst hat, merkt, dass die Komponente Netzwerk doch nicht alle Nachrichten hin- und hertransportieren darf. Wer den Knackpunkt in die Kommentare schreibt, darf sich auf einen virtuellen Keks freuen ;)

Aktueller Stand

Ihr merkt also, wir haben uns etwas Arbeit gemacht um eine Struktur zu finden, mit der wir möglichst viele Einsatzmöglichkeiten unseres Players abdecken können und ihn zu einem richtigen Universalwerkzeug machen. Aber wir haben nicht nur konzipiert: Das Framework, in das jede Komponente eingebettet wird, mit der sie sich am EventBus anmelden, sowie Daten Laden und Speichern kann steht bereits. Auch unsere primäre Soundengine, NativeBass, ist bereits auf das neue System übertragen worden, gemeinsam mit einer einfachen Bibliotheksfunktion (welche die Dateinamen der aktuell verwendeten Lieder verwaltet). Unsere Meilensteine für die nächsten Wochen sind also die Übertragung der Playlistenverwaltung, des Playlistenlayouts, der Hotkeys und schließlich der Benutzeroberfläche selbst.

Unser Plan ist es zur DreieichCon am 23. und 24 November eine Version präsentieren zu können, die mindestens den Funktionsstand unserer letzten Version 0.4.3 hat, aber nach dem neuen Verfahren funktioniert. Auch eine (mindestens) rudimentäre Version der Fernsteuerung mit dem Smartphone wollen wir euch dort zeigen können.

1 Kommentar:

  1. Wunderbar, das klingt super. Ich freue mich drauf. :)

    AntwortenLöschen