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é
dans le
php.ini
il faut que cette ligne soit présenteffi.enable="preload"
on peut vérifier la bonne activation de FFI avec la commande
php -m | grep FFI
qui doit afficherFFI
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 commandelocate libcsfml-graphics.so
. - Attention ! si SFML n’est pas installé avec CSFML la bibliothèque ne pourra pas se charger.
- 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
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
aveccomposer 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.
- il vous suffit de mettre au début de votre script la ligne ajoutant le fichier
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.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.
$text = new Text("Hello");
$text->setFillColor($blue);
$text->setPosition([150, 50]);
$text->setCharacterSize(50);
$window->run(
new Event(),
null,
function () use ($text, $window) {
$window->draw($text);
}
);
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.
function dessine() {
...
}
$maFonction = 'dessine';
//ou
$maFonction = function () {
...
}
$window->run(new Event(), null, $maFonction);
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.
$window->addToDrawingList(
'rectangle', // la clé de l'objet
new RectangleShape(
[400, 200],
[100, 200],
new Color(Color::BLUE) // définition de la couleur de fond en bleue
)
);
$window->run(
new Event(),
null,
function () use ($red, $window) {
$window
->getDrawingList()
->getObject('rectangle')
->setFillColor($red) // Le rectangle affiché sera rouge au lieu d'être bleue comme défini plus haut
;
}
);
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.
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 classeWindow
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 classeWindow
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.