miércoles, 2 de marzo de 2016

El paso a wxWidgets 3.x

Como comenté hace poco, la actualización de la biblioteca wxWidgets (wx) es un cambio interno en ZinjaI y PSeInt que vengo esquivando hace rato. wx es conocida principalmente por permitir generar interfaces (GUIs) de forma portable (entre plataformas). Pero en realidad es un framework completo, que ofrece muchísimas otras abstracciones de distinta índole. Por ejemplo, gestiona el lanzamiento de procesos hijos y las tuberías de entrada/salida para controlarlos, ofrece una interfaz para conexiones TCP/IP, tiene sus propios threads, su propio manejo de cadenas, etc. En ZinjaI y PSeInt uso casi todo eso, lo que es de interfaz, y también lo que no.

Estoy utilizando la última release estable de wx 2, la versión 2.8.12, que ya tiene más 6 años. Para cualquier biblioteca de este tipo eso es una eternidad. Desde hace un tiempo mucho más corto ya tenemos disponible wxWidgets 3 estable, y acaba de publicarse hace horas su primer actualización grande (la versión 3.1). Pero en mi caso, cambiar a la versión 3 no es simplemente instalarla y recompilar.

Izquierda: wxWidgets 2.8.21, Derecha: wxWidgets 3.0.2. En la versión de la izquierda
aún no funcionan ni el coloreado de sintaxis, ni el árbol de procesos y variables.

Con unos cuantos parches, pude compilar la interfaz principal de PSeInt con wx 3, pero hay muchas cosas que todavía no andan. Por ejemplo, la última vez que probé, "no me funcionaba" el coloreado de sintaxis de scintilla. Por "no funciona" entiéndase, compila, ejecuta, no se ve mensaje de error, pero tampoco se ve coloreado (todo el texto negro). Y sin contar, que para peor en la versión 2 de wx no uso scintilla tal como viene, sino que la versión de scintilla que uso también tiene algunos argregados mios que necesito en ZinjaI y PSeint. Agregados que tendré que rehacer también en la versión 3.

Además de estos detalles, quería aprovechar el trabajo para de paso hacer el código compatible con las compilaciones Unicode de la biblioteca. La biblioteca tiene su propia gestión de cadenas, y se puede compilar para que trabaje directamente (y casi que solo con) caracteres ascii (el modo Ansi), o para que permita utilizar otras codificaciones, y convertir entre ellas (el modo Unicode). En la versión 2, en el modo Ansi, la conversión de/a std::string o char* en un código fuente ascii, era directa y transparente. En el modo Unicode hay que utilizar funciones de conversión por todas partes. Trabajé siempre en modo Ansi, porque era más cómodo y rápido, pero no es lo más general ni más recomendable. Impone algunas limitaciones, y trae algunos problemas.

Tenía parches en PSeInt y wxWidgets 2 para estos problemas, pero no soluciones definitivas. Por ejemplo, por estas cosas las rutas con acentos, eñes, u otros caracteres raros no se toman bien en muchos sistemas GNU/Linux. Cuando la codificación por defecto del sistema es UTF-8 (lo más usual en estos días), y ZinjaI o PSeInt fuerzan el modo Ansi (sería ISO-8859) no se aplican todas las conversiones como deberían.

Si intentamos compilar la última release de ZinjaI con la versión 3.0.2 Unicode obtenemos unos 96 errores de
compilación, pero hay ocultos muchos más de lógica, que son los difíciles de encontrar.  Con la compilación
Ansi se reducen un tercio los de compilación, pero se evitan la mayoría de los nuevos errores de lógica.

