Resaltando bloques en Pilas
Pilas permite visualizar el código que se está ejecutando en todo momento.
La aplicación pinta con un color diferente las lineas de código que efectivamente se ejecutaron:
Este resaltado es útil incluso para los que programamos hace tiempo. Porque
sin esto te ves obligado a llenar el código de console.log
para asegurarte
de qué está haciendo el programa.
Sin embargo, cuando empecé a jugar con la idea de añadir bloques a Pilas, noté que el resaltado de código era algo que faltaba. Sin resaltado me veo obligado a tener que imaginarme el programa ejecutando en mi cabeza, imaginando qué bloque se está ejecutando.
Claramente necesitaba poder resaltar bloques en pilas.
El problema
La biblioteca que estoy utilizando para incorporar bloques tiene
una función dedicada
a resaltar bloques llamada highlightBlock
:
El problema es que el editor de pilas está dividido en varios componentes independientes entre
sí. Por ejemplo el área que visualiza el juego es un componente que a su vez tiene
un iframe
dentro para independizar el scope
de ejecución. Y a su vez, el área de bloques
también está en su propio componente con un iframe
:
Así que para resaltar bloque tuve que seguir varios pasos.
Instrumentando código
Al igual que como hice con el resaltado de código en el editor de texto, aquí tuve que insertar automáticamente código de seguimiento para saber qué partes del código resaltar.
Por suerte Blockly ya incluye algo para hacer esto muy fácilmente, solamente hay que escribir algo como esto:
Blockly.JavaScript.STATEMENT_PREFIX = `
this.pilas.notificar_ejecucion_del_bloque(%1, this.id);
`;
Blockly se va a encargar de insertar esta llamada a pilas antes de cada una de las sentencias, por ejemplo:
Quienes usen pilas no van a notar que este código se agrega automáticamente, ya que esta versión modificada el código se genera en memoria y se procesa justo antes de poner en ejecución el juego.
Almacenando información de ejecución
Para saber qué bloques ir resaltando hice que la función notificar_ejecucion_del_bloque
simplemente almacene en un diccionario todos los bloques
a resaltar por actor.
Así, el diccionario instrumentacion_de_bloques
se va llenando con
todos los bloques que se ejecutan en un solo ciclo del pilas.
Por ejemplo, en una escena donde hay dos actores con bloques el diccionario puede quedar así:
{
1278: [
"M.ujdyfst~C9SNlx%%~W",
"n#Df-%|n/TtB*Qc([e(d"
],
1585: [
"Sux_IEGyGca,_Slu#R?!"
]
}
Los números 1278
y 1585
son los identificadores de actores, mientras
que las cadenas de texto como "M.ujdyfst...
son los identificadores
de bloques.
Resaltando bloques
Ahora, con este diccionario la tarea se volvió mucho más sencilla, porque pude separar en dos lugares independientes “qué bloques colorear” vs “dónde colorearlos”.
Pilas tiene un sistema de eventos similar al que comenté en este otro post, así que pude enviar el diccionario a través de un evento que puede capturar el componente de Blockly.
Este es un ejemplo de cómo quedó la integración cuando se usa el modo pausa:
Conclusión
Me quedé muy contento con la forma en la que se colorean los bloques. Pensé que iba a ser mucho más sencillo de implementar, pero aún así creo que llegué a una buena forma de resolverlo.
Más adelante voy a poner a prueba el rendimiento a ver si no afecta mucho la velocidad del motor.