Entwurfsüberlegungen für das Konfigurationsmenü auf einem eingebetteten System

8

Ich arbeite an einem eingebetteten System, das über mehrere Tasten und ein kleines Grafikdisplay mit dem Benutzer verbunden ist.

Als Randnotiz: Da ich mich auf einem eingebetteten System befinde, möchte ich die dynamische Speicherzuweisung so weit wie möglich verhindern. So etwas wie std :: vector ist nicht einmal verfügbar.

Ich muss ein Konfigurationsmenü mit einer klassischen verschachtelten Menüstruktur wie dieser implementieren:

Level A Node 1
 -> Level B Node 1
    -> Level C Node 1
 -> Level B Node 2
 -> Level B Node 3
Level A Node 2
Level A Node 3

Ich bin mir nicht sicher, wie ich hier am besten vorgehen soll. Ich habe über verschiedene Möglichkeiten gelesen, wie ich mit dem zusammengesetzten Muster an so etwas herangehen kann. Ich stoße jedoch immer auf etwas, das "auf dem Papier" gut aussah, aber anscheinend ein Chaos zu implementieren scheint.

Mein allgemeiner Gedanke ist, eine MenuNodeKlasse zu haben, die bei der Initialisierung über ihre Unterknoten und übergeordneten Knoten Bescheid weiß. Eine MenuKlasse könnte die Knotennavigation und -verarbeitung übernehmen. Offensichtlich muss jeder ein MenuNodebestimmtes Verhalten ausführen / implementieren wie:

  • Berichten Sie an das, Menuwas angezeigt werden soll (das tatsächliche Layout / die Positionierung sollte nicht das Anliegen des sein MenuNode).
  • Reagieren Sie auf Benutzereingaben (wie ein Tastendruck zum Erhöhen / Verringern / Umschalten eines Werts)
  • Zugriff auf den tatsächlichen Wert von Interesse (sie befinden sich in einer ApplicationSettingsKlasse)

Was wäre der beste Weg, dies umzusetzen?

  1. Verwenden Sie eine (abstrakte) MenuNodeBasisklasse und erstellen Sie eine Unterklasse für JEDES Menüknotenelement. Während der Initialisierung könnte ich einen Zeiger auf ApplicationSettingsoder andere Abhängigkeiten bereitstellen, die es möglicherweise benötigt. Irgendwie fühlt es sich falsch an, 10 abgeleitete Klassen zu erstellen, in denen jede nur einmal instanziiert wird.

  2. Verwenden Sie MenuNodefür jeden Knoten dieselbe Klasse und implementieren Sie Funktionen durch Rückrufe auf freie Funktionen. Nach dem, was ich gelesen habe, ist es ziemlich üblich, freie Funktionen mit Objekten zu "koppeln". Es fühlt sich jedoch so an, als würde es die Dinge überkomplizieren. Für jedes Mitglied könnte es sein, wie ReportButtonPress () oder so, ich müsste den Rückruf für die eigentliche Implementierung während der Initialisierung bereitstellen.

  3. Ich bin sicher, dass ich hier etwas übersehen habe.

Rev1.0
quelle
5
Ich habe in der Vergangenheit ähnliche Menüs für Embedded mit C erstellt, und dies ist das Größte, was ich daraus gelernt habe: Halten Sie die Menüdefinition von der Implementierung getrennt. Verwenden Sie das hierarchische Textdateiformat (JSON / XML / ...), um das Menü zu beschreiben, und verwenden Sie dann die Skriptsprache, um es in C- oder C ++ - Datenstrukturen zu konvertieren. Auf diese Weise können Sie die Implementierung nach Belieben ändern und die Daten auf die effizienteste Form vorverarbeiten (dies hilft, eine dynamische Speicherzuweisung zur Laufzeit zu vermeiden).
user694733

Antworten:

1

Wählen Sie mit Option 1 statisch eine Klasse pro UI-Element, um Eingabeereignisse an Aktionen zu binden. Auf diese Weise weist die Implementierung zur Laufzeit KEINEN Speicher zu.

Wenn Ihr C ++ - Compiler Lambda-Schließungen unterstützt, können Sie die Eingabeereignisse auf saubere Weise an Aktionen in Ihrem Menü-Setup-Code binden.

Bei allem, was zur Überprüfung statischen Codes verwendet wird, besteht die Möglichkeit, dass Fehler erkannt werden.

Ignorieren Sie Vorschläge für ein "Menü-Dateiformat" und erstellen Sie Ihre eigenen Tools. Sie verkaufen keine Menü-Toolkit-Bibliotheken, also tun Sie es nicht.

Sie sagen, dass Sie eine kleine grafische Anzeige haben ... Ist das eine grafische Anzeige (Bitmap-Anzeige?)? Wenn Sie kein GUI-Toolkit verwenden, fragen Sie sich, warum nicht? Wenn es einfach nicht passt, fair genug. QT Embedded oder etwas Leichteres erspart Ihnen möglicherweise viel fehleranfälligen GUI-Widget-Code.

Tim Williscroft
quelle