Forum d'entraide à la création de jeux d'aventure
 
PortailAccueilFAQRechercherS'enregistrerMembresConnexion

Partagez | 
 

 Structures et mots-clés (static, attribute, readonly...)

Voir le sujet précédent Voir le sujet suivant Aller en bas 
AuteurMessage
Billbis
Disciple de la Grande Tasse Bleue
Disciple de la Grande Tasse Bleue


Nombre de messages : 1275

Date d'inscription : 10/05/2012


MessageSujet: Structures et mots-clés (static, attribute, readonly...)   Jeu 4 Juil 2013 - 13:35

J'ai quelques questions concernant le langage de script AGS, et je pense que Kitai pourra y répondre. Par exemple si je prend cette ligne de code :
Code:
static bool SpaSpeech::get_Enabled() { return Spatialized; }
-A quoi sert le static ? J'avais lu quelque par que c'était optionnel mais plus joli, mais je ne retrouve plus la page en question.
-C'est quoi les "::" ? J'imagine que c'est pour dire que get_Enabled appartient à la struct SpaSpeech ? Quel est l’intérêt d'utiliser une struct dans le cas présent ?
Code:
import static attribute bool Enabled;
-A quoi sert le attribute ?
Tout ça me dépasse toralement. zarb 
Ne te sens pas obligé de répondre, c'est pas grave si je n'y comprend rien. clin d\\\\'oeil
EDIT : Je viens aussi de remarquer qu'on ne pouvait pas télécharger ton module, juste copier / coller le code. C'est volontaire ?

_________________
Mon petit DevBlog


Dernière édition par Billbis le Ven 5 Juil 2013 - 14:49, édité 1 fois
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://nothingaboutthedog.blogspot.fr/
Kitai
Délégué de la tasse bleue
Délégué de la tasse bleue


Nombre de messages : 2431

Date d'inscription : 01/08/2006


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Jeu 4 Juil 2013 - 16:31

Billbis a écrit:
Ne te sens pas obligé de répondre, c'est pas grave si je n'y comprend rien. clin d\\\\'oeil
C'est bien vrai, reste donc dans ton ignorance crasse ! clin d\\\\'oeil

Billbis a écrit:
-A quoi sert le static ? J'avais lu quelque par que c'était optionnel mais plus joli, mais je ne retrouve plus la page en question.
Je ne sais pas à quoi tu fais référence, mais sous AGS je n'ai pas connaissance d'un contexte où static soit optionnel.
J'avais déjà rapidement évoqué ce mot-clé sur ce sujet et en fait tu le trouveras (ainsi que attribute pour -quasi?- toutes les propriétés) assez souvent dans le fichier qu'on a traduit également clin d\\\\'oeil

Donc pour résumé, le static sert à ce qu'on puisse appeler la propriété comme cela :
Code:
if (SpaSpeech.Enabled) player.Say("&1 La classe, le volume et l'équilibrage de ma voix s'adaptent à ma position !");
else player.Say("&2 Et dire que cette phrase sera aussi bien entendue de près comme de loin, quel manque de réalisme...");
plutôt que comme cela :
Code:
SpaSpeech instance_inutile;
if (instance_inutile.Enabled) player.Say("&1 La classe, le volume et l'équilibrage de ma voix s'adaptent à ma position !");
else player.Say("&2 Et dire que cette phrase sera aussi bien entendue de près comme de loin, quel manque de réalisme...");
C'est ce mot-clé qui permet à AGS de proposer une fonction Character.GetAtScreenXY où tu trouves bien l'expression Character sur la gauche et non pas, par exemple, player.

Ainsi dans AGS, le mot-clé static n'a de sens qu'au sein d'une structure : cela détermine si la méthode/propriété est à appeler sur une instance de cette structure (auquel cas le mot-clé est absent) ou sur la structure elle-même (auquel cas le mot-clé est présent).
Attention car dans d'autres langages, comme le C++ par exemple, ce mot-clé recouvre davantage de significations.

Billbis a écrit:
-C'est quoi les "::" ? J'imagine que c'est pour dire que get_Enabled appartient à la struct SpaSpeech ? Quel est l’intérêt d'utiliser une struct dans le cas présent ?
Oui, c'est bien là la fonction des "::". La motivation pour utiliser une structure est principalement un soucis de convention : il est considéré comme plus propre de regrouper les fonctions globales de ton modules dans une structure et de les rendre statiques (à appeler directement sur la structure donc) :
Strazer dans ses recommandations sur les modules a écrit:
- Grouping of functions by using static member functions is recommended:
J'admets qu'il n'est pas explicitement recommandé de faire de même pour les variables, mais avoue que proposer SpaSpeech.Enabled respecte bien plus les soucis de compatibilité que proposer Enabled et est discutablement plus élégant que proposer SpaSpeech_Enabled.
D'autre part, dans la mesure où Enabled est alors un attribut de SpaSpeech, j'ai davantage de contrôle sur les bêtises que pourraient faire les utilisateurs du module s'ils modifiaient directement sa valeur (voir ci-après).

