Styles

vendredi 8 septembre 2017

Game Engine Black Book, pour comprendre les techniques bas niveau de 1992

Fabien Sanglard, d'origine de Romans-Sur-Isere, aujourd'hui employé de Google à Mountain View, CA vient de publier son livre que beaucoup attendaient avec impatience: Game Engine Black Book: Wolfenstein 3D. Depuis plusieurs années, Fabien nous gratifie de nombreux billets techniques sur son blog, essentiellement sur la programmation de jeux, et notamment des explications des techniques "bas niveau" de jeux mythiques comme Wolfenstein 3D ou Quake, ou de plateformes, certes anciennes, mais qui sont tellement instructives qu'il est passionnant de s'y pencher à nouveau.

Aujourd'hui avec son livre Game Engine Black Book, Fabien prend le temps d'expliquer le hardware de l'époque de Wolfenstein 3D, les outils de l'époque (TurboC++) et toutes les techniques géniales qui ont été mises en œuvre pour la première fois dans un jeu pour construire la vision 3D en vitesse rapide. Nécessité est mère de l'inventivité : les contraintes si fortes de l'époque ont poussé les développeurs comme John Carmack à trouver des techniques bas-niveau originales et puissantes qui, aujourd'hui encore sont appréciées pour leur élégance et leur efficacité.


Et c'est pour cela qu'il est intéressant de lire le code source de Wolfenstein 3D accompagné du livre Game Engine Black Book pour en tirer toute la substantifique moelle et en tirer des leçons pour soi-même, dont la première est l'humilité : pour produire de telles optimisations, une somme incroyable de temps et de jus de cerveau a du être déployée, et on ne peut être qu'impressionné par le niveau de maitrise complète du système qu'avaient ces programmeurs.

L'utilisation de langages de haut niveau, avec ramasse-miettes, des sucres syntactiques, d'abstractions sur d'autres abstractions sur d'autres frameworks, sur d'autres machines virtuelles jusqu'à l'infini abouti à programmer sur des sables mouvants où la complexité est telle qu'aucune maitrise réelle n'est envisageable. Cette programmation "abstraite" revient presque à un exercice de croyance où la qualité n'est qu'espérée sur la foi des développeurs des technologies sous-jacentes et la croyance dans leur capacité à maintenir complètes et entières leurs abstractions.

jeudi 27 juillet 2017

OpenBSD passe le compilateur par défaut à clang sur amd64 et i386

Une petite nouvelle mais assez significative pour le projet OpenBSD : hier a été commité le changement du compilateur par défaut de amd64 et i386 de OpenBSD pour passer sur clang. Cela permet au projet OpenBSD de s'abstraire petit à petit d'une grosse dépendance envers le projet GCC sous licence GPL, et de profiter des avantages de clang/llvm par rapport au compilateur gcc, avantages que l'on peut résumer ainsi:

- clang utilise une licence BSD,
- clang n'est pas monolithique comme gcc, clang a été conçu depuis sa création, comme une API permettant ainsi sa réutilisation dans des outils d'analyse de code, des outils de 'refactoring' ainsi que des générateurs de code,
- clang est bien plus rapide et consomme moins de mémoire que gcc.

De plus, grâce à clang, le projet OpenBSD va bénéficier de technologies comme Control Flow Integrity (CFI) ou SafeStack.

Voir la discussion sur Lobste.rs.

lundi 29 mai 2017

Prolog est orphelin

Je viens d’apprendre le décès d’Alain Colmerauer. Alain est l’inventeur du langage Prolog, qui a joué un rôle clé dans le développement de l’IA. Prolog est un langage vraiment original qui pousse à réfléchir différement aux problèmes à résoudre. Prolog est donc un des langages absolument nécessaires d'avoir cotoyé dans sa vie d'informaticien.

Pour plus d'information : Prolog est orphelin.

samedi 14 janvier 2017

Ne plus avoir à saisir son mot de passe git sous OpenBSD

Par défaut, git demande votre login et mot de passe à chaque fois que vous accédez à un dépôt git protégé en HTTPS. Plusieurs techniques existent pour ne pas avoir à ressaisir le mot de passe, comme par exemple l'utilisation de clés SSH à la place de HTTPS. Cette dernière que je ne détaillerai pas ici, nécessite de mettre en place un agent SSH.

Je vous propose dans cet article de configurer votre OpenBSD pour les dépôts git sous HTTPS. Que vous soyez sous XFCE ou Gnome, c'est la même méthode vu qu'elle est à base de gnome-keyring. Si vous êtes sous KDE, allez voir du côté du KDE Wallet.

Etape 1: Ajouter les paquets suivants:

pkg_add -iv gnome-keyring
pkg_add -iv libgnome-keyring
pkg_add -iv gmake

Si vous êtes sous XFCE: Sous le compte utilisateur :
- Cliquer sur le menu XFCE Applications/Settings/Session and Startup
- Dans la boîte de dialoge "Session and Startup", cliquer sur l'onglet "Advanced"
- Dans l'onglet "Advanced" cliquer sur l'option "Launch GNOME services on startup"
- Cliquer ensuite sur "Close" et fermer votre session XFCE puis rouvrez-en une.

