Chapitre 3 Utilisation de la bibliothèque

3.1 Pré-requis à l’utilisation

Nous avons vu dans le 2.2 que la bibliothèque développée comportait certaines dépendances résumé dans le 2.2, PHP FFI et CSFML. Après les avoir installées il reste un minimum de configuration pour pouvoir parfaitement exécuter votre premier script.

3.1.1 Préchargement FFI et header CSFML

La bibliothèque utilise la fonctionnalité de préchargement de PHP pour précharger les header CSFML nécessaire pour charger et utiliser cette dernière en PHP. Il s’agit donc de modifier certaines variables de configuration de php.ini pour convenir à nos besoins. Les instructions données seront pour linux, il est possible que la procédure change sur windows

3.1.1.1 Activation de FFI :

Il faut s’assurer que FFI est en mode preload et est bien activé

  1. dans le php.ini il faut que cette ligne soit présente ffi.enable="preload"

  2. on peut vérifier la bonne activation de FFI avec la commande php -m | grep FFI qui doit afficher FFI

  3. activer opcache en ligne de commande en modifiant la valeur du paramètre opcache.enable_cli à true.

3.1.1.2 Mettre en place le préchargement :

Les fichiers header (extension en .h) à précharger sont dans le dossier preloading du dépot de la bibliothèque. Les deux premières ligne de chaque fichiers définissent :

  • l’espace de définition utilisé pour charger la bibliothèque C en PHP, à ne pas modifier
  • le chemin absolu vers le fichier binaire de la bibliothèque à charger, CSFML pour notre cas.
    • Il faut bien s’assurer que ce chemin est le bon pour réussir le chargement de la bibliothèque avec FFI. On peut vérifier cela avec la commande locate. Par exemple pour le module Graphics de CSFML il faut exécuter la commande locate libcsfml-graphics.so.
    • Attention ! si SFML n’est pas installé avec CSFML la bibliothèque ne pourra pas se charger.

Le chemin absolu vers le dossier contenant ces fichiers doit être renseigné dans la variable ffi.preload du fichier de configuration de PHP en ligne de commande, sur ma machine son chemins est /etc/php/7.4/cli/php.ini. Ce chemin doit ensuite être suffixé de *.h pour préciser que nous voulons tous les fichiers d’extension .h situé dans ce dossier.

  • Par exemple si le chemin vers le dossier preloading du dépôt est /home/user/phpml/preloading/ la nouvelle valeur de la variable sera : ffi.preload="/home/user/phpml/preloading/*.h"

Si tout s’est bien passé, avec cette nouvelle configuration on devrait être capable d’exécuter un script de test du dépôt sans erreurs dès qu’on l’aura installé dans un nouveau projet avec composer.

3.1.2 Installation dans un nouveau projet

Partant du contexte que vous commencez un nouveau projet appelé nice-stuff et que vous vouliez y intégrer cette bibliothèque, les étapes que vous aurez à réaliser doivent comprendre :

  • la création du dossier nice_stuff
  • l’initialisation de votre fichier composer.json avec composer init, après l’avoir préalablement installé 2.5.2
  • l’ajout de la bibliothèque PHPML en tant que dépendance à votre projet : composer require djuhnix/phpml
  • il est important de noter que vous aurez besoin de la fonction d’autochargement fournie par composer :
    • il vous suffit de mettre au début de votre script la ligne ajoutant le fichier vendor/autoload.php. Cette ligne pourrait ressembler à require_once("vendor/autoload.php") mais veillez à ce que le chemin passé à la fonction soit relatif à l’emplacement de votre script.

A présent vous êtes prêt à utiliser la bibliothèque PHPML dans votre projet, composer s’occupera de charger les différentes classes que vous appellerez.

3.2 Exemple d’utilisation et documentations

3.2.1 Utilisation

Vous pouvez trouver des exemples d’utilisation de la bibliothèque dans le dossier tests/functionnal du dépôt git. Mais voici comment réaliser certaines tâches avec PHPML.

3.2.1.1 Comment ouvrir une fenêtre

Il deux façons d’ouvrir une fenêtre, la première consiste à utiliser la classe de base Window et gérer par sois même les boucles qui permettent de garder la fenêtre ouverte et de gérer les événements, notamment la fermeture de la fenêtre pour éviter de démarrer une boucle infini.

La création d’une instance de la classe Window nécessite obligatoirement de définir un mode de rendu qui contient également la taille de la fenêtre. Pour simplifier, la création de la fenêtre j’ai pris la décision de ne pas permettre la surcharge du mode de rendu vidéo et j’utilise celui de l’ordinateur par défaut, généralement de 32 bits par pixel.

Malgré cela, cette procédure restant fastidieuse à réaliser à chacun de ses scripts j’ai pensé à réaliser une autre classe ExtendedWindow héritant de la classe Window et qui étend ou plutôt facilite l’utilisation des fonctionnalités de cette dernière.

