Search code examples
c++architectureabstractionreusability

How do you abstract the information to be displayed in a screen?


I'm writing an application that requires me to write information to a TFT display (kinda like a gameboy display). I'm outputting the information to the display line by line. The way I'm doing it now requires me to have a function for each different screen. Like:

void displayWelcomeMessage();
void displayInsertCoinMessage();
void displayGoodByeMessage();

Each function follows this logic:

void displaWelcomeMessage()
{
  writeline(0, "Hi David");
  writeline(1, "Welcome");
  writeline(2, "Back!");
}

Problem: I hate to have a different function for each screen. It's not scalable at all, imagine if I had 500 different screens. How do I abstract the process of writing to the display? So that I end up with a single generic function responsible for writing to the display.

Thank you


Update

Following "Useless's" and Michael.P's advice, what I will probably end up doing is storing the format of each message in a file:

DisplayMessages.cfg

WELCOME_MESSAGE_1 = "Hi %name"
WELCOME_MESSAGE_2 = "Welcome"
WELCOME_MESSAGE_3 = "back!"

And in the code I will do something like:

using Message = std::vector<QString>;

void login(){

 //Do Stuff...

 QString line
 Message welcomeMessage;

 line=getMessageStructureFromCfg("WELCOME_MESSAGE_1").arg(userName); // loads "Hi %name" and replaces %name with the content of userName
 welcomeMessage.pushBack(line); // pushes the first line to welcomeMessage

 line=getMessageStructureFromCfg("WELCOME_MESSAGE_2"); // loads "Welcome"
 welcomeMessage.pushBack(line); // pushes the second line to welcomeMessage

 line=getMessageStructureFromCfg("WELCOME_MESSAGE_3"); // loads "back!"
 welcomeMessage.pushBack(line); // pushes the third line to welcomeMessage

 displayMessage(welcomeMessage);

}

void displayMessage(Message const &msg) {
 int i = 0;
 for (auto &line : msg) {
   writeline(i, line);
   i++;
 }
}

Thank you all for your help!

PS: Further improvements can be made if the file containing the messages structure used JSON instead of plain text. This way you could just iterate the child members(the lines) of each message and process accordingly


Solution

  • How do you abstract the information to be displayed in a screen?

    The same way you abstract any information - you move the data out of the code and into a data structure.

    Your displayXMessage() functions perform a fixed sequence of calls on a fixed sequence of hardcoded string literals. So, split the algorithm from the data the usual way, by passing the data as an argument:

    using Message = std::vector<std::pair<int, std::string>>;
    
    void displayMessage(Message const &msg) {
      for (auto &line : msg) {
        writeline(line.first, line.second);
      }
    }
    

    and call it with the appropriate data:

    Message welcomeMsg { {0, "Hi David"}, 
                         {1, "Welcome"},
                         {2, "Back!"}
                       };
    displayMessage(welcomeMsg);