Considerações de design para o menu de configuração no sistema incorporado

8

Estou trabalhando em um sistema incorporado que faz interface com o usuário com vários botões e uma pequena tela gráfica.

Como uma observação lateral: Como estou em um sistema incorporado, gostaria de evitar o máximo possível da alocação dinâmica de memória. Algo como std :: vector nem está disponível.

Preciso implementar um menu de configuração usando uma estrutura de menu aninhada clássica como esta:

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

Estou muito inseguro sobre a melhor abordagem aqui. Eu li sobre várias maneiras de abordar algo assim, como usar o Padrão composto. No entanto, eu sempre topo com algo que parecia bom "no papel", mas parece ser uma bagunça de implementar.

Meu pensamento geral é ter algo que uma MenuNodeclasse saiba sobre seus subnós e nó pai na inicialização. Uma Menuclasse poderia lidar com a navegação e o processamento do nó. Obviamente, todos MenuNodeprecisam executar / implementar comportamentos específicos, como:

  • Relate o Menuque deseja exibir (o layout / posicionamento real não deve ser uma preocupação do MenuNode)
  • Reagir à entrada do usuário (como pressionar um botão para aumentar / diminuir / alternar um valor)
  • Acesse o valor real do interesse (eles residem em uma ApplicationSettingsclasse)

Qual seria a melhor maneira de implementar isso?

  1. Use uma MenuNodeclasse base (abstrata) e crie uma subclasse para CADA item do nó do menu. Durante a inicialização, eu poderia fornecer um ponteiro para ApplicationSettingsou outras dependências que ele possa precisar. De alguma forma, parece errado criar 10 classes derivadas, nas quais cada uma será instanciada apenas uma vez.

  2. Use a mesma MenuNodeclasse para cada nó e implemente a funcionalidade por meio de retornos de chamada para liberar funções. Pelo que li, é bastante comum "acoplar" funções livres com objetos. No entanto, parece que isso complicaria demais as coisas. Para cada membro, como ReportButtonPress () ou algo assim, eu precisaria fornecer o retorno de chamada para a implementação real durante a inicialização.

  3. Estou certo de que há algo que estou ignorando aqui.

Rev1.0
fonte
5
Eu criei menus semelhantes para incorporar usando C no passado, e essa é a maior coisa que aprendi com ele: mantenha a definição de menu separada da implementação. Use o formato de arquivo de texto hierárquico (JSON / XML / ...) para descrever o menu e use a linguagem de script para convertê-lo em estruturas de dados C ou C ++. Isso lhe dá liberdade para alterar a implementação como desejar e capacidade de pré-processar os dados da forma mais eficiente (ajuda a evitar a alocação dinâmica de memória em tempo de execução).
user694733

Respostas:

1

Vá com a opção 1, crie estaticamente uma classe por item de interface do usuário para vincular eventos de entrada a ações. Dessa forma, a implementação NÃO alocará memória em tempo de execução.

Se o seu compilador C ++ suportar fechamentos lambda, essa é uma maneira organizada de vincular os eventos de entrada às ações no código de configuração do menu.

Com tudo, as ferramentas de verificação de código estático têm a chance de detectar erros.

Ignore as sugestões para ter um "formato de arquivo de menu" e crie suas próprias ferramentas. Você não está vendendo bibliotecas de kits de ferramentas de menu, então não faça isso.

Você diz que possui uma pequena tela gráfica ... Essa é uma tela gráfica (mapa mapeado por bits?) Se você não estiver usando um kit de ferramentas da GUI, pergunte-se por que não? Se simplesmente não couber, é justo o suficiente. O QT incorporado ou algo mais leve pode economizar muito código de widget da GUI propenso a erros.

Tim Williscroft
fonte