Architecture

Où passe la frontière, ce que fait une image, et ce que le langage a décidé plutôt que la conception.

La frontière

Le C en dessous fait quatre choses : ouvrir une fenêtre, rapporter ce que l'utilisateur a fait, remettre un tampon de pixels, et se rendormir jusqu'à ce qu'il se passe quelque chose. Il ne dessine pas. Toute la surface C est runtime/kv.h — un tampon d'image, un bloc d'octets, une structure d'événement, et les accesseurs de chacun, tous les chauds en static inline et donc inlinés dans Keal.

C'est pour ça qu'ajouter Windows puis Linux n'a rien changé au-dessus de runtime/. Un backend, c'est un fichier contre une douzaine de fonctions.

the files
runtime/
  kv.h            the whole C surface: framebuffer, blob, event, accessors
  kv_cocoa.m      macOS: NSWindow, a layer-backed view, a ring of events
  kv_win32.c      Windows: the same, through Win32 and GDI
  kv_x11.c        Linux: the same, through Xlib alone
src/
  ffi.keal        the only file in keal-view that mentions C
  color.keal      colour packed in an Int — the per-pixel loop
  geom.keal       rectangles, insets, and the cell-coverage function
  canvas.keal     the rasteriser
  font.keal       TrueType, parsed and rasterised
  text.keal       measuring, wrapping, ellipsising, caret hit-testing
  theme.keal      the palettes, the metrics, and Paint
  view.keal       the tree an application describes
  layout.keal     measuring it and giving every node a rectangle
  paint.keal      every widget's appearance, and icons drawn from strokes
  ui.keal         what outlives a tree rebuilt every frame
  event.keal      what happened, in points
  state.keal      Cell<T> and one revision counter
  dock.keal       splits, tabs, and dragging a panel between them
  popup.keal      menus, dialogs and tooltips
  app.keal        the loop, and how input gets back to the application

Ce qu'est une image

Construire l'arbre depuis l'état, le mettre en page, lui remettre les événements arrivés, et — si un gestionnaire a changé quelque chose — le reconstruire et le remettre en page une fois de plus avant de dessiner. Distribuer les événements contre une mise en page fraîche plutôt que celle de l'image précédente est ce qui fait qu'un clic atterrit sur ce qui était sous le pointeur au moment où il a eu lieu, y compris sur l'image où la fenêtre a changé de taille.

L'arbre est jeté et refait. Il n'y a pas de comparaison d'arbres, donc rien à oublier d'invalider. Ce qui lui survit — survol, focus, décalages de défilement, curseurs d'insertion — est rangé par identité dans ui.keal, et l'identité d'un nœud est l'endroit où il se trouve, sauf si on lui a donné une clé.

Entre deux images, la boucle est dans kvWait, qui bloque. Une fenêtre au repos n'utilise aucun processeur. Cette phrase est restée deux jours dans le README avant que quiconque la mesure, et quand quelqu'un l'a fait elle était fausse sous Windows : le pointeur posé n'importe où sur la fenêtre, l'attente revenait aussitôt pour toujours et le processus tenait 96 % d'un cœur. C'est corrigé, et la liste de portage demande désormais la mesure deux fois.

Ce que le langage a décidé

Un endroit où la forme de keal-view est choisie par Keal et non par la conception : un trait n'est pas un type en Keal, donc une List<Widget> d'implémentations différentes ne peut pas exister. Une seule classe View avec un kind est ce que le langage offre. Les constructeurs et les modificateurs chaînés sont la véritable interface, et rien en dehors de view.keal ne pose kind à la main.

Et ce que sa construction a trouvé

Ce framework a été le premier usage sérieux de plusieurs coins du compilateur, et il y a trouvé quatre défauts — un appel dont l'appelé est un champ de type fonction ; une variable locale qui ne masquait pas une fonction importée du même nom ; une lambda qui ne pouvait pas capturer une liaison de premier niveau ; et Int sans opérateurs bit à bit. Les quatre sont corrigés en amont, et ce dépôt a été réécrit en conséquence.

Le langage où ils ont été corrigés →

Ce qui n'y est pas encore

  • plusieurs fenêtres système
  • un panneau détaché d'un dock dans une fenêtre à lui
  • la sélection de texte sur plusieurs lignes
  • l'écriture de droite à gauche et les écritures complexes — le moteur de polices associe les points de code aux glyphes un par un, ce qui est honnête pour le latin, le grec et le cyrillique et faux pour l'arabe et la dévanagari
  • les contours CFF , donc une police OpenType à courbes cubiques se charge et annonce qu'elle n'en a aucun
  • sauvegarder et restaurer un agencement de dock
  • l'animation au-delà d'un curseur qui clignote
  • les images