See site in english Voir le site en francais
Website skin:
home  download  forum  link  contact

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

Author Topic: [tutorial] Posez vos question sur les DLL C++ (no 2)  (Read 28751 times)

0 Members and 1 Guest are viewing this topic.

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 14999
  • Karma: 172
  • Hein, quoi !?
    • FsPassengers
Reply #50 - 23 May 2008, 18:02:42
Cool !

Peut être spacecraft et la similarité des noms ? En tout cas une cause exogène il semble.
Mais rassure toi, les CTD "bizarre" sont assez rare. En général on a fait une bêtise dans
le code et on la trouve rapidement.

A++

Dan


Offline Papyref

  • Legend
  • ******
  • Posts: 4726
  • Country: France fr
  • Karma: 180
  • Je suis dans la Lune ne pas me déranger
Reply #51 - 28 May 2008, 09:56:03
Question probablement bête !

Pour animer une trappe faite de deux meshes par exemple j'écris:

static UINT GrpMeshTrappeDroit[2] = {72,73};
TrappeDroitOuvre = new MGROUP_ROTATE (0, GrpMeshTrappeDroit,2, _V(-7,-7,0), _V(0,0,1), float(-0.7*PI));

Pour définir ce que doit faire le GrpMesh et de quoi il est constitué.

Je pense que dans ce cas par exemple un petit tableau de données est constitué avec les deux meshes cités en
première ligne et que ces données vont être utilisées pour construire le groupe.

Dans l'initialisation des variables de classe on écrit
TrappeDroitOuvre   =NULL;  
qui mets le pointeur à zéro.

Que se passerait il si on ne mettait pas le pointeur à zéro ? Je ne vois pas de différence en testant l'animation !

:sage: Papyref


Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 14999
  • Karma: 172
  • Hein, quoi !?
    • FsPassengers
Reply #52 - 28 May 2008, 10:57:05
Quote
Papyref a écrit:
static UINT GrpMeshTrappeDroit[2] = {72,73};
TrappeDroitOuvre = new MGROUP_ROTATE (0, GrpMeshTrappeDroit,2, _V(-7,-7,0), _V(0,0,1), float(-0.7*PI));
Pour définir ce que doit faire le GrpMesh et de quoi il est constitué.
Je pense que dans ce cas par exemple un petit tableau de données est constitué avec les deux meshes cités en
première ligne et que ces données vont être utilisées pour construire le groupe.

Exact, ne pas oublier de mettre le nombre d'entrée du tableaux en parametres je crois que c'est celui la (que tu a
bien mis à 2): (0, GrpMeshTrappeDroit,2, _V(-7,-7,0), _V(0,0,1), float(-0.7*PI));

Le mettre faux peu faire des plantées.

Quote
Papyref a écrit:
Dans l'initialisation des variables de classe on écrit
TrappeDroitOuvre   =NULL;  
qui mets le pointeur à zéro.
Que se passerait il si on ne mettait pas le pointeur à zéro ? Je ne vois pas de différence en testant l'animation !

Pour autant que tu n'aie fais aucune erreurs et dans ce cas précis aucuns avantages vu que la variable est assignée
par le "TrappeDroitOuvre=new" avant utilisation. Donc qu'elle aie une valeur indéfinie (n'importe quoi) ou
0 (NULL) avant cette assignation ca ne change rien.

Mais ca ne change pas la rêgle imuable: "toutes variables de classe doivent être initialisée" et j'explique pourquoi.

1-Imagine que tu à fais une erreur au niveau du "new" tu part en débug tu controle ton pointeur quand il doit être
utilisé et comme tu ne l'a pas initialisé à zéro tu vois une valeur "0x3A45FFE" tu te dis "il est valide" et tu perd trois
heures et 1247 cheveux à chercher ailleurs le problème. Avec initialisation tu voit tout de suite qu'il est "null" au
moment de l'utilisation: tu tiens ton bug !

2-Rêgle immuable: tout pointeur invalide doit obligatoirement être à zéro (NULL)