Billbis a écrit:
-A quoi sert le attribute ?
Le wiki d'AGS possède une page dédiée à ce mot-clé. Je vais tout de même rapidement expliquer son intérêt.

Sous AGS, il est impossible de définir une variable statique pour une structure alors qu'on peut le faire en revanche pour les fonctions (voir plus haut). Ce qui suit va donc déclencher une erreur à la compilation :
Code:
struct Vehicule {
  int Vitesse; // La vitesse de déplacement du véhicule instancié par la structure

  import static void RevolutionIndustrielle(); // Une fonction statique (Vehicule.RevolutionIndustrielle();) qui augmente le niveau d'évolution technologique

  static int NiveauTechnologique; // Le niveau d'évolution technologique actuel de la société : déclenchera une erreur à la compilation (variables statiques interdites)
};
Pour avoir une variable globale malgré tout (car le niveau d'évolution technologique de la société est global, il n'est pas propre à chaque véhicule), il faut utiliser le mot-clé attribute :
Code:
struct Vehicule {
  int Vitesse; // La vitesse de déplacement du véhicule instancié par la structure

  import static void RevolutionIndustrielle(); // Une fonction statique (Vehicule.RevolutionIndustrielle();) qui augmente le niveau d'évolution technologique

  import static attribute int NiveauTechnologique; // Le niveau d'évolution technologique actuel de la société
};
Mais la ruse est en fait plus complexe : attribute ne crée pas une variable statique, cela crée une propriété superficielle de la structure (c'est-à-dire que cela va bien être présenté au programmeur utilisateur comme une variable globale de la structure), mais en réalité toute consultation de cet attribut appelle une fonction de façon sous-jacente. Cette fonction doit être spécifiée par le développeur de la structure et doit s'appeler get_NiveauTechnologique.

De cette manière, chaque fois que l'utilisateur utilise Vehicule.NiveauTechnologique dans un contexte qui consulte la valeur de cette variable (dans la condition d'un if par exemple), cela revient à utiliser Vehicule.get_NiveauTechnologique(), de la façon suivante :
Code:
if (Vehicule.NiveauTechnologique == 0) Display("On est des arriérés, mais on est heureux quand même !"); // Ceci est équivalent à
if (Vehicule.get_NiveauTechnologique() == 0) Display("On est des arriérés, mais on est heureux quand même !"); // ceci
Il faut donc définir cette fonction de façon à ce qu'elle retourne une valeur cohérente. On peut par exemple imaginer ce qui suit :
Code:
// Fichier en-tête, .ash
struct Vehicule {
  int Vitesse; // La vitesse de déplacement du véhicule instancié par la structure

  import static void RevolutionIndustrielle(); // Une fonction statique (Vehicule.RevolutionIndustrielle();) qui augmente le niveau d'évolution technologique

  import static attribute int NiveauTechnologique; // Le niveau d'évolution technologique actuel de la société
  import static int get_NiveauTechnologique(); // $AUTOCOMPLETEIGNORE$ On ne veut pas que cette fonction sous-jacente apparaisse aux yeux écœurés des utilisateurs du module
};


// Fichier corps, .asc
#define FIN_DU_PROGRES 5 // Valeur arbitraire correspondant à l'aboutissement technologique d'une société et précédant de peu son déclin inéluctable
int NiveauTechnologique;

static int Vehicule::get_NiveauTehcnologique() {
 if (NiveauTechnologique < 0) return 0; // On évite tout bug éventuel : une société ne peut pas avoir régressé technologiquement en dessous de 0
  else return NiveauTechnologique; // On retourne le niveau technologique actuel
}

static void RevolutionIndustrielle() {
  if (NiveauTechnologique >= FIN_DU_PROGRES) {
    Display("Pauvres fous, vous venez de provoquer votre propre perte, vous n'êtes pas des dieux !");
    NiveauTechnologique = 0;
  }
  else NiveauTechnologique++; // On passe au niveau technologique supérieur
}
Comme tu peux le voir, les attributs permettent un très grand contrôle sur la manière dont l'utilisateur récupère et modifie les valeurs.

Pour finir je n'ai pas été tout à fait rigoureux dans l'exemple précédent : j'aurais dû utiliser readonly import static attribute int NiveauTechnologique; car je ne veux pas que l'utilisateur puisse directement modifier la valeur de NiveauTechnologique ; c'est à la fonction RevolutionIndustrielle que revient le rôle de la modifier.
Toutefois, j'aurais pu me passer de cette dernière fonction et permettre à l'utilisateur de modifier lui-même la valeur de NiveauTechnologique (auquel cas il ne faut bien sûr pas utiliser le mot-clé readonly). Et tout comme il y a une fonction qui est appelée lorsqu'on consulte la valeur d'un attribut, il y a une fonction qui est appelée lorsqu'on en modifie la valeur (et donc lorsque cet attribut n'est pas en lecture seule - readonly). Cette fonction doit en l'occurrence se nommer set_NiveauTechnologique. Cette fonction permet autant de contrôle que notre ancienne fonction RevolutionIndustrielle :
Code:
// Fichier en-tête, .ash
struct Vehicule {
  int Vitesse; // La vitesse de déplacement du véhicule instancié par la structure

  import static attribute int NiveauTechnologique; // Le niveau d'évolution technologique actuel de la société
  import static void get_NiveauTechnologique(); // $AUTOCOMPLETEIGNORE$
  import static int set_NiveauTechnologique(int niveau); // $AUTOCOMPLETEIGNORE$
};


// Fichier corps, .asc
#define FIN_DU_PROGRES 5 // Valeur arbitraire correspondant à l'aboutissement technologique d'une société et précédant de peu son déclin inéluctable
int NiveauTechnologique;

static int Vehicule::get_NiveauTehcnologique() {
 if (NiveauTechnologique < 0) return 0; // On évite tout bug éventuel : on ne peut pas régresser technologiquement en dessous de 0
  else return NiveauTechnologique; // On retourne le niveau technologique actuel
}

static void set_NiveauTechnologique(int niveau) {
  if (niveau >= FIN_DU_PROGRES) {
    Display("Pauvres fous, vous venez de provoquer votre propre perte, vous n'êtes pas des dieux !");
    NiveauTechnologique = 0;
  }
  else NiveauTechnologique = niveau; // On passe au niveau spécifié
}
Et alors on pourra l'utiliser de la façon suivante ailleurs dans un script :
Code:
#define FACTEUR_VITESSE 5
Vehicule bateau, train, avion;

function game_start() {
  bateau.Vitesse = 1;
  train.Vitesse = 2;
  avion.Vitesse = 3;
}

function AfficheVitessesAbsoluesVehicules() {
  if (!Vehicule.NiveauTechnologique) Display("Pas encore de technologique, pas de véhicule !");
  else {
    Display("Vitesse du bateau : %d km/h", bateau.Vitesse * Vehicule.NiveauTechnologique * FACTEUR_VITESSE);
    Display("Vitesse du train : %d km/h", train.Vitesse * Vehicule.NiveauTechnologique * FACTEUR_VITESSE);
    Display("Vitesse de l'avion : %d km/h", avion.Vitesse * Vehicule.NiveauTechnologique * FACTEUR_VITESSE);
  }
}

function RevolutionTechnologique() {
 Vitesse.NiveauTechnologique++;
  // Note que cette commande est équivalente à
  //   Vitesse.NiveauTechnologique = Vitesse.NiveauTechnologique + 1;
  // et à
  //   Vitesse.set_NiveauTechnologique(Vitesse.NiveauTechnologique + 1);
}

EDIT :
Billbis a écrit:
EDIT : Je viens aussi de remarquer qu'on ne pouvait pas télécharger ton module, juste copier / coller le code. C'est volontaire ?
Oui, puisque le code est plutôt court je n'ai pas pris la peine de mettre une version compilé du module en ligne. J'avoue que ce raisonnement n'a aucun sens, je proposerai peut-être un fichier .scm à l'occasion clin d\\\\'oeil

_________________
Ga is Ga
Vous pouvez consulter l'aide d'AGS 3.2 en français et contribuer à la traduction et à l'amélioration si le cœur vous en dit !


Dernière édition par Kitai le Jeu 4 Juil 2013 - 17:27, édité 2 fois (Raison : Réponse)
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://admin.no.uchi.free.fr/dokuwiki-2008-05-05/doku.php En ligne
Billbis
Disciple de la Grande Tasse Bleue
Disciple de la Grande Tasse Bleue


Nombre de messages : 1275

Date d'inscription : 10/05/2012


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Jeu 4 Juil 2013 - 17:48

Merci Kitai d'avoir pris le temps de tout expliquer.
Bon, même si je pense avoir compris le schéma général, il va me falloir mettre en application pour que je sois sûr de maitriser le truc. J'ai surtout l'impression qu'il me manque l'intuition de savoir quand il est pertinent d'utiliser ces méthodes, et quand ça l'est moins.
Il faut dire que j'ai de grosses lacunes en ce qui concerne la programmation orienté objet. Mais tu m'aide beaucoup à les combler.
Je sens que je ne suis plus très loin de comprendre pourquoi c'est si dramatique de ne pas pouvoir passer de pointeur vers ces structures personnalisées sous AGS script.

Kitai a écrit:
Je ne sais pas à quoi tu fais référence, mais sous AGS je n'ai pas connaissance d'un contexte où static soit optionnel.
Tu as raison, j'ai du confondre avec readonly. D'ailleurs, j'ai encore du mal à comprendre l’intérêt de l'encapsulation, mais ça viendra. (C'est bizarre d'interdire la modification d'une valeur pour ensuite coder un méthode pour modifier cette même valeur...)

_________________
Mon petit DevBlog
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://nothingaboutthedog.blogspot.fr/
Kitai
Délégué de la tasse bleue
Délégué de la tasse bleue


Nombre de messages : 2431

Date d'inscription : 01/08/2006


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Ven 5 Juil 2013 - 8:47

Billbis a écrit:
J'ai surtout l'impression qu'il me manque l'intuition de savoir quand il est pertinent d'utiliser ces méthodes, et quand ça l'est moins.
En ce qui concerne attribute, hormis le fait que ça permet de créer des propriétés globales des structures, ça permet aussi un grand contrôle sur les valeurs que peut prendre la propriété en question.

Billbis a écrit:
Je sens que je ne suis plus très loin de comprendre pourquoi c'est si dramatique de ne pas pouvoir passer de pointeur vers ces structures personnalisées sous AGS script.
Tant mieux ! Par contre je ne vois pas trop le rapport avec ces mots-clés...

Billbis a écrit:
Tu as raison, j'ai du confondre avec readonly. D'ailleurs, j'ai encore du mal à comprendre l’intérêt de l'encapsulation, mais ça viendra. (C'est bizarre d'interdire la modification d'une valeur pour ensuite coder un méthode pour modifier cette même valeur...)
En fait readonly n'est pas vraiment optionnel : ça change vraiment quelque chose de le mettre ou de l'omettre.

Peut-être qu'un exemple t'apparaîtra plus parlant que des discours abstraits.
Imagine que tu veuilles faire une structure qui représente des membres d'un forum (c'est qu'un exemple hein ! clin d\\\\'oeil). Entre autres choses, tu veux associer des grades aux membres ainsi que le titre correspondant (Cliqueur amateur, Disciple de la Tasse Bleue, etc.).
L'idée c'est qu'on va créer, hors des structures, un tableau de String qui va correspondre aux titres. Ensuite on attribuera un grade à chaque membre : au grade 0 le titre du membre correspondra donc à la chaîne d'indice 0 dans le tableau, au grade 1 son titre correspondra à la chaîne d'indice 1 dans le tableau, etc.
On commence donc avec le code suivant :
Code:
// Forum.ash (en-tête du script)
struct Membre {
  String Nom; // Le nom du membre
  int Grade; // Le grade (niveau) du membre
  import function AfficheLeGrade();
};


// Forums.asc (corps du script)
#define NOMBRE_GRADES 3
String Titres[NOMBRE_GRADES];

function game_start() {
  // Initialisation des grades
  Titres[0] = "Cliqueur amateur";
  Titres[1] = "Disciple de la Tasse Bleue";
  Titres[2] = "Grand cliqueur royal";
}

function Membre::AfficheLeGrade() {
  Display("Membre %s de grade %d (%s)", this.Nom, this.Grade, Titres[this.Grade]);
}
Mais que se passe-t-il si un utilisateur crée une instance Membre à laquelle il attribue un grade valant -1 ou 3 par exemple ? Le jeu crashera, parce qu'il y aura échec de référence dans le tableau, dont les indices possibles vont de 0 à 2.
Une solution consiste donc à faire du grade un attribut de la propriété, sur laquelle on aura plus de contrôle :
Code:
// Forum.ash (en-tête du script)
struct Membre {
  String Nom; // Le nom du membre
  import attribute int Grade; // Le grade : attribut (superficiel)
  protected int grade; // La contrepartie non superficielle et accessible uniquement depuis le corps d'une fonction de la structure (protected)
  import int get_Grade(); // $AUTOCOMPLETEIGNORE$
  import void set_Grade(int valeur); // $AUTOCOMPLETEIGNORE$
  import function AfficheLeGrade();
};


// Forums.asc (corps du script)
#define NOMBRE_GRADES 3
String Titres[NOMBRE_GRADES];

function game_start() {
  // Initialisation des grades
  Titres[0] = "Cliqueur amateur";
  Titres[1] = "Disciple de la Tasse Bleue";
  Titres[2] = "Grand cliqueur royal";
}

function Membre::AfficheLeGrade() {
  // Note l'utilisation de this.grade et non pas this.Grade
  Display("Membre %s de grade %d (%s)", this.Nom, this.grade, Titres[this.grade]);
}

void Membre::set_Grade(int valeur) {
  if (valeur < 0) valeur = 0;
  if (valeur >= NOMBRE_GRADES) valeur = NOMBRE_GRADES-1;
  this.grade = valeur;
}

int Membre::get_Grade() { return this.grade; }
Puisque la propriété Grade (note la majuscule) est maintenant un attribut (donc superficiel), on a besoin de stocker la valeur du grade elle-même ailleurs. C'est pourquoi on crée une véritable variable (non superficielle) grade (note bien la minuscule) qui contiendra la valeur.
Mais là on semble retomber sur le problème qu'on cherchait à éviter : on vient de recréer une variable modifiable par l'utilisateur. C'est là que le mot-clé protected va nous servir : cela empêche totalement à l'utilisateur d'accéder à la variable en question (grade). Cette variable sera consultable et modifiable uniquement depuis le corps d'une fonction de la structure (set_Grade et get_Grade par exemple).
Pour résumer : en surface, l'utilisateur récupère et modifie le grade du membre par la propriété Grade de la structure et il n'a pas accès à grade. De façon sous-jacente, c'est la variable grade qui va contenir la valeur du grade, et ce sera toujours la fonction set_Grade qui modifiera la valeur de grade et qui s'assurera qu'on ne lui passe pas une valeur hors des indices permis par le tableau Titres (0,1,2).

Maintenant imagine que tu veux aussi permettre à l'utilisateur de savoir combien il existe de grades. Une possibilité serait de mettre le #define dans l'en-tête histoire qu'il soit accessible partout. Mais imaginons en plus qu'il y a deux modes pour les grades : un mode binaire (où on ne définit que deux grades, de titres régulier et spécial) et un mode subtil (où on définit plus de deux grades, comme avant). Malgré tout tu veux que l'utilisateur puisse facilement savoir combien il y a de grades. Une possibilité serait d'exporter une variable NombreGrades dans l'en-tête. Mais alors l'utilisateur pourrait modifier cette valeur de façon arbitraire et on retomberait sur le problème du dépassement des indices pour le tableau.
On va donc utiliser le même type de subterfuge pour NombreGrades qu'on a utilisé pour Grade : on va en faire un attribut statique de la structure, histoire de pouvoir contrôler sa valeur. Et encore mieux : on va tout bonnement interdire à l'utilisateur de modifier cette valeur en utilisant le mot-clé readonly. Sa valeur ne sera déterminée que par le module au lancement du jeu selon le mode (binaire ou subtil) qu'on aura choisi :
Code:
// Forum.ash (en-tête du script)
#define MEMBRE_MODE eMembre_Subtil
struct Membre {
  String Nom; // Le nom du membre
  import attribute int Grade; // Le grade : attribut (superficiel)
  protected int grade; // La contrepartie non superficielle et accessible uniquement depuis le corps d'une fonction de la structure (protected)
  import int get_Grade(); // $AUTOCOMPLETEIGNORE$
  import void set_Grade(int valeur); // $AUTOCOMPLETEIGNORE$
  import function AfficheLeGrade(); // Affiche le grade du membre

  readonly import static attribute int NombreGrades; // Le nombre de grades possibles
};


// Forums.asc (corps du script)
#define NOMBRE_GRADES_SUBTILS 3
String Titres[];
enum eMembre_Mode {
  eMembre_Binaire,
  eMembre_Subtil
};

function game_start() {
  // Initialisation des grades
  if (MEMBRE_MODE == eMembre_Binaire) {
    Titres = new String[2];
    Titres[0] = "Régulier";
    Titres[1] = "Spécial";
  }
  else {
    Titres = new String[NOMBRE_GRADES_SUBTILS];
    Titres[0] = "Cliqueur amateur";
    Titres[1] = "Disciple de la Tasse Bleue";
    Titres[2] = "Grand cliqueur royal";
}

static int Membre::get_NombreGrades() {
  if (MEMBRE_MODE == eMembre_Binaire) return 2;
  else return NOMBRE_GRADES_SUBTILS;
}

function Membre::AfficheLeGrade() {
  Display("Membre %s de grade %d (%s)", this.Nom, this.grade, Titres[this.grade]);
}

void Membre::set_Grade(int valeur) {
  if (valeur < 0) valeur = 0;
  if (valeur >= Membre.get_NombreGrades()) valeur = Membre.get_NombreGrades()-1;
  this.grade = valeur;
}

int Membre::get_Grade() { return this.grade; }
Ainsi, ailleurs dans ton jeu, tu peux savoir le nombre de grades indépendamment du mode dans lequel tu te trouves. Par exemple tu peux vouloir proposer au joueur de jouer un administrateur du forum qui modifie le grade des utilisateurs, et vérifier que le joueur passe un grade acceptable :
Code:
if (grade_que_le_joueur_propose < 0 || grade_que_le_joueur_propose >= Membre.NombreGrades) Display("Valeur impossible : doit être comprise entre 0 et %d", Membre.NombreGrades-1);

Voilà, il y aurait encore des choses à dire vis-à-vis du fait qu'on peut avoir des tableaux comme attributs ou encore qu'on ne peut pas faire référence directement aux attributs dans le corps du script qui définit leurs fonctions associées, mais cela est expliqué sur la page du wiki anglophone.

En espérant avoir montré la pertinence de ces mots-clés !

_________________
Ga is Ga
Vous pouvez consulter l'aide d'AGS 3.2 en français et contribuer à la traduction et à l'amélioration si le cœur vous en dit !


Dernière édition par Kitai le Ven 5 Juil 2013 - 8:53, édité 2 fois (Raison : rectification du code)
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://admin.no.uchi.free.fr/dokuwiki-2008-05-05/doku.php En ligne
Billbis
Disciple de la Grande Tasse Bleue
Disciple de la Grande Tasse Bleue


Nombre de messages : 1275

Date d'inscription : 10/05/2012


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Ven 5 Juil 2013 - 10:15

Super, c'est un peu complexe en première lecture, mais très clair.
Merci Kitai. coeur
Me reste plus qu'à surpasser mes névroses philosophiques :
- Pourquoi priver de libertés comme ça un pauvre utilisateur ? Lui "empêche[r] totalement [...] d'accéder" à une variable ? Je doit encore être trop libertaire...
- Je comprend bien que ça limite un peu les crash, mais bon... On peut toujours rajouter des if à l’infini dans ce cas. Parce que si j'ai bien compris :
Code:
Billbis.Grade = 1000; //Ne crashera pas
Billbis.Grade = "Roi suprême"; // Crashera quand même malgré tout notre bazar avec les attribute employés.
Mais j'avais déjà remarqué que tu aimais bien mettre des if partout (ce qui doit surement être bien), alors que moi j'aimais bien en mettre le moins possible. Et si ça crash parce que l'utilisateur a fait une bêtise, et bin bien fait pour lui !
^^

_________________
Mon petit DevBlog
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://nothingaboutthedog.blogspot.fr/
Kitai
Délégué de la tasse bleue
Délégué de la tasse bleue


Nombre de messages : 2431

Date d'inscription : 01/08/2006


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Ven 5 Juil 2013 - 15:10

Billbis a écrit:
- Pourquoi priver de libertés comme ça un pauvre utilisateur ? Lui "empêche[r] totalement [...] d'accéder" à une variable ? Je doit encore être trop libertaire...
Quel proudhoniste : ni dieux ni maîtres ni readonly !
Mais remarque que j'ai parlé un peu vite : readonly n'empêche pas totalement l'utilisateur d'accéder aux variables, en fait cela l'empêche plutôt d'y accéder n'importe comment (il peut toujours ouvrir le fichier .asc et aller y modifier la valeur s'il le souhaite).
Est-ce que tu préférerais que les voitures modernes n'aient pas de capot qui recouvre leur moteur ? clin d\\\\'oeil

Billbis a écrit:
- Je comprend bien que ça limite un peu les crash, mais bon... On peut toujours rajouter des if à l’infini dans ce cas.
Billbis a écrit:
Mais j'avais déjà remarqué que tu aimais bien mettre des if partout (ce qui doit surement être bien), alors que moi j'aimais bien en mettre le moins possible. Et si ça crash parce que l'utilisateur à fait une bêtise, et bin bien fait pour lui !
^^
Je peux concevoir qu'on estime que l'utilisateur du module doit prendre toutes ses responsabilités, mais n'est-ce pas un peu radical ? Si je programme ma machine à laver et que je définis une température trop élevée pour le programme sélectionné, est-ce que la machine devrait ajuster automatiquement à la valeur maximale pour le programme, ou est-ce qu'elle devrait brûler mes vêtements ?
Mais en toute honnêteté, c'est une fausse alternative : la machine pourrait simplement ne pas lancer le programme, et même émettre un avertissement.
C'est peut-être le comportement que tu préférerais, et les attributs te permettent de faire cela :
Code:
// Fichier.ash
struct MaStructure {
  import attribute int ID;
  protected int id;
  import int get_ID();
  import void set_ID(int id);
};


// Fichier.asc
#define MAX_ID 9
int MaStructure::get_ID() { return this.id; }
void MaStructure::set_ID(int id) {
  if (id < 0) AbortGame("Tentative d'assigner un ID négatif à une instance de MaStructure");
  if (id > MAX_ID) AbortGame("Tentative d'assigner un ID supérieur à la limite (%d) à une instance de MaStructure", id);
  this.id = id;
}

_________________
Ga is Ga
Vous pouvez consulter l'aide d'AGS 3.2 en français et contribuer à la traduction et à l'amélioration si le cœur vous en dit !
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://admin.no.uchi.free.fr/dokuwiki-2008-05-05/doku.php En ligne
Billbis
Disciple de la Grande Tasse Bleue
Disciple de la Grande Tasse Bleue


Nombre de messages : 1275

Date d'inscription : 10/05/2012


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Ven 5 Juil 2013 - 15:24

Kitai a écrit:
Est-ce que tu préférerais que les voitures modernes n'aient pas de capot qui recouvre leur moteur ?
En tout cas, je préférerai que les imprimantes ne soient pas fermés avec des vis hexagonales. clin d\\\\'oeil
Mais n'en jette plus, je suis convaincu (mais encore un peu névrosé). Encore merci pour ces explications très instructives.

_________________
Mon petit DevBlog
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://nothingaboutthedog.blogspot.fr/
Billbis
Disciple de la Grande Tasse Bleue
Disciple de la Grande Tasse Bleue


Nombre de messages : 1275

Date d'inscription : 10/05/2012


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Mar 16 Juil 2013 - 17:53

J'ai retrouvé comment s'appelait le fait d'être réticent à l'encapsulation : ça vient que quand j'avais essayé d'apprendre Python :
Lu sur Wikipedia ou sur ce blog :
Thibaut Sertier a écrit:
Nous sommes entre adultes consentants

Cette phrase décrit l’absence de notion de privé/public en Python : tout est accessible, on fait confiance au développeur pour ne pas faire n’importe quoi. Si vous invitez vos amis chez vous, vous ne mettez pas de cadenas sur votre tiroir à lingerie : vous leur faites confiance pour ne pas aller fourrer leur nez dedans, et si ils le font quand même, c’est sans doute qu’ils ont une bonne raison (ou que vous devriez changer d’amis).

Plus globalement, cette phrase résume assez bien l’esprit de Python. Pourquoi restreindre des usages, masquer des informations ? Déjà ça n’aurait pas beaucoup de sens dans un langage de script non compilé, où il suffit d’un éditeur de texte pour lire un programme. Mais surtout, on passerait à côté de l’opportunité d’utiliser un programme de manière créative, de le détourner de son but premier pour répondre à un besoin que l’auteur n’imaginait même pas.
Oui, ma mauvaise foi est sans limites et se cache derrière des justifications et références obscures. langue

_________________
Mon petit DevBlog


Dernière édition par Billbis le Mer 17 Juil 2013 - 8:02, édité 2 fois
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://nothingaboutthedog.blogspot.fr/
valoulef
Délégué de la tasse bleue
Délégué de la tasse bleue


Nombre de messages : 1278

Age : 27

Localisation : Condate

Date d'inscription : 01/08/2011


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Mar 16 Juil 2013 - 19:04

"Nous sommes entre adultes consentants"... La phrase pertinente ne serait pas plutôt "Nous sommes entre adultes responsables" ? Parce que là euh...

Non je ne ferai pas un commentaire plus intelligent, ça me fait très peur de lire vos dizaines et dizaines de lignes (pourtant probablement très instructives) je ne suis pas sûr d'avoir assez de paracétamol en stock... ^^

_________________
"Je pense que la Terre tourne autour du soleil à une vitesse de 30 kilomètres par seconde et que je suis là, accroché à ce bolide de feu qui fonce d'un infini à un autre, accroché à une table, suspendu dans le vide, pendant que, sérieusement, drogué, abruti, inconscient, j'affirme que nous sommes désolés d'apprendre la perte d'un colis expédié le 4 et que nous ferons l'impossible pour réparer cet incident."

L'Employé, Jacques Sternberg.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Kitai
Délégué de la tasse bleue
Délégué de la tasse bleue


Nombre de messages : 2431

Date d'inscription : 01/08/2006


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Mar 16 Juil 2013 - 19:46

Billbis a écrit:
Oui, ma mauvaise foi et sans limites et se cache derrière des justifications et références obscures. langue
Je suis surtout impressionné par l'effort (l'obsession ? clin d\\\\'oeil) que tu mets à retrouver ça !

Thibaut Sertier a écrit:
Si vous invitez vos amis chez vous, vous ne mettez pas de cadenas sur votre tiroir à lingerie : vous leur faites confiance pour ne pas aller fourrer leur nez dedans, et si ils le font quand même, c’est sans doute qu’ils ont une bonne raison (ou que vous devriez changer d’amis).
Quitte à filer la métaphore, je ferai remarquer qu'on prend justement généralement soin de mettre la lingerie dans le tiroir, souvent opaque, et non pas partout bien en vue dans l'appartement clin d\\\\'oeil
On ne voudrait ni leur en imposer la vue, ni risquer de l'abîmer.

_________________
Ga is Ga
Vous pouvez consulter l'aide d'AGS 3.2 en français et contribuer à la traduction et à l'amélioration si le cœur vous en dit !
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://admin.no.uchi.free.fr/dokuwiki-2008-05-05/doku.php En ligne
Billbis
Disciple de la Grande Tasse Bleue
Disciple de la Grande Tasse Bleue


Nombre de messages : 1275

Date d'inscription : 10/05/2012


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Mer 4 Déc 2013 - 21:11

Coucou,
j'essaye de rajouter une propriété à la classe Character. Je ne suis pas bien sur que le langage de script d'AGS permette ça. Pour l'instant mon code ressemble à ça :
Code:
// Header
import bool Character::IsoMoving();

// Script
bool Character::IsoMoving() {
  if (this.Moving || IsoW_noBlock) return true;
  else return false;
}
Mais j'ai un message d’erreur sur l'import : 'Character' does not contain a function 'IsoMoving'
J'ai essayé ça :
Code:
// Header
struct Character {
  import bool IsoMoving();
}
Et le message est le suivant :  'Character' is already defined
Je suis un peu perdu. rougit
Sinon je peux faire ça :
Code:
// Header
import bool IsoMoving(this Character*);

//Script
bool IsoMoving(this Character*) {
  if (this.Moving || IsoW_noBlock) return true;
  else return false;
}
Mais ça oblige à appeler la fonction avec une parenthèse vide ( cEgo.IsoMoving() au lieu de cEgo.IsoMoving ). perplexe
Des suggestions ?

_________________
Mon petit DevBlog
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://nothingaboutthedog.blogspot.fr/
Kitai
Délégué de la tasse bleue
Délégué de la tasse bleue


Nombre de messages : 2431

Date d'inscription : 01/08/2006


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Jeu 5 Déc 2013 - 8:47

Billbis a écrit:
Mais j'ai un message d’erreur sur l'import : 'Character' does not contain a function 'IsoMoving'
C'est bizarre, je croyais qu'AGS supportait désormais la déclaration type Character::fonction() pour type fonction(this Character*).
Peut-être que c'est en revanche impossible pour l'import, où il faut toujours passer par import type fonction(this Character*);.

Billbis a écrit:
Et le message est le suivant :  'Character' is already defined
Oui car le mot-clé struct est réservé aux structure personnalisées, il ne peut pas être utilisé sur les structures prédéfinies (même si c'est un peu plus compliqué, d'où l'utilisation du mot-clé managed dans agsdefns.sh).

Billbis a écrit:
Mais ça oblige à appeler la fonction avec une parenthèse vide ( cEgo.IsoMoving() au lieu de cEgo.IsoMoving ). perplexe
En fait si ce que tu essayes de faire au début marchait (ou même la version avec struct), tu serais là aussi obligé d'appeler avec une paire de parenthèses. Puisque dans tous les cas c'est une fonction que tu cherches à définir, vu qu'il y a des parenthèses dans ta déclaration.

Billbis a écrit:
j'essaye de rajouter une propriété à la classe Character. Je ne suis pas bien sur que le langage de script d'AGS permette ça.
En effet : AGS ne permet pas encore d'ajouter des propriétés (en l'occurrence un attribut) à des structures prédéfinies.

Je pense que la seule "solution" est donc de faire une version fonction.

_________________
Ga is Ga
Vous pouvez consulter l'aide d'AGS 3.2 en français et contribuer à la traduction et à l'amélioration si le cœur vous en dit !
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://admin.no.uchi.free.fr/dokuwiki-2008-05-05/doku.php En ligne
Billbis
Disciple de la Grande Tasse Bleue
Disciple de la Grande Tasse Bleue


Nombre de messages : 1275

Date d'inscription : 10/05/2012


MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Jeu 5 Déc 2013 - 19:48

Kitai a écrit:
En effet : AGS ne permet pas encore d'ajouter des propriétés (en l'occurrence un attribut) à des structures prédéfinies.

Je pense que la seule "solution" est donc de faire une version fonction.
triste 
Merci pour la réponse et pour ces éclaircissements, Kitai !

_________________
Mon petit DevBlog
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://nothingaboutthedog.blogspot.fr/
Contenu sponsorisé




MessageSujet: Re: Structures et mots-clés (static, attribute, readonly...)   Aujourd'hui à 17:20

Revenir en haut Aller en bas
 
Structures et mots-clés (static, attribute, readonly...)
Voir le sujet précédent Voir le sujet suivant Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» Structures et mots-clés (static, attribute, readonly...)
» La suite en 4 mots
» Jeux de mots, Ramoucho !
» ORIGINE DES MOTS OU EXPRESSIONS
» Problème de ... hmm, j'éditerais quand j'aurais trouvé mes mots ^^

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
Adventure Games Studio fr :: CREATION DE JEUX :: Questions / Réponses-
Sauter vers: