arma_3:createurs_de_missions:sqf_for_noobs:fonctions

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
arma_3:createurs_de_missions:sqf_for_noobs:fonctions [2023/05/01 08:57]
admin
arma_3:createurs_de_missions:sqf_for_noobs:fonctions [2023/05/01 12:20] (Version actuelle)
admin
Ligne 3: Ligne 3:
 ===== Qu'est-ce ? ===== ===== Qu'est-ce ? =====
  
-Les programmeurs et les codeurs sont des "flemmards" qui adorent automatiser les taches. Or en programmation il arrive très souvent que l'on fasse des taches très répétitives. Au tout début de l'informatiquel'une des toute première révolution fut la création d'une structure appelée la boucleCette dernière permet de répéter des lignes de code un certain nombre de fois à un endroit du codeévitant de devoir les réécrireToutefois cette structure ne permet pas de le faire à différent endroit de votre programme.+En programmationil arrive très souvent que l'on répète une tache identique ou semblable à divers endroits de notre code. //E.g.// calculer le carré d'un nombre ouautre exemple, dans arma récupérer le joueur le plus proche d'une position (aucune commande arma pour cela)On est donc obligé de construire notre propre algorithme pour le faire. Une fois construit il serait pratique de pouvoirau lieu de le copier coller partout, l'appeler sous un mot-clef comme une commandeL'avantage est que si on a une erreur dans l'agorithme il n'y a pas besoin de la corriger dans tous les endroits où l'on exécute notre code, seulement à l'endroit où on le définit.
  
-Ainsi il est apparaît évident le besoin d'une autre structure syntaxique. C'est ainsi que fut né la **fonction**. Son nom vient tout simplement de l'objet mathématique portant le même nom.\\ +Une telle structure syntaxique porte un nom, c'est la**fonction**. Son appellation vient tout simplement de l'objet mathématique du même nom. 
-En effet, en mathématique une fonction ''f'' prend une ou plusieurs variables ''x_1, x_2, x_3, etc'' pour retourner une seule valeur ''y'' et l'on appelle avec des parenthèses ''f(x_1, x_2, x_3, etc)''. En informatique c'est quasiment pareil, excepté que l'on peut prendre en entré d'autre chose que des nombres (c.f. [[arma_3:createurs_de_missions:sqf_for_noobs:variables|variables]]) et idem pour la valeur de sortie.\\ + 
-Ainsi une fonction ''maSuperbeFonction'' peut prendre les paramètres ''monPremierMagnifiqueParamètre, monDeuxièmeMagnifiqueParamètre, etc'' et retourne ''maBrillantissimeValeur''.+<note>Petit rappel de math. Une fonction peut prendre une ou plusieurs variables et retourne une valeur. //E.g.// prenons une fonction noté //f// qui prend plusieurs variables //x_1, x_2, x_3, etc// et qui retourne une valeur. Pour appeler notre fonction on utilise la syntaxe //f(x_1, x_2, x_3, etc)//. En informatiquec'est pareil. Ainsi on peut créer une fonction ''maSuperbeFonction'' peut prendre les paramètres ''monPremierMagnifiqueParamètre, monDeuxièmeMagnifiqueParamètre, etc'' et retourne ''maBrillantissimeValeur''.</note>
  
 Le principe est donc clair, vous écrivez **une seule fois** le code de votre fonction en définissant les paramètres attendus ainsi que la valeur retournée. Ensuite il ne vous reste plus qu'appeler là où vous le voulez dans votre code en écrivant ''maSuperbeFonction(...)'' (Dans un language bien écrit, hein Bohémia avec ton SQF). Le principe est donc clair, vous écrivez **une seule fois** le code de votre fonction en définissant les paramètres attendus ainsi que la valeur retournée. Ensuite il ne vous reste plus qu'appeler là où vous le voulez dans votre code en écrivant ''maSuperbeFonction(...)'' (Dans un language bien écrit, hein Bohémia avec ton SQF).
Ligne 23: Ligne 23:
 Deux points positifs sont : Deux points positifs sont :
   - La syntaxe pour les paramètres est identique dans les deux cas ainsi que pour la valeur de retour.   - La syntaxe pour les paramètres est identique dans les deux cas ainsi que pour la valeur de retour.
-  - Il suffit de suivre la recette de cuisine pour pas se tromper pour déclarer ces paramètres.+  - Il suffit de suivre la recette de cuisine pour pas se tromper pour déclarer ces paramètres. (Bon ça c'est commun à tous les langages).
  
-Le point négatif est que le SQF a vraiment une syntaxe de merde pour les fonctions si l'on compare le SQF à celle des langages de programmation répandus, même ancien. Toutefois pas d'inquiétude, c'est abordable.+Le point négatif est que le SQF a décidé de ne pas suivre une syntaxe conventionnel (parce que Bohémia) pour les fonctions si l'on compare le SQF à celle des langages de programmation répandus, même ancien. Toutefois pas d'inquiétude, c'est abordable.
  
 ==== Construire une fonction ==== ==== Construire une fonction ====
  
-===== Création et exécution =====+=== Création et exécution ===
  
  
Ligne 39: Ligne 39:
 Comment exécuter la fonction ?\\ Comment exécuter la fonction ?\\
 Modifions d'abord le contenu de notre fonction qui est pour l'instant vide avec Modifions d'abord le contenu de notre fonction qui est pour l'instant vide avec
-<code>+<code sqf>
 monCode = { monCode = {
  systemChat "Hello from monCode";  systemChat "Hello from monCode";
Ligne 45: Ligne 45:
 </code> </code>
 Une solution intuitive pour l'exécuter serait d'écrire la ligne suivante Une solution intuitive pour l'exécuter serait d'écrire la ligne suivante
-<code>+<code sqf>
 monCode; monCode;
 </code> </code>
 Malheureusement, rien ne se passe. En fait ici, vous appelez simplement le contenu de votre variable, //i.e.// le contenu de votre code mais il n'est pas exécuté. Pour le faire exécuter, il existe une commande (en réalité 2 mais c'est pour un autre tuto) : ''call''. Malheureusement, rien ne se passe. En fait ici, vous appelez simplement le contenu de votre variable, //i.e.// le contenu de votre code mais il n'est pas exécuté. Pour le faire exécuter, il existe une commande (en réalité 2 mais c'est pour un autre tuto) : ''call''.
-<code>+<code sqf>
 call monCode; call monCode;
 </code> </code>
 Si vous exécutez ces lignes dans la console de débug, vous devez avoir le message dans le chat du jeu. Si vous exécutez ces lignes dans la console de débug, vous devez avoir le message dans le chat du jeu.
  
-===== Paramètres =====+=== Paramètres ===
  
 +La puissance des fonctions vient principalement de leur paramétrisation. Prenons l'exemple d'une fonction que l'on appelle //carre// et qui calcul le carré du chiffre 3.
 +<code sqf>
 +carre = {
 + systemChat "Le carré de 3 est " + str(3^2);
 +};
 +</code>
 +Si je l'exécute
 +<code sqf>
 +call carre;
 +</code>
 +j'obtient dans le chat : Le carré de 3 est 9\\
 +Cette fonction est peu pratique car si on veut calculer le carré d'un autre nombre il nous faut réécrire une autre fonction différente et on pert tout l'avantage des fonctions. Heureusement on peut paramétriser nos fonctions.
  
 +Pour passer un paramètre à une fonction on l'ajouter devant l'appel de la fonction. Avec notre exemple ça donne :
 +<code sqf>
 +3 call carre;
 +</code>
 +Maintenant comment utilise t'on ce paramètre ? C'est là où on rentre dans les spécifications bizarre du SQF. Le paramètre passé va être contenu dans une variable magique appelé ''_this''.
 +
 +<note>**Variable magiques** : en programmation on appelle [[https://community.bistudio.com/wiki/Magic_Variables|variable magique]], une variable spéciale créée par le langage lui-même sans que l'utilisateur le fasse. En fait c'est une variable habituelle mais réservée par le langage, //i.e.// on peut lire cette variable mais il ne faut pas changer sa valeur et s'en servir comme n'importe qu'elle autre variable sous peine de maux de tête interminables sur des bugs pourris.</note>
 +
 +On réécrit le code de notre fonction comme ceci
 +<code sqf>
 +carre = {
 + systemChat format["Le carré de %1 est %2", _this, _this^2];
 +};
 +</code>
 +où l'on a remplacé la valeur 3 par ''_this''. Maintenant on peut utiliser notre fonction pour afficher le carré de n'importe quel nombre.
 +
 +Comment passe t'on plusieurs paramètres ?\\
 +Eh bien en SQF, on ne peut pas mais c'est contournable. Tout d'abord l'astuce est de regrouper tous vos paramètres dans un ''[[https://community.bistudio.com/wiki/Array|array]]'' (tableau en français) et c'est ce tableau que l'on va passer comme dans l'exemple ci-dessous.
 +<code>
 +[param_0, param_1] call multiplication;
 +</code>
 +et dans le code de notre fonction, on peut récupérer nos paramètres comme on extrait les valeurs d'un tableau.
 +<code sqf>
 +multiplication = {
 + private _x = _this#0;
 + private _y = _this#1;
 + systemChat format["Le produit de %1 par %2 vaut %3", _x, _y, _x * _y];
 +};
 +</code>
 +Toutefois Bohémia a créé une commande spécial pour cette situation et avoir une syntaxe plus compréhensible qui est ''[[https://community.bistudio.com/wiki/params|params]]''. Cela permet de réécrire notre fonction comme
 +<code sqf>
 +multiplication = {
 + params['_x', '_y'];
 + systemChat format["Le produit de %1 par %2 vaut %3", _x, _y, _x * _y];
 +};
 +</code>
 +
 +=== Sortie ===
 +
 +On aimerait maintenant pouvoir récupérer le résultat de notre fonction. Dans un langage normalement constitué, il existe un mot-clef pour cette opération afin que quelqu'un qui lit le code puisse comprendre précisément quelle valeur est retournée en sortie.
 +Pour le SQF, il n'y a pas de mot-clef et il s'agit de la dernière valeur calculée.
 +<code sqf>
 +carre = {
 + _this * _this;
 +};
 +
 +multiplication = {
 + params['_x', '_y'];
 + _x * _y
 +};
 +
 +carreDeTrois = 3 call carre;
 +monSuperbeMultiple = [4, 6] call multiplication;  // Retourne 4*6 donc 24
 +</code>
 +Pour la fonction //carre//, la dernière opération est notre paramètre multiplié par lui-même (donc son carré) et pour la fonction //multiplication// c'est ''_x*_y''. Le point virgule n'est pas obligatoire et la convention est de ne pas le mettre pour spécifié à l'utilisateur que c'est bien la sortie voulue.
 +
 +Par comparaison voici dans deux autres langages l'implémentation de ces deux fonctions (avec des commentaires) :\\
 +En Python
 +<code python>
 +def square(x):
 +    """Compute the square of a number
 +
 +    Parameters
 +    ----------
 +    x : float
 +
 +    Returns
 +    -------
 +    float
 +        Squared number
 +    """
 +    return x**2
 +
 +
 +def multiply(x, y):
 +    """Multiply 2 numbers
 +
 +    Parameters
 +    ----------
 +    x : float
 +    y : float
 +
 +    Returns
 +    -------
 +    float
 +    """
 +    return x * y
 +</code>
 +En C
 +<code C>
 +/**
 + * @brief Compute the square of a number
 + *
 + *
 + * @param x
 + * @return squared number
 + */
 +double square(double x) {
 + return x*x;
 +}
 +
 +/**
 + * @brief Multiply 2 numbers
 + *
 + *
 + * @param x
 + * @param y
 + * @return
 + */
 +double multiply(double x, double y) {
 + return x*y;
 +}
 +</code>
 +
 +==== Fonction dans un fichier ====
 +
 +Il est possible de définir vos fonctions dans des fichiers séparés avec une fonction par fichier. Dans ce cas précis il ne faut pas utiliser d'accolades, le fichier remplissant leur fonction à la place. En fait tout script SQF peut être considéré comme une fonction non paramétrée (comme notre toute première version de la fonction //carre//).
 +
 +Ainsi il suffit de copier coller le contenu de vos accolades dans un fichier. Pour pouvoir l'utiliser ailleurs, il suffit de la compiler à l'aide des deux commandes suivantes [[https://community.bistudio.com/wiki/preprocessFile|preprocessFile]] et [[https://community.bistudio.com/wiki/compile|compile]] comme dans l'exemple suivant
 +<code sqf>
 +maSuperbeFonction = compile preprocessFile "path_to_my_function\maSuperbeFonction.sqf";
 +</code>
  
  • arma_3/createurs_de_missions/sqf_for_noobs/fonctions.txt
  • Dernière modification: 2023/05/01 12:20
  • de admin