Les pointeurs invalides sont une des premières cause de CTD, une fois le programme touffu avec pleins de
pointeurs ca devient un casse tête si on n'a pas pris dès le début cette bonne habitude.
Donc à l'initialisation= NULL et quand on les "détruit" on devrais toujours utiliser des fonctions de "delete" qui
remettent en plus le pointeur à zéro. (cf: SafeDelete() )

Ca permet en plus de mettre toutes les fonctions sensibles qui utilisent des pointeurs derrières des conditions qui
vont toutes assumer qu'un pointeur à zéro est invalide et valide sinon:

Code: [Select]
if(cMonPointeur!=NULL)   // passe seulement si pointeur non null
{
    ExecuteFonctionSensible(MonPointeur); // aucun risque de CTD
}

3- une variable de classe non initialisée est une cause fréquente de bug chez le débutant (et même plus tard)

4-Même si ce n'est pas absolument indispensable comme dans ton cas, le fait d'initialiser systématiquement tes
valeurs de classes va t'inculquer un véritable reflexe salutaire: "1-j'ajoute dans la classe, 2-j'initialise"
qui va te prémunir contre des oublis (on oublie déjà assez de trucs comme cela pour prendre en plus de mauvaises
habitudes)

5- Même si il n'y a pas absolument besoin dans un cas précis imagine que tu change un peu ton code et que maintenant tu aurais besoin quelle soit initialisée, comment fera tu pour gêrer le fait que tu à une moitié de variables initialisée et l'autre pas... tout recontroller ?

Donc pour toutes ces raisons, variables, pointeur, tableaux, tout ce qui est declaré dans la classe devrait être à 100% initialisé après le constructeur (clbkSetClassCap dans notre cas)

Ca répond ?

A++

Dan



Message modifié ( 28-05-2008 11:04 )


Offline Papyref

  • Legend
  • ******
  • Posts: 4726
  • Country: France fr
  • Karma: 180
  • Je suis dans la Lune ne pas me déranger
Reply #53 - 28 May 2008, 11:17:40
OK merci Dan !

Papy


Offline Papyref

  • Legend
  • ******
  • Posts: 4726
  • Country: France fr
  • Karma: 180
  • Je suis dans la Lune ne pas me déranger
Reply #54 - 28 May 2008, 17:54:31
J'ai créé une animation pour les portes avec SetAnimation (uAnim_Porte , Porte_proc);
Elle fonctionne bien avec le Keyboard en passant par un RevertPorte ().

Il me semble qu'une animation étant caractérisée par son status et sa procédure, ce sont ces paramètres que je dois
sauvegarder dans le scénario.

J'ai donc écrit ce qui suit pour sauvegarder dans le scénario puis recharger:

Quote
void Hercule::clbkSaveState(FILEHANDLE scn)
{
   char cbuf [256];

   VESSEL2::clbkSaveState (scn);

   sprintf (cbuf," %d %0.4f",Porte_status,Porte_proc);
   oapiWriteScenario_string (scn,"PORTE", cbuf);

}

void Hercule::clbkLoadStateEx(FILEHANDLE scn, void *vs)
{
   char *line;

   while (oapiReadScenario_nextline (scn, line))
   {
      if (!_strnicmp (line, "PORTE", 5))
      {
         sscanf (line+5, "%d %0.4f", &Porte_status,&Porte_proc);
      }
      else
      {
         ParseScenarioLineEx (line, vs);
      }

   }

   SetAnimation (uAnim_Porte , Porte_proc);
}

Si je sauvegarde  avec les portes fermées j'obtiens dans le scénario PORTE 0 0.0000 et si je sauvegarde portes
ouvertes j'obtiens 3 1.0000

Quand je relance mon scénario sauvegardé portes ouvertes, les portes sont fermées. Ca aurait été trop beau si ça
avait marché !
Ou est mon erreur d'interprétation ?

:sick: PoorPapyref


Offline no matter

  • Legend
  • ******
  • Posts: 2826
  • Karma: 0
Reply #55 - 28 May 2008, 18:08:03
Quote
Si je sauvegarde avec les portes fermées j'obtiens dans le scénario PORTE 0 0.0000 et si je sauvegarde
portes ouvertes j'obtiens 3 1.0000

SetAnimation (uAnim_Porte , Porte_proc); est bien dans clbkPostCreation?

EDIT:
Quote
Il me semble qu'une animation étant caractérisée par son status et sa procédure, ce sont ces paramètres que je dois sauvegarder dans le scénario.
Absolument et il me semble que cette partie-là est ecrite correctement dans ton code, d'ailleurs le scénario sauvegardé le confirme. L'erreur vient plutôt ensuite, après la lecture au moment d'initialiser l'animation, d'où mon idée sur SetAnimation().



Message modifié ( 28-05-2008 18:14 )

------------

no matter.

Offline Papyref

  • Legend
  • ******
  • Posts: 4726
  • Country: France fr
  • Karma: 180
  • Je suis dans la Lune ne pas me déranger
Reply #56 - 28 May 2008, 18:23:54
Mon SetAnimation est en clbkPostStep et je ne vois pas trop pourquoi il ne marcherait pas ?
Le maitre aura peut être un avis. Je dois avoir oublié d'initialiser quelquechose


Offline no matter

  • Legend
  • ******
  • Posts: 2826
  • Karma: 0
Reply #57 - 28 May 2008, 18:52:46
En effet, tel qu'il est écrit il est correct.

Lorsque tu recharges un scénario avec la porte ouverte, l'anim n'est pas initialisée dans l'état sauvegardé, tu te
retrouves donc avec porte fermée. Que se passe-t-il si tu lance l'anim?
La porte s'ouvre ou passe subitement de l'état fermé à l'état ouvert sans intermédiaire pour se refermer?

Sinon, effectivement, je ne vois pas d'erreur au niveau de ce que tu as posté.
J'utilise plutôt strnicmp (respect de la casse obligatoire) que _strnicmp (se fout royalement de la casse) mais ce n'est
pas le problème ici.



Message modifié ( 28-05-2008 18:53 )

------------

no matter.

Offline Papyref

  • Legend
  • ******
  • Posts: 4726
  • Country: France fr
  • Karma: 180
  • Je suis dans la Lune ne pas me déranger
Reply #58 - 28 May 2008, 19:41:00
En lançant le scénario suavegardé porte ouverte, la porte est fermée et il faut que je demande deux fois son
ouverture avec le clavier pour qu'elle fonctionne.
Son ouverture doit donc bien être demandée mais elle ne marche pas et la première demande doit réinitialiser et
permettre à la deuxième de s'éxecuter.


Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 14999
  • Karma: 172
  • Hein, quoi !?
    • FsPassengers
Reply #59 - 28 May 2008, 20:35:54
Quote
Papyref a écrit:
Mon SetAnimation est en clbkPostStep et je ne vois pas trop pourquoi il ne marcherait pas ?
Le maitre aura peut être un avis. Je dois avoir oublié d'initialiser quelquechose

Dans clbkPostStep le SetAnimation n'est executé QUE si le status de la port est "OPENING" ou "CLOSING"
donc si le status est CLOSED ou OPEN il n'est jamais executé. (ET ca DOIT rester comme cela!)

Donc le mettre en plus à la fin de "clbkLoadStateEx" EST la bonne solution.

Bon a savoir: Les callback sont appellé dans cet ordre au lancement:

1-ClbkSetClassCap
2-DefineAnimation (appellé par le précédent)
3-clbkLoadStateEX (animation valide, restore les variable, remet la porte à la position sauvegardée)
4-clbkPostStep

Par contre je te conseil fortement d'utiliser ma classe "saveRestore" plutot que la méthode par defaut d'Orbiter.
Ma methode est hyper simple une fois la classe incluse dans le projet et t'évitera beaucoup de prise de têtes avec les
saves restore des variables.

Classe SaveRestore à telecharger ici:
http://orbiter.dansteph.com/forum/index.php?topic=6381.msg96441#msg96441


Une fois installée et "loadState et "saveState" modifié exactement comme decrit dans l'instalation au début de
clbkSetClassCap inclure ceci:

Code: [Select]
void MonAddon::clbkSetClassCaps (FILEHANDLE cfg)
{

////////////////////////////////////////////////////////////
// DEFINI LES VARIABLES A SAUVER/RESTORER
// elle seront sauvées/resotrées automatiquement
// dans clbkSaveState et clbkLoadStateEx
////////////////////////////////////////////////////////////
Scn.InitClass();   // obligatoirement en premier
// Variables compressée (utilisation normale)
Scn.SavedVariable(0, &Porte_status);
Scn.SavedVariable(1, &Porte_proc);


Variante si tu veux garder des noms explicites dans le scenario:

Code: [Select]
void MonAddon::clbkSetClassCaps (FILEHANDLE cfg)
{

////////////////////////////////////////////////////////////
// DEFINI LES VARIABLES A SAUVER/RESTORER
// elle seront sauvées/resotrées automatiquement
// dans clbkSaveState et clbkLoadStateEx
////////////////////////////////////////////////////////////
Scn.InitClass();   // obligatoirement en premier
Scn.SavedVariable("DOOR_STATUS", &Porte_status);
Scn.SavedVariable("DOOR_STATE", &Porte_proc);



A la fin de "clbkLoadStateEx" rajoute en plus "SetAnimation" comme ci-dessous:

Code: [Select]
// --------------------------------------------------------------
// Read status from scenario file
// --------------------------------------------------------------
void ShuttlePB::clbkLoadStateEx (FILEHANDLE scn, void *vs)
{
char *line;
while (oapiReadScenario_nextline (scn, line))
{
if(Scn.LoadScenario(line)==TRUE)
continue;
ParseScenarioLineEx (line, vs); // unrecognised option - pass to Orbiter's generic parser
}

// ici les variables sont toutes restorées
// remet les portes à la bonne position
SetAnimation (uAnim_Porte , Porte_proc);
}



Message modifié ( 28-05-2008 20:55 )


Offline Papyref

  • Legend
  • ******
  • Posts: 4726
  • Country: France fr
  • Karma: 180
  • Je suis dans la Lune ne pas me déranger
Reply #60 - 28 May 2008, 20:52:07
Merci Maître.
Demain je revois ma copie !

:sage: Papyref


Offline no matter

  • Legend
  • ******
  • Posts: 2826
  • Karma: 0
Reply #61 - 28 May 2008, 20:53:58
Quote
Classe SaveRestore à telecharger ici:
http://orbiter.dansteph.com/forum/index.php?topic=6381.msg96441#msg96441
A propos de cette classe justement, j'avais bien saisi l'intérêt mais j'avais raté ceci:
"cette classe offre en plus la possibilité de sauver des variables "non compressée" avec un nom pour garder la
possibilité d'édition
"
Et dire que je l'ai pas utilisée jusqu'ici parce que je croyais que tout était compressé et non éditable dans le .scn.
Impardonnable ^^



Message modifié ( 28-05-2008 20:55 )

------------

no matter.

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 14999
  • Karma: 172
  • Hein, quoi !?
    • FsPassengers
Reply #62 - 28 May 2008, 21:00:20
C'est clair que c'est un gain de temps et une source de prise de tête et d'erreur énormes supprimée.
Que ne l'ai je pas ecrite plus tot et utilisé dans le DGIII/IV  :sad: ... j'ai perdu des heures et des milliers de cheveux avec l'ancienne methode. :pfff:

Par contre bien comprendre le principe:

Dans clbkSetClassCap on "marques" les variables comme "à sauver/restorer" mais elle ne sont pas sauvées ni restorées à cet endroit !!!!

Elle le seront automatiquement dans les fonctions "clbkLoadStateEx" et "clbkSaveState" si on doit remettre des
choses comme les animations le faire donc à la fin de "clbkLoadStateEx"

Dan



Message modifié ( 28-05-2008 21:02 )


Offline Schimz

  • Legend
  • ******
  • Posts: 1598
  • Karma: 1
Reply #63 - 31 May 2008, 20:47:43
Hello les gens :)

Je retrouve plus le topic qui parlait de l'édition de ressources, un peu indispensable pour refaire un projet au
propre (avant de venir pleurer pour un oui ou pour un non :badsmile: )

ps : j'ai changé de VS because la version de 97(!) marche pas avec OS3.5.



Offline picto

  • Legend
  • ******
  • Posts: 5013
  • Country: France fr
  • Karma: 24
  • Criiii Crii Crii
Reply #64 - 31 May 2008, 21:07:18

Hello Schimz,
Content de te voir dans le coin. :beer:

Si c'est ResEdit que tu cherches, ça en cause un peu là .... mais c'est un peu nul. :sad:
http://orbiter.dansteph.com/forum/index.php?topic=6342.msg95681#msg95681

Et là, le post de NoMatter, le troisième en partant du bas de la page
http://orbiter.dansteph.com/forum/index.php?topic=6342.msg95675#msg95675

Extrait :

Oui, la version express de VC++ ne permet pas d'éditer de fichier .rc.
Il faut passer par un autre logiciel pour les modifier, pr exemple:
http://www.resedit.net/ (doit y'en avoir d'autre...)


Pic

Offline Schimz

  • Legend
  • ******
  • Posts: 1598
  • Karma: 1
Reply #65 - 01 June 2008, 20:02:32
ok danke



Offline Coussini

  • Legend
  • ******
  • Posts: 3050
  • Country: Canada ca
  • Karma: 6
Reply #66 - 01 June 2008, 23:29:36
Salut Schimz... content de te revoir ici également. Re-Bon-Vol parmis nous ;)