Désormais ouvrir une fenêtre revient à écrire

Comme le dit la documentation, la méthode run() de la classe Window

Lance la boucle principale de la fenêtre et l’ouvre dans le même temps.

En plus de cela elle gère également la boucle d’événement qui s’occupe de la fermeture de la fenêtre, s’occupe de dessiner à chaque rafraîchissement les objets qui lui sont attachés et possède bien plus d’atouts que nous détaillerons plus tard. Cette méthode facilite l’utilisation de bibliothèque à un point considérable car elle permet de s’abstraire des tâches répétitives lié à la création d’une fenêtre dans les bibliothèques graphiques classiques, c’est également la pierre angulaire de la librairie parce que c’est par elle que commence toutes activités que l’on voudrait réaliser avec la bibliothèque, comme dessiner des formes.

3.2.1.2 Comment dessiner

Pour dessiner sur une fenêtre il n’y a rien de plus simple que l’appelle à la méthode draw() de la classe Window qui prend en paramètre un objet “dessinable” préalablement initialisé (de préférence à l’extérieur de la boucle) et l’affiche sur la fenêtre actuelle.

Après avoir ouvert notre fenêtre, en supposant qu’on utilise la première méthode qu’offre notre bibliothèque, il faudrait écrire dans la partie réserver aux dessins (mise en évidence plus haut) :

Cependant faire cela est une mauvaise pratique et il serait préférable de créer ses formes avant le lancement de la boucle de la fenêtre, cela empêcherait l’inutile création de la même forme tout au long de la boucle qui maintient la fenêtre ouverte.

Cela reste valable même si l’on utilise la seconde possibilité d’ouverture de fenêtre qu’est la méthode run() de la ExtendedWindow. Pour revenir sur cette méthode, il faut savoir qu’elle prend en paramètre en plus de la variable d’événements, deux fonctions qui sont respectivement utilisé pour la gestion personnalisée d’événements par l’utilisateur et la réalisation de dessins sur la fenêtre, s’il n’y a que cette dernière option qui nous intéresse on peut toujours passé null à la fonction run() à la place de la fonction de gestion d’événements. Il est vrai que cette façon de faire nécessite de connaître le concept de fonction anonyme (closure) qui relève de l’algorithmie légèrement avancé pour un débutant mais dès qu’on sait comment l’utiliser le reste n’est que de simples détails théoriques.

Le mot clé use est là pour dire que nous voulons utiliser ces variables pré-définie à l’interieur de notre fonction anonyme, sinon PHP ne sait pas que ces variables ont bien été déclaré et initialisé. Notre fonction anonyme peut ne pas être si anonyme qu’on peut le croire car on peut lui donner un nom, l’enregistrer dans une variable et passer cette dernière dans à la méthode run() plus tard dans notre script.

Cependant il faut prendre en compte le fait que si l’on utiliser des variables mise à jour dynamiquement par la bibliothèque comme les événements cette méthode est à proscrire.

3.2.1.3 Comment garder les modifications appliquées à ses objets

Par défaut la bibliothèque n’enregistre pas toutes les modifications que vous appliquer à vos formes et autres objets dessinables parce qu’ils ne sont pas attachés à la fenêtre. Pour ce faire il faut utiliser la méthode addToDrawingList() qui comme son nom l’indique ajoute un objet identifié par une clé à la liste des éléments à dessiner qui seront enregistrés avec les données de la fenêtre et mis à jour à toutes futures modifications. L’objet enregistré peut toujours être retrouvé grâce à son identifiant et modifié si besoin.

Tout cela dans le but de faciliter l’utilisation de la bibliothèque par des débutants et surtout flexibilité de celle-ci.

3.2.1.4 Extra

3.2.1.4.1 Créer une couleur

Des couleurs sont prédéfinie dans l’énumération prévu pour. Mais pour s’en servir il faut créer une instance de couleur avec l’une de ces valeurs.

Il est évidemment possible de créer des couleurs dynamique avec des valeur de couleurs primaires.

3.2.1.4.2 Gérer des événements

On ne pourrait pas parler proprement de bibliothèque graphique sans gestion des événements déclencher sur la fenêtre, voilà pourquoi l’implémentation de la gestion des événements et des entrées (clavier et souris) faisaient parties de mes priorités.

On a précédemment vu sur les morceaux de codes qu’on pouvait créer une instance d’événement avec

Le constructeur de cette classe ne prend rien en paramètre car tout est géré en interne pour l’utilisateur. Tout ce qu’il reste à faire pour l’utiliser c’est de vérifier qu’un certain type d’événement à bien été reçu et le traiter en tant que tel. Un exemple d’utilisation serait :

3.2.2 Documentation

Actuellement la documentation de la bibliothèque n’est pas hébergé mais elle peut être lu directement sur les sources de la bibliothèque sur le dépôt github.