Etape 2: Compiler git-credential-gnomekeyring

git clone https://github.com/shugo/git-credential-gnomekeyring.git
cd git-credential-gnomekeyring
gmake
mkdir ~/bin
# Normalement ~/bin est déjà dans le PATH: à vérifier.
cp git-credential-gnomekeyring ~/bin

git config --global credential.helper gnomekeyring

Maintenant Git fait appel à Gnome Keyring pour stocker les mots de passe. A la première utilisation Gnome Keyring demande un mot de passe pour protéger le Keyring. Tout cela marche très bien aussi sous Emacs avec magit ou sous n'importe qu'elle application qui utilise les commandes git.

ATTENTION
Toujours mettre le username sur l'URL utilisée lors du git clone. Par exemple: git clone https://jradix@github.com/jradix/.emacs.d Sinon, git continuera toujours de vous demander avec quel compte vous souhaitez vous connecter.

Si vous souhaitez modifier l'URL du dépôt pour ajouter le username par exemple, faire, dans un répertoire du dépôt en question : git remote set-url origin https://jradix@github.com/jradix/.emacs.d

mercredi 4 janvier 2017

EmacsLisp et les processus réseaux

Emacs cache en son sein une machine virtuelle complète, qui, si elle accuse effectivement le poids des ans, n'en reste pas moins fonctionnelle, à défaut d'être performante.

EmacsLisp, le Lisp qu'elle supporte, ressemble plus à du Common Lisp qu'à du Scheme. Le fait que l'éditeur soit intimement lié avec la machine virtuelle facilite l'apprentissage de ce monde étrange et sinueux qu'est la programmation en EmacsLisp.

J'ai voulu tester les capacités réseaux offertes par EmacsLisp pour apprendre notamment à ouvrir des connexions et développer de véritables serveurs. Emacs propose déjà des applications réseaux intéressantes comme Elnode (serveur Web asynchrone) ou tout simplement l'outil TRAMP qui permet d'accéder à n'importe quel fichier sur le réseau et de l'éditer comme tout autre fichier dans Emacs sans différence aucune.

Le programme  suivant réalise un test automatisé (avec ERT) de la création d'un serveur et d'un client, ce dernier envoyant un "Hello World" au serveur:

;;; -*- coding: utf-8; lexical-binding: t -*-

;;; Test of network functions.

(require 'ert)

(defvar net-server-port 10000
  "port of the net-test server")

(defun net-test-server-log (string &optional client)
  "If a *net-test-server* buffer exists, write STRING to it for
logging purposes."
  (if (get-buffer "*net-test-server*")
      (with-current-buffer "*net-test-server*"
 (goto-char (point-max))
 (insert (current-time-string)
  (if client (format " %s:" client) " ")
  string)
 (or (bolp) (newline)))))

(defun net-test-server-sentinel (proc msg)
  "Server sentinel"
  (if (string= msg "connection broken by remote peer\n")
      (net-test-server-log (format "client %s has quit" proc))
    (if (string= msg "deleted\n")
 (net-test-server-log (format "server %s has been deleted" proc))
      (net-test-server-log (format "unknown message for %s : %s" proc msg)))))

(defun net-test-server-filter (proc string)
  "Server filter function"
  (net-test-server-log string proc))

(ert-deftest net-test ()
  "Test the opening of a TCP network connection to a server."
  (let ((server (make-network-process
   :name "net-test-server"
   :buffer "*net-test-server*"
   :family 'ipv4
   :service net-server-port
   :sentinel 'net-test-server-sentinel
   :filter 'net-test-server-filter
   :server 't
   )))
    (should (processp server))
    (should (equal (process-contact server :service) net-server-port))
    (let ((client
    (open-network-stream "net-test-client"
    "*net-test-client*"
    "localhost"
    net-server-port)))
      (sit-for 1)
      (should (processp client))
      (should (equal (process-contact client :service) net-server-port))
      (process-send-string client "hello world\n")
      (sit-for 1)
      (delete-process client)
      (sit-for 1))
    (delete-process server)))


Les connexions réseaux en EmacsLisp sont gérées comme des "processus" d'un type particulier.

La programmation réseau en EmacsLisp tourne autour des points suivants:
- une fonction "sentinel" qui est appelée quand le processus réseau change d'état,
- une fonction "filtre" qui est appelée à chaque fois qu'un message est reçu par le processus réseau.

A chaque processus réseau peut être associé ou non un tampon ("buffer"), la fonction "filtre" par défaut réalisant une écriture du message reçu dans le tampon.

Comme l'indique la documentation officielle EmacsLisp, il faut laisser à Emacs des moments de respiration pour lui permettre d'appeler de façon asynchrone les méthodes "filtre" et "sentinel". C'est le rôle des appels à la fonction "sit-for" qui fait une pause d'1 seconde, pour éviter que le test unitaire ne ferme le client ou le serveur avant même qu'ils aient pu entrer en communication et s'envoyer des messages.