Coussini "Maître des liens"


Offline Papyref

  • Legend
  • ******
  • Posts: 4726
  • Country: France fr
  • Karma: 180
  • Je suis dans la Lune ne pas me déranger
Reply #67 - 02 June 2008, 18:19:42
1 ére question

J'ai créé des animations de train droit et gauche avec parent pour des jambes de train se déplaçant en translation
entrainant un patin qui se déplace en rotation.
J'ai donc écrrit un truc comme ça:

   
Quote
//====================================================
   //ANIMATIONS AVEC PARENT
   //====================================================
   
   ANIMATIONCOMPONENT_HANDLE parent;

   //*** Jambes et patins du train

   static UINT GrpMeshJambeGauche[4] = {11,12,15,16};
    JambeGaucheOuvre = new MGROUP_TRANSLATE (0, GrpMeshJambeGauche,4, _V(1.5,-3.5,0));

   static UINT GrpMeshPatinGauche[3] = {20,59,61};
    PatinGaucheOuvre = new MGROUP_ROTATE (0, GrpMeshPatinGauche,3, _V(4.5,-4.9,0), _V(0,0,1), float(-0.166*PI));
   
   uAnim_JambeGauche  = CreateAnimation (0.0);
   parent = AddAnimationComponent (uAnim_JambeGauche, 0, 1,JambeGaucheOuvre );

   uAnim_PatinGauche = CreateAnimation (0.0);
   AddAnimationComponent (uAnim_PatinGauche,0.2,1,PatinGaucheOuvre,parent);

   static UINT GrpMeshJambeDroit[4] = {13,14,17,18};
    JambeDroitOuvre = new MGROUP_TRANSLATE (0, GrpMeshJambeDroit,4, _V(-1.5,-3.5,0));

   static UINT GrpMeshPatinDroit[3] = {19,58,60};
    PatinDroitOuvre = new MGROUP_ROTATE (0, GrpMeshPatinDroit,3, _V(-4.5,-4.9,0), _V(0,0,1), float(0.166*PI));
   
   uAnim_JambeDroit  = CreateAnimation (0.0);
   parent = AddAnimationComponent (uAnim_JambeDroit, 0, 1,JambeDroitOuvre );

   uAnim_PatinDroit = CreateAnimation (0.0);
   AddAnimationComponent (uAnim_PatinDroit,0.2,1,PatinDroitOuvre,parent);


}  //*** FIN ANIMATION PARENT