Hacer todo compatible con el modo Unicode, en ZinjaI requiere muchísimo más trabajo y análisis, por cosas como utilizar wx para comunicarme con gdb, y explotar la conversión a cstring para parsear las respuestas. Al pasar a modo Unicode ya ni puedo confiar en que acceder a una posición de la cadena sea O(1). Así que probablemente primero pase a las compilaciones Ansi de wx 3 y deje el problema del Unicode para más adelante. Y para rematar, aún con la versión Ansi, en wx 3 el tema de las cadenas se puso un poco más estricto porque, por dentro, ahora ambos modos usan Unicode. Y la "interfaz" Ansi está cerca de ser declarada deprecated.

Por último, está el detalle del soporte para Mac. Las versiones que publico para Mac OS X se compilan desde GNU/Linux con una versión cruzada de gcc que obtuve de IMCROSS. Esta versión de gcc es basatante vieja, y no me sirve para compilar wx 3. Intenté un día en la Mac de un amigo compilar wx 3 de forma nativa, en una de las últimas versiones de OS X, y nuevamente tuve problemas que no pude resolver. Digamos que el "configure && make" de toda la vida no funcionó, y obtuve a cambio cientos de errores de compilación. Había probado con wx 3.0, tengo la esperanza de que con la versión 3.1 se solucionen varios de estos problemas, pero igual necesito encontrar una forma de no depender de una PC ajena para empaquetar las futuras versiones.

Ejemplo de nuevas posibilidades que ofrece wx 3: un mecanismo para insertar mensajes entre
lineas en el código, llamado anotaciones, que puedo usar para los mensajes de error.

En resumen, el cambio requiere muchísimo trabajo, se hace cada vez más inevitable, y lo peor es que no se verá inmediatamente reflejado en la experiencia del usuario ni en nuevas funcionalidades. Pero es una inversión a futuro. En el medio del camino voy a tener la posibilidad de rediseñar y simplificar unas cuantas cosas, y la nueva versión de la biblioteca solucionará definitivamente varios problemas plataforma-dependientes que vengo parcheando hace rato. Finalmente, cuando todo converja, abrirá la puerta a mejoras más tangibles en la interfaz.

8 comentarios:

  1. Como dije en su entrada anterior, sería bueno que la actualizaciones de wxWidgets fueran menos traumáticas para el proyecto.

    ResponderEliminar
    Respuestas
    1. Lo traumático es culpa mía mayormente por haber usado la compilación Ansi. De haber usado desde el principio la versión Unicode (que es la que se recomienda hace años, y la que incluyen normalmente las distros) hoy no tendría tantos problemas (ya los habría aprendido a resolver antes con la versión 2).

      Eliminar
  2. Adicional a lo que comenté en la publicación anterior "Arranca el 2016", ¿Es posible que para las nuevas versiones (Posiblemente las que incluyan wxWidgets) se publiquen versiones algo así como versiones alfas y betas para ser probadas por los usuarios?
    Es decir, tratar de liberar una versión de PSeInt muy básica (Ligera) como alfa para ser probada y de acuerdo a la retroalimentación de los usuarios, ir añadiendo funcionalidades, características y mejoras.
    Lo anterior, debido a que usted ha comentado en anteriores oportunidades que el cambio a wxWidgets es bastante complejo y dispendioso y podría tomar mucho tiempo.

    ResponderEliminar
    Respuestas
    1. Muy probablemente sea así, ya lo hice con ZinjaI en algunas oportunidades. Pero ahora seguramente podré subir para cada nueva versión dos paquetes equivalentes: una compilación con wx 2 como estable para la mayoría, y una versión de prueba alternativa con wx 3 para quienes quieran ayudar a encontrar diferencias.

      Eliminar
    2. La version actual (2018) esta compilada con wx 2 o 3?

      Eliminar
  3. las anotaciones, podrían usarce también para agregar comentarios, que se puedan ocultar y visualizar rápidamente?

    ResponderEliminar
  4. Ven por eso es que hay que programar en Phyton y se quitan todos esos problemas

    ResponderEliminar
  5. hola alguno conoce alguna web para descargar las librerias? eh estado buscando y las que encontre hablan de las librerias pero no veo donde descargarlas

    ResponderEliminar