Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| lehrkraefte:blc:informatik:ffprg2-2021:l8 [2021/12/07 07:02] – created Ivo Blöchliger | lehrkraefte:blc:informatik:ffprg2-2021:l8 [2021/12/07 07:30] (current) – Ivo Blöchliger | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Klassen und Instanzen ====== | ||
| + | |||
| + | <code c++> | ||
| + | // Definition typischer in .h Datei | ||
| + | class Beispiel { | ||
| + | private: | ||
| + | int instanz_variable = 42; | ||
| + | |||
| + | public: | ||
| + | |||
| + | static int klassen_variable; | ||
| + | void hallo_instanz(); | ||
| + | static void hallo_klasse(); | ||
| + | |||
| + | }; // Strichpunkt nach Klassendefinition! | ||
| + | |||
| + | // Implementation typischweise in .cpp-Datei | ||
| + | |||
| + | void Beispiel:: | ||
| + | Serial.printf(" | ||
| + | instanz_variable++; | ||
| + | klassen_variable++; | ||
| + | } | ||
| + | |||
| + | void Beispiel:: | ||
| + | Serial.printf(" | ||
| + | klassen_variable++; | ||
| + | } | ||
| + | |||
| + | // Diese Zeile **muss** in einer .cpp-Datei stehen. | ||
| + | int Beispiel:: | ||
| + | |||
| + | // Start vom Programm (normalerweise main() in C++, ausser mit Arduino-Framework) | ||
| + | void setup() { | ||
| + | Beispiel bsp1; // Neues Beispiel | ||
| + | bsp1.hallo_instanz(); | ||
| + | bsp1.hallo_instanz(); | ||
| + | Beispiel:: | ||
| + | | ||
| + | Beispiel* bsp_pointer = new Beispiel(); | ||
| + | bsp_pointer-> | ||
| + | bsp1.hallo_instanz(); | ||
| + | bsp_pointer-> | ||
| + | | ||
| + | delete bsp_pointer; | ||
| + | bsp_pointer = nullptr; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | ====== Callbacks ====== | ||
| + | Callbacks sind Funktionen, die registriert werden und dann aufgerufen, wenn etwas passiert (z.B. ein Klick). Das ist oft besser als polling (permanent abfragen, ob was geklickt wurde). | ||
| + | |||
| + | Das Problem ist, dass damit keine (bzw. nicht ohne weiteres) Instanz-Methoden registriert werden können, weil dazu eine Referenz (oder Pointer) auf die Instanz gebraucht wird. Dazu gibt es verschiedene Lösungsansätze: | ||
| + | * Klassenvariable, | ||
| + | * Wenn der Callback die Möglichkeit bietet, zusätzliche Daten zu übermitteln, | ||
| + | * Je nachdem ist es möglich eine Closure zu machen und so einen Pointer auf die Instanz zu übergeben (nicht möglich mit unserer lvgl-Version, | ||
| + | |||
| + | ===== User-Data in lvgl ===== | ||
| + | In jedem lvgl-Objekt kann ein Pointer als user-data gespeichert werden. Dieser Pointer hat den Typ (void*), d.h. einfach eine Speicheradresse ohne Information, | ||
| + | |||
| + | Dieser Pointer wird dann mittels Typenumwandlung (cast) zum gewünschten Pointer gemacht: | ||
| + | <code c++> | ||
| + | // In einer Instanz-Methode im GUI-Objekt ein Pointer auf die aktuelle Instanz speichern: | ||
| + | lv_obj_set_user_data(obj, | ||
| + | |||
| + | // Im der Callback-Funktion die Instanz auslesen und darauf die Instanz-Methode aufrufen: | ||
| + | Beispiel* bsp = (Beispiel*) obj-> | ||
| + | bsp-> | ||
| + | </ | ||
| + | |||
| + | ===== Implementation eines Callbacks ===== | ||
| + | Es gibt zwei Möglichkeiten: | ||
| + | * Klassenmethode (static) | ||
| + | * Anonyme Funktion (mit user_data im gui-Objekt) | ||
| + | |||
| + | <code c++> | ||
| + | lv_obj_set_event_cb(button, | ||
| + | if (event != LV_EVENT_SHORT_CLICKED) return; | ||
| + | ((Beispiel*)(button-> | ||
| + | } | ||
| + | ); | ||
| + | </ | ||
| + | |||
| + | Je nach Definition des Callbacks könnten in die eckigen Klammern noch Variablen eingetragen werden, auf die die Funktion Zugriff hat (closure). Das geht aber nicht mit lvgl-Callacks. | ||
| + | |||