Wątek przeniesiony 2018-11-07 15:02 z Inżynieria oprogramowania przez Marooned.

Obsługa wyświetlacza TFT - OOP

0

Tworzę kod do obsługi wyświetlacza TFT (240x320) w C++ na platformę ARM. W tej chwili mam dwie klasy: ST7789V jako driver (funkcje init, write, ...), i dziedziczącą po niej prywatnie klasę Display która udostępnia rysowanie prostych, prostokątów, itd.Teraz do tej klasy chciałem dodać możliwość wyświetlenia obrazków (BMP, GIF) z karty SD.

Czy funkcja rysująca obraz powinna być odpowiedzialna za otwarcie i zamknięcie pliku? Innymi słowy, czy powinna dostać wskaźnik na otwarty plik, czy ścieżkę do pliku?

0

Czy funkcja rysująca obraz powinna być odpowiedzialna za otwarcie i zamknięcie pliku? Innymi słowy, czy powinna dostać wskaźnik na otwarty plik, czy ścieżkę do pliku?
Funkcja rysujaca powinna dostac kolekcje danych ktore ma wyswietlic a nie plik. Obroke pliku na dana strukture zrob w obosnej klasie i przekaz ta strukture/klase do klasy wyswietlajacej

0

Ale czy takie podejście nie wymaga załadowania pliku do pamięci RAM. Właściwie od razu mogłem napisać, że dysponuję 128 + 32 kB ramu (Procek to STM32L476), i nie mogę używać dynamicznej alokacji pamięci.

0

to bedziesz musial robic to krokowo
https://stackoverflow.com/questions/34751873/how-to-read-huge-file-in-c
Ladujesz powiedzmy 4kB pliku. Robisz to co pisalem tylko ze jako part, wiec potrzebujesz jedynie wiedziec std::map<kolumna, sumaWynikow> i wczytujesz znowu kawalek pliku

3

W tej chwili mam dwie klasy: ST7789V jako driver (funkcje init, write, ...), i dziedziczącą po niej prywatnie klasę Display

A co, gdybyś teraz miał napisać sterownik dla SSD1963 i chciał mieć funkcję, która przyjmie po prostu Display? :-)

Powinieneś to zaprojektować na odwrót, czyli mieć klasę Display z abstrakcyjną metodą drawPixel(x, y), a następie klasę ST7789V, która dziedziczy po Display i realizuje tę metodę.

Taki design nadal byłby zły, choć nieco lepszy od Twojego aktualnego.

IMHO najsensowniej rozplanować to kompozycją (w pseudokodzie):

interface LcdDriver {

  void drawPixel(uint x, uint y);

}

class ST7789V
  implements Driver {

  /* ... */

}

class SSD1963
  implements Driver {

  /* ... */

}

class Display {

  Display(LcdDriver driver) {
    this->driver = driver;
  }

  void drawPixel(uint x, uint y) {
    this->driver->drawPixel(x, y);
  }

  void drawRectangle(uint x, uint y, uint width, uint height) {
    for (...) {
      /* ... */
    }
  }

}

// i potem gdziekolwiek:

Display createDisplay() {
  return new Display(
    new DowolnySterownik()
  );
}

void drawSomething(Display display) {
  display->drawText(...);
  display->drawRectangle(...);
}
0
fasadin napisał(a):

Funkcja rysujaca powinna dostac kolekcje danych ktore ma wyswietlic a nie plik. Obroke pliku na dana strukture zrob w obosnej klasie i przekaz ta strukture/klase do klasy wyswietlajacej

...wiec potrzebujesz jedynie wiedziec std::map<kolumna, sumaWynikow>

Przyznam, że dalej nie rozumiem, jak to zrobić. I nie rozumiem o co masz na myśli pisząc o wykorzystaniu std::map. W klasie Display mam metody:

void addressControl(Direction direction);
void setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
void write(const uint16_t *px_data, uint32_t size);

Teraz powinienem utworzyć nową klasę np. Image i w niej mieć publiczną metodę:

void draw(const Display *display, uint16_t x, uint16_t y, const char *path);

I to klasa Image ma być odpowiedzialna, za otwarcie pliku, odczytanie / zdekodowanie pikseli i wyświetlenie ich za pomocą metody write z klasy Display?

1 użytkowników online, w tym zalogowanych: 0, gości: 1