TL;RD Usando técnicas de programación funcional, podemos construir fácilmente terminales sofisticados con componentes dinámicos en C++. es una biblioteca de C++ que proporciona algunos de los componentes básicos necesarios para implementar este concepto. RxTerm Aplicamos las mismas ideas en . Este es el resultado: Buckaroo Motivación Imagine que queremos crear una aplicación basada en texto que actualice la consola a medida que cambia su estado. Un gran ejemplo de esto es Curl, que ofrece una barra de progreso en vivo para las descargas. Prueba esto en tu terminal: Estas interfaces se implementan mediante . Estos son caracteres invisibles que tienen efectos secundarios, como borrar caracteres y mover el cursor. códigos de escape ANSI Podemos usar estos códigos de escape para crear interfaces de texto en vivo. Una implementación simple podría actualizar una barra de progreso como esta: Hasta aquí todo bien, pero ¿y si tenemos un caso más complicado? Idealmente, aprovecharíamos una biblioteca que resuelva estas cosas por nosotros. Solo deberíamos tener que especificar cómo debería verse la salida del terminal, y las funciones de la biblioteca descubrirían los caracteres que se imprimirán para llevarnos allí. Entonces, a un alto nivel, necesitamos tres cosas: 1. Una variable para rastrear el estado anterior de la consola 2. Una función para representar el estado actual de la aplicación 3. Una función para transformar la consola del estado anterior al siguiente estado Los desarrolladores de estarán familiarizados con este patrón. ¡Es una estrategia inteligente que en realidad se puede aplicar a cualquier dispositivo de E/S! React Además, queremos poder aprovechar los componentes de la interfaz de usuario reutilizables para cosas como barras de progreso, listas, etc. Algo como HTML, pero más simple, sería ideal. Un componente sería cualquier objeto que se pueda representar en la salida de la consola. Ejemplo de API simple Para ver hacia dónde vamos, echemos un vistazo a un ejemplo en . Con RxTerm, podemos convertir los componentes básicos de la terminal en componentes más complejos mediante la composición. Si el estado de la aplicación cambia, calculamos una nueva vista para el terminal y reemplazamos la salida visible actualmente. RxTerm Este ejemplo muestra cómo podemos diseñar un nuevo componente llamado , que imprime marcos como este: fancyCounter Aquí está el código: Como puede ver, la interfaz es de muy alto nivel. Códigos de escape ANSI Empecemos con lo básico. ¿Cómo podemos usar los códigos de escape ANSI para cambiar el color y eliminar una línea? Esta función imprime en letra roja seguida de en el color predeterminado. Las secuencias de escape mágicas ( y ) modifican la forma en que la terminal muestra los caracteres. Hello World \e[31m \e[0m Se introduce una secuencia de escape con seguida de una lista de modificadores separados por punto y coma, que termina con . Por ejemplo, imprimiría en cursiva roja sobre un fondo azul. \e[ m \e[3;31;42mTEXT TEXT También podemos imprimir para restablecer el terminal a su estado predeterminado. \e[0m Puede encontrar una lista completa en . bash-hackers.org Abstracción del estado terminal Para poder componer componentes, necesitamos una representación de alto nivel del estado de la consola. Como queremos admitir colores, una representación intuitiva de esto es un mapa de coordenadas a píxeles: Una vez que tengamos la abstracción básica para los componentes, podemos aprovechar el borrado de tipos para mantener la semántica de valores y hacer que la herencia sea un detalle de implementación: Ahora, podemos construir componentes de orden superior como un objeto de : Text Puede encontrar la implementación real . aquí Realización de transiciones de estado Imagina que queremos hacer la transición de esto: … a esto: La forma más sencilla sería eliminar las últimas 3 líneas e imprimir las nuevas líneas. Podemos eliminar la última línea imprimiendo ( ; ; ). \e[2K\r\e[1A delete line move cursor to the start of the line move cursor up one line Un enfoque más sofisticado sería calcular la diferencia y moverse a la posición de destino y editar solo los píxeles terminales que cambiaron. Para simplificar, nos ceñiremos al primer enfoque y combinaremos las partes móviles en una sola clase: La . implementación real está alojada en GitHub Veredicto ¡Vimos lo fácil que es escribir un marco de terminal reactivo y administrar las transiciones de estado sin demasiados dolores de cabeza! Puede encontrar la implementación de algunos componentes básicos en nuestro . ¡Nos encantaría ver a más personas haciendo hermosas interfaces de terminal! repositorio en GitHub Avance: Componentes estilo FRP con RxCpp Nuestro próximo artículo tratará sobre cómo podemos aprovechar para escribir aplicaciones altamente simultáneas con una gestión de estado compleja. RxCpp Más sobre Buckaroo Creamos para facilitar la reutilización de código C++. Lea más sobre esto : Buckaroo en Medium _Buck es un sistema de compilación multiplataforma y multilenguaje creado para la compilación a gran escala en Facebook. Todo Buckaroo…_hackernoon.com 7 razones para usar Buck Build _C++ es un lenguaje inusual en el sentido de que todavía no tiene un administrador de paquetes dominante (¡estamos trabajando en ello!). Como resultado... _hackernoon.com Enfoques de la gestión de dependencias de C++, o por qué construimos Buckaroo _Al escribir aplicaciones C++, inevitablemente hará uso de bibliotecas externas. ¡Ésto es una cosa buena! Reutilización de código…_hackernoon.com 6 razones por las que distribuimos bibliotecas C++ como código fuente