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 MenuNode
classe saiba sobre seus subnós e nó pai na inicialização. Uma Menu
classe poderia lidar com a navegação e o processamento do nó. Obviamente, todos MenuNode
precisam executar / implementar comportamentos específicos, como:
- Relate o
Menu
que deseja exibir (o layout / posicionamento real não deve ser uma preocupação doMenuNode
) - 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
ApplicationSettings
classe)
Qual seria a melhor maneira de implementar isso?
Use uma
MenuNode
classe base (abstrata) e crie uma subclasse para CADA item do nó do menu. Durante a inicialização, eu poderia fornecer um ponteiro paraApplicationSettings
ou 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.Use a mesma
MenuNode
classe 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.Estou certo de que há algo que estou ignorando aqui.
fonte
Respostas:
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.
fonte