Consideraciones de diseño para el menú de configuración en el sistema embebido

8

Estoy trabajando en un sistema integrado que interactúa con el usuario con varios botones y una pequeña pantalla gráfica.

Como nota al margen: dado que estoy en un sistema embebido, me gustaría evitar la asignación de memoria dinámica tanto como sea posible. Algo como std :: vector ni siquiera está disponible.

Necesito implementar un menú de configuración usando una estructura de menú anidada clásica 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

No estoy muy seguro sobre el mejor enfoque aquí. Leí acerca de varias formas de abordar algo como esto, como usar el patrón compuesto. Sin embargo, siempre me encuentro con algo que se veía bien "en papel", pero parece ser un desastre para implementar.

Mi pensamiento general es tener algo que una MenuNodeclase sepa sobre sus subnodos y el nodo primario al momento de la inicialización. Una Menuclase podría manejar la navegación y el procesamiento del nodo. Obviamente, cada uno MenuNodetiene que ejecutar / implementar comportamientos específicos como:

  • Informe a Menulo que quiere mostrar (el diseño / posicionamiento real no debería ser asunto del MenuNode)
  • Reaccionar a la entrada del usuario (como presionar un botón para aumentar / disminuir / cambiar un valor)
  • Acceda al valor real de interés (residen en una ApplicationSettingsclase)

¿Cuál sería la mejor manera de implementar esto?

  1. Use una MenuNodeclase base (abstracta) y cree una subclase para CADA elemento de nodo de menú. Durante la inicialización, podría proporcionar un puntero ApplicationSettingsu otras dependencias que pueda necesitar. De alguna manera se siente mal crear como 10 clases derivadas donde cada una se instanciará solo una vez.

  2. Use la misma MenuNodeclase para cada nodo e implemente la funcionalidad a través de devoluciones de llamada para liberar funciones. Por lo que leí, es bastante común "emparejar" funciones gratuitas con objetos. Sin embargo, parece que complicaría demasiado las cosas. Para cada miembro puede haber, como ReportButtonPress () o algo así, tendría que proporcionar la devolución de llamada para la implementación real durante la inicialización.

  3. Estoy seguro de que hay algo que estoy pasando por alto aquí.

Rev1.0
fuente
55
He hecho menús similares para incrustar usando C en el pasado, y esto es lo más importante que aprendí de él: mantenga la definición del menú separada de la implementación. Use el formato de archivo de texto jerárquico (JSON / XML / ...) para describir el menú, luego use lenguaje de script para convertirlo en estructuras de datos C o C ++. Esto le da libertad para cambiar la implementación a su gusto, y la capacidad de preprocesar los datos a la forma más eficiente (ayuda a evitar la asignación dinámica de memoria en tiempo de ejecución).
user694733

Respuestas:

1

Vaya con la opción 1, cree estáticamente una clase por elemento de IU para vincular eventos de entrada a acciones. De esta manera, la implementación NO asignará memoria en tiempo de ejecución.

Si su compilador de C ++ admite cierres lambda, esa es una forma ordenada de vincular los eventos de entrada a las acciones en el código de configuración del menú.

Con todo, las herramientas de verificación de código estático tienen la posibilidad de detectar errores.

Ignore las sugerencias para tener un "formato de archivo de menú" y cree sus propias herramientas. No está en el negocio de vender bibliotecas de kits de herramientas de menú, así que no lo haga.

Dices que tienes una pequeña pantalla gráfica ... ¿Es una gráfica (pantalla de mapa de bits)? Si no estás usando un kit de herramientas GUI, pregúntate por qué no. Si simplemente no encaja, lo suficientemente justo. QT incrustado o algo más ligero podría ahorrarle mucho código de widget GUI propenso a errores.

Tim Williscroft
fuente