Ca fonctionne mais j'ai un doute. Est ce que parent doit être réinitialisé pour chaque création sinon on risque des
ennuis. Si oui comment faudrait il procéder ?
Il ne me semble pas en regardant l'exemple du bras d'Atlantis mais j'aimerai en être sûr.

2ème question

Elle concerne la classe Save Load

J'ai procédé aux modifs conformément au post de Dan pour pouvoir obtenir la sauvegarde et le chargement dans le
scénario et fait l'init en clbkSetClassCaps

Quote
void Hercule::clbkSetClassCaps (FILEHANDLE cfg)
{
   Scn.InitClass();
..............
Si je lance une compile j'ai le message ci dessous

1>Compilation en cours...
1>clbkSetClassCap.cpp
1>f:\orbiter\orbitersdk\samples\herculebidon\clbksetclasscap.cpp(13) : error C2065: 'Scn' : identificateur non déclaré
1>f:\orbiter\orbitersdk\samples\herculebidon\clbksetclasscap.cpp(13) : error C2228: la partie gauche de '.InitClass'
doit avoir un class/struct/union
1>        le type est ''unknown-type''
1>Le journal de génération a été enregistré à
l'emplacement "file://f:\Orbiter\Orbitersdk\samples\HerculeBidon\Debug\BuildLog.htm"
1>Hercule - 2 erreur(s), 0 avertissement(s)
========== Génération : 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========


Quelle erreur ai je pu commettre pour obtenir ce message ésotérique ?

Merci pour tout renseignement qui sera récompensé par un pot au Papybar

:stupid: Papyref


Offline MartySpaceLines

  • Legend
  • ******
  • Posts: 1096
  • Karma: 0
Reply #68 - 02 June 2008, 18:22:15
Pour la 2ème question: t'as déclaré SaveRestore.h (ou quelque-chose comme ca) dans la classe?


@++

MSL  


Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 14999
  • Karma: 172
  • Hein, quoi !?
    • FsPassengers
Reply #69 - 02 June 2008, 18:42:04
Quote
Papyref a écrit:
1&gtf:\orbiter\orbitersdk\samples\herculebidon\clbksetclasscap.cpp(13) : error C2228: la partie gauche
de '.InitClass'
doit avoir un class/struct/union
1&gt        le type est ''unknown-type''
1&gtLe journal de génération a été enregistré à
l'emplacement "file://f:\Orbiter\Orbitersdk\samples\HerculeBidon\Debug\BuildLog.htm"

il doit te manquer surtout le handle de la classe saverestore "Scn" en rouge:

Code: [Select]
#include "orbitersdk.h"

#include "SaveRestoreScenario.h"  // header du SDK

class Hercule:public VESSEL2
{
public:
Hercule(OBJHANDLE hVessel, int flightmodel): VESSEL2 (hVessel, flightmodel) {}

SaveRestoreScenario Scn;  // handle de la classe
                .....
}

Dan



Message modifié ( 02-06-2008 18:42 )


Offline Papyref

  • Legend
  • ******
  • Posts: 4726
  • Country: France fr
  • Karma: 180
  • Je suis dans la Lune ne pas me déranger
Reply #70 - 07 June 2008, 09:31:19
Problème réglé pour SaveRestore grâce à ton aide. Merci Dan !
Je ferai plus attention aux indentations dans les boucles...

Une question qui va paraître saugrenue : si on écrit MaFonction () est ce pareil que MaFonction (void) ?

:sage: Papyref l'édenté (pas l'indenté)


Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 14999
  • Karma: 172
  • Hein, quoi !?
    • FsPassengers
Reply #71 - 07 June 2008, 12:42:59
void veut dire... "rien"

Par defaut effectivement tu peux déclarer une fonction comme ceci:

Code: [Select]
Function()
{

}

Et le compilateur lui comprend que tu a voulu dire:

Code: [Select]
Function(void)
{

}

Donc pas de passage de parametres, "rien" en bref.

De même une fonction qui ne retourne rien comme valeur s'écrit:

Code: [Select]
void Function(void)
{

}

au contraire d'une qui retournerait une valeur int par exemple:

Code: [Select]
int Function(void)
{


return 1;
}


En bref pour répondre à ta question:

Si tu écrit: "Function()" tu peux éventuellement confondre avec un "appel" de la fonction plutôt qu'une déclaration.
Je trouve mieux d'être plus "verbeux" donc je mets des void.

IMPORTANT A propos d'être verbeux justement, voila un piège vicieux, ou comment une sois-disante
économie de lignes peut nous pourrir la vie.

Une condition qui ne contient qu'une seule ligne n'a pas besoin de crochets:

Code: [Select]
if(Tata)
     CaMarche();
else
     CaMarcheAussi2();

Et voila comment s'arracher les cheveux à peu de frais;

Code: [Select]
if(Tata)
     CaMarche();
     MaisPlusIci();
else
     CaMarcheAussi2();

ET voui, sans crochets seule la ligne en dessous des if/else en dépend "MaisPlusIci()" sera exécuté à chaque fois.
C'est pour cela que JAMAIS je n'omets les crochets, même pour une condition à une seule ligne que je ne prévois pas
de modifier. (jamais jamais? ;)

Code: [Select]
// voila du rustique concu pour les intempéries
if(Tata)
{
     CaMarche();
}
else
{
     CaMarcheAussi2();
     EtIciAussi();
}

C'est plus long (plus lisible aussi) mais aucune chance d'avoir des problèmes. Sur un gros projets ça peut faire toutes la différence entre un truc fragile voir buggé à mort et une application stable.

Les "grrrrand" théoriciens du C++ qui sévissent sur les forums spécialisés et hurlent à l'hérésie quand on prend une ligne de plus ou quand on est verbeux ne sont souvent pas ceux qui écrivent des applications. Ce sont des "poêtes" qui aiment le verbe pour le verbe, pas des techniciens.

Donc verbeux: "void" et crochets... En prenant toujours les même tics d'écriture "bourrine" on minimise les risques d'oublis. Les ciselures ca le fait pas, du rustique , du costaud !

Dan



Message modifié ( 08-06-2008 07:35 )


Offline Papyref

  • Legend
  • ******
  • Posts: 4726
  • Country: France fr
  • Karma: 180
  • Je suis dans la Lune ne pas me déranger
Reply #72 - 07 June 2008, 14:37:02
Tu as raison Dan, il vaut mieux un peu de verbiage que de se trouver plus tard comme une poule devant un cure
dents !

J'ai suivi ton conseil et fait un clbkPostStep_AnimAuto à partir du clbkPostStep pour écrire mes conditions
d'animations automatiquzs sur critères particuliers et ça clarifie bien le listing.
C'est une bonne méthode surtout pour un projet complexe !

Mon train rentre et sort seul au décollage et à l'atterrissage en l'asservissant à l'altitude et au sens de la vitesse de
montée et je suis assez content de moi. Il me reste à faire des tests plus complets pour voir qu'il n'y a pas de
blocage possible.

Les spécialistes vont me trouver un peu simpliste mais ça fait plaisir d'y arriver !

PapyC++


Offline picto

  • Legend
  • ******
  • Posts: 5013
  • Country: France fr
  • Karma: 24
  • Criiii Crii Crii
Reply #73 - 07 June 2008, 15:15:02
Papy, n'aurais-tu pas envie d'ouvrir un topic parallèlle à celui-ci pour que l'on puisse se faire une idée de ton projet en
cours avec photos et tout le tremblement ?
A moins que tout ceci ne soit strictement classé Secret défense ...


Pic

Offline brainstorm

  • Legend
  • ******
  • Posts: 2693
  • Karma: 0
Reply #74 - 07 June 2008, 17:11:04
Voire Très Secret Défense .... :lol: