Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3102 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Des conseils sur mon programme, SVP

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

Des conseils sur mon programme, SVP

n°749232
yawen
Posté le 02-06-2004 à 18:08:48  profilanswer
 

Alors voilà, je suis en train de coder un "jeu" utilisant OpenGL, mais je me pose pas mal de questions metaphysiques sur ma façon de procéder. Je précise pour commencer que je n'ai jamais eu de cours de C++, donc je prierais par avance Taz d'éviter de se foutre de ma gueule si j'ai fais des trucs pas catholiques, je commence mes premiers vrais cours d'info l'année prochaine. Mais bref, voilà ma question :
 
J'ai créé une librairie pour gérer tout ce qui est affichage OpenGL : le principe est que lorsque mon programme veut créer un objet 3D, il demande à cette librairie un pointeur sur un objet de classe GL_Node. De cette classe sont dérivées tous les types d'objets gérés par mon programme : GL_Face, GL_Object (plusieurs faces), GL_Group (plusieurs objets), GL_Sprite, etc... Pour savoir quel objet ma librairie doit créer, je lui passe un pointeur NULL du type qui va bien (par exemple GL_Face) qui est récupérer par un fonction template qui va créer le bon objet :

Code :
  1. template<class T> T *NewNode(T *type) {
  2.    GL_Node *tmp=new T;
  3.    nodes.add(tmp);
  4.    return tmp;
  5. };


cet objet est à la fois stocké dans l'objet 'nodes' qui contient tous les objets 3D créés, et renvoyé au programme principal (sous forme de pointeur), pour qu'il puisse le modifier. ensuite, dans mon programme principal, j'ai juste à appeler une fonction Draw() et la librairie s'occupe d'afficher tous les objets déjà créés. Le tout simplifie pas mal mon programme principal, puisqu'il n'y a plus rien à gérer au niveau de l'affichage : il suffit de créer un objet, il sera dessiner tout seul au bon moment. Mais le tout est assez complexe, et il m'est arrivé d'avoir des gros soucis dans un programme précédent fonctionnant sur le même principe : le programme portait sur des vaisseaux spatiaux qui contiennent chacun un certain nombre d'équipement, eux même contenant d'autres équipements (exemple : le vaisseau possède une tourelle sur laquelle sont montés des cannons), le tout avec des classes dérivées dans tous les sens, et au moment de détruire un vaisseau, certains objets 3D étaient détruis, mais le programme cherchait encore à les dessiner, d'où problème... bref, ma nouvelle version du programme a l'air de mieux fonctionner pour le moment, mais je sais pas ce que ça va donner quand j'aurais plus avancé... donc si quelqu'un peut me dire si ma méthode semble bien, ou pas, et s'il y a mieux ou plus simple... merci d'avance (et merci déjà d'avoir tout lu  :p ) et désolé si j'ai pas été clair  :whistle:

mood
Publicité
Posté le 02-06-2004 à 18:08:48  profilanswer
 

n°749270
yawen
Posté le 02-06-2004 à 18:36:10  profilanswer
 

ben il faut que mon programme récupère le pointeur sur l'objet créé, pour pouvoir le modifier. bon, je met un bout de code (inventé pour l'occasion) qui aurait pu être dans mon programme principal :

Code :
  1. GL_Object *obj=NewNode((GL_Object *)NULL); //créer un objet de type GL_Object
  2. // modification de l'objet (ajout de faces, translations, rotations, etc...
  3. Draw(); //affiche l'objet qui a été créé, à partir de sa référence dans 'nodes'


 
donc ta fonction, dans laquelle tu n'as fais que retirer le renvois de l'adresse de l'objet créé, ne convient pas dans mon cas...


Message édité par yawen le 02-06-2004 à 18:37:18
n°749275
yawen
Posté le 02-06-2004 à 18:41:21  profilanswer
 

ah non, désolé, je viens de voir ce que tu voulais dire... effectivement, ça pourrais marcher, mais ce serais plutot
 

Code :
  1. template<typename T>
  2.   void NewNode( T*& node ) { 
  3.        node = new T;
  4.      nodes.add( node ); };


il faut que ce soit une référence sur un pointeur, pour que la valeur du pointeur soit réellement modifiée... mais sinon, c pas con... mais dans le fond, ça change pas grand chose... moi je demandais surtout si le principe était correct, pas forcément dans les détails...

n°749283
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 18:45:12  profilanswer
 

Exact, je suis allé un peu vite ;) Comment gères tu le retrait des objets dans ta liste nodes ?


---------------
Cordialement, Xterm-in'Hate...
n°749284
yawen
Posté le 02-06-2004 à 18:46:04  profilanswer
 

éh, c quoi ça, tu as retiré ton message ? (si c'est possible ?)

n°749290
yawen
Posté le 02-06-2004 à 18:55:09  profilanswer
 

alors je donne la classe à partir de laquelle je fais mon objet 'nodes' :

Code :
  1. template <class T> class ContainerP { //objects handled by class HandleC must be destroyed before this is destroyed (in order to ensure that no one has an invalid reference)
  2. public:
  3. template <class T1> int NewH(T1 *t);
  4. void DeleteH(int i);
  5. int Enlarge();
  6. T** node;
  7. int size;
  8. bool *h;
  9. public:
  10. void Delete(int i);
  11. int GetFreeNode();
  12. template <class T1> T1* New(T1 *t);
  13. T* operator[](int i);
  14. void Init(int n);
  15. void InitAndConstruct(int n);
  16. void CleanUp();
  17. int GetIndex(T *t);
  18. int Rsize;
  19. int nNodes;
  20. void operator=(ContainerP<T> &c) {assert(NULL);};
  21. ContainerP() {node=NULL;nNodes=0;size=0;Rsize=MAIN_DefaultRsize;h=NULL;};
  22. ContainerP(ContainerP<T> &c) {assert(NULL);};
  23. ~ContainerP() {CleanUp();};
  24. };


 
je met pas les définitions de toutes les fonctions, c'est un peu long... le principe de cette classe, c'est qu'elle stocke les objets par un tableau de pointeurs sur les objets. Le tableau est redimensionné si besoin (i.e. un nouveau tableau est créé et l'ancien est copié dedans, puis effacé). C'est pour ça que je stocke tout dedans avec des pointeurs : même si je déplace les poiteurs, l'objet lui même n'est pas déplacé. de plus ça permet de stocké des objets de types différents, mais dérivés d'une même classe de base. enfin, l'histoire du HandleC, c'est une autre classe :
 

Code :
  1. template <class T,class T1> class HandleC {
  2. ContainerP<T1> *owner;
  3. T *p;
  4. int index;
  5. public:
  6. void Delete() {if(!p) return;assert(owner);assert(index>=0);owner->DeleteH(index);p=NULL;index=-1;owner=NULL;};
  7. void New(ContainerP<T1> *_owner) {Delete();assert(_owner);owner=_owner;index=owner->NewH((T*)NULL);assert(index>=0);p=(T*)owner->node[index];assert(p);};
  8. operator T*() {return p;};
  9. T* operator->() {assert(p);return p;};
  10. HandleC() {p=NULL;index=-1;owner=NULL;};
  11. ~HandleC() {Delete();};
  12. };


 
cette classe permet de faire des trucs comme ça :
 

Code :
  1. class bidon {
  2. public:
  3. HandleC<GL_Node,GL_Object> obj;
  4. //contructeurs et destructeurs...
  5. };
  6. bidon bidon1;
  7. bidon1.obj.New(&nodes);


 
ensuite, quand l'objet bidon1 sera détruit, ça va appeler le destructeur de l'objet 'HandleC obj' qu'il contient, et donc libérer la mémoire comme il faut, et mettre à jour le tableau de 'nodes'...


Message édité par yawen le 02-06-2004 à 18:55:58
n°749303
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:03:59  profilanswer
 

Est ce que l'utilisation d'une liste (std::liste<GL_Node*> ) ne permetrait pas deja de simplifier un peu ta classe container. D'ailleurs, si elle n'a qu'une seule instance, tu pourrais en faire un singleton pour le style.


---------------
Cordialement, Xterm-in'Hate...
n°749305
yawen
Posté le 02-06-2004 à 19:04:32  profilanswer
 

pour répondre à ta question, les retraits sont fais de la manière suivante : l'objet considéré est détruit (avec delete), et le pointeur vers cet objet dans le tableau est remis à NULL. quand on ajoute un objet, le programme cherche le premier pointeur NULL dans le tableau, il créé l'objet (new) et met l'adresse dans le tableau. si tout les pointeurs sont déjà utilisés, le tableau est agrandit.

n°749306
yawen
Posté le 02-06-2004 à 19:06:29  profilanswer
 

euh elle n'a pas du tout qu'une seule instance, et le principe de cette classe c'est que quand je détruit un objet dedans, elle ne décale pas tous les autres, histoire de garder le maximum de performances. sinon, je sais pas ce que c'est un singleton... pour info, cette classe est aussi utilisée pour stocker les objets physiques du jeu (description solide de l'objet, pour gérer les collisions), et les effets graphiques (en gros, tout ce qui marche avec des effets de transparence)

n°749308
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:07:07  profilanswer
 

Lorsqu'un objet complexe crée à lui seul N objets dans ta liste, comment ca se passe lorsque ton objet complexe doit etre detruit ( comment sont retirés les N objets de la liste constituant ton objet complexe ) ? Gardes tu une trace de ces N objets dans la classe correspondant à ton objet complexe ?


---------------
Cordialement, Xterm-in'Hate...
mood
Publicité
Posté le 02-06-2004 à 19:07:07  profilanswer
 

n°749312
yawen
Posté le 02-06-2004 à 19:08:33  profilanswer
 

mais en fait, je ne sais pas comment marche std::liste<>. je connaissait std::vector<> mais ça ne corespond pas à ce que je veux, puisque quand on détruit un élément, il décale tous les autres... par exemple, s'il s'agit de la liste de tous les projectiles lancés par tous les vaisseaux, vu que ça bouge pas mal (les projectiles sont créés et détruits très vite), ça fais tout ramer...

n°749316
yawen
Posté le 02-06-2004 à 19:11:27  profilanswer
 

pfff, c galère, on se répond avec un message de retard.. hum, bref... alors pour répondre à

xterminhate a écrit :

Lorsqu'un objet complexe crée à lui seul N objets dans ta liste, comment ca se passe lorsque ton objet complexe doit etre detruit ( comment sont retirés les N objets de la liste constituant ton objet complexe ) ? Gardes tu une trace de ces N objets dans la classe correspondant à ton objet complexe ?


 
je dirais que si j'utilise la fameuse classe HandleC dans l'objet complexe, c'est le destructeur de cette classe qui se charge de demander à la classe ContainerP corespondante de détruire l'objet, et qui règle sa propre référence à NULL, histoire d'être bien sûr de pas accéder à l'objet qui vient d'être détruit. Mais ça, je ne l'ai ajouté que dans la dernière version de mon programme, justement pour règler le problème des plantages d'avant... mais je me demande quand même si y'a pas plus simple que tout ça...

n°749322
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:14:01  profilanswer
 

En somme, tu as autant de listes d'objets que d'objets complexes dans le jeu ?


---------------
Cordialement, Xterm-in'Hate...
n°749323
yawen
Posté le 02-06-2004 à 19:14:21  profilanswer
 

ah oui, et j'ai une autre question : je voudrais mettre en private certains éléments de la classe ContainerP, mais que la classe HandleC puisse quand même (et seulement cette classe) accéder aux éléments privés de la classe ContainerP. C'est possible ?

n°749326
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:14:52  profilanswer
 

Du devrais faire un petit effort pour exploiter std::liste. Cela pourra sans doute te servir pour d'autres applications.


---------------
Cordialement, Xterm-in'Hate...
n°749331
yawen
Posté le 02-06-2004 à 19:15:37  profilanswer
 

non non, je n'ai pas autant de listes d'objets que d'objets complexes dans le jeu ! tout est centralisé dans une seule liste (sinon ça n'a aucun intérêt).

n°749333
yawen
Posté le 02-06-2004 à 19:16:04  profilanswer
 

je peux trouver où de la doc sur std::liste ?

n°749336
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:16:42  profilanswer
 

Est ce que des classes héritent de HandleC ? si oui de quelle anière (public/private) ?


---------------
Cordialement, Xterm-in'Hate...
n°749339
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:17:22  profilanswer
 

http://www.sgi.com/tech/stl/List.html


---------------
Cordialement, Xterm-in'Hate...
n°749342
yawen
Posté le 02-06-2004 à 19:19:52  profilanswer
 

non, aucune classe n'hérite de HandleC. bon, je met un exemple, ce sera peut-être plus clair :

Code :
  1. class Vaisseau {
  2. public:
  3. HandleC <GL_Node,GL_Object> fuselage;
  4. HandleC <GL_Node,GL_Group> reacteurs;
  5. void Init();
  6. //contructeurs/destructeurs
  7. };
  8. void Vaisseau::Init() {
  9. fuselage.New(&nodes);
  10. reacteurs.New(&nodes);
  11. //charge un fichier et remplis les objets pointés par fuselage et reacteurs
  12. }


Message édité par yawen le 02-06-2004 à 19:20:34
n°749347
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:23:18  profilanswer
 

Declares protected: les membres dont tu veux restreindres l'accès à HandleC uniquement. (A vérifier, depuis que je code en asm et en C, je commence à oublier le C++, lol).


---------------
Cordialement, Xterm-in'Hate...
n°749352
yawen
Posté le 02-06-2004 à 19:24:42  profilanswer
 

ok, merci pour le lien,  je verrais ça si je dois faire un truc du genre dans le futur, mais là je me vois mal refaire tout mon code pour utiliser std::list

n°749355
yawen
Posté le 02-06-2004 à 19:26:37  profilanswer
 

euh ouais, mais je les déclare comment protected ? faut bien que je mettre quelque part que c'est par rapport à HandleC que je veux restreindre l'accès (enfin laisser l'accès, plutot). C'est quoi la syntaxe ? (je suis un peu perdu depuis que MSDN ne veut plus marcher sur mon pc... oui, bon, je sais, utiliser VC++ c nul, mais bon, c le premier compilateur que j'ai eu entre les mains...)

n°749358
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:27:12  profilanswer
 

Programmes dans le but d'apprendre un maximum de chose (les listes par exemple ;)). D'ailleurs, j'ai rarement vu des projes perso se terminer !


---------------
Cordialement, Xterm-in'Hate...
n°749365
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:29:43  profilanswer
 

A ma connaissance tu ne peux pas restreindre à un classe dérivée en particulier.

Code :
  1. class toto {
  2. public:
  3. // ici, tout le monde accède
  4. protected:
  5. // ici, les classes dérivées et les amies accèdent
  6. private:
  7. // ici, les amies accèdent
  8. }


---------------
Cordialement, Xterm-in'Hate...
n°749366
yawen
Posté le 02-06-2004 à 19:30:10  profilanswer
 

En fait, mon problème (qui n'en est pas forcément un), c'est que je ne sais pas si c'est une bonne idée de vouloir tout centraliser dans un même tableau, et de surcroit d'utiliser des objets de type différents dans le même tableau... est ce que par exemple je ferais pas mieux de mettre directement  
GL_Object fuselage;  
et  
GL_Group reacteurs;  
dans ma classe vaisseau ? parce que ça compliquerais la classe vaisseau (il faudrait ajouter une fonction Draw qui appellerais les fonctions Draw de GL_Object et GL_Group) mais d'un autres coté ça simplifierais pas mal la gestion de la mémoire... dilemme... et niveau performances, je sais pas ce qui est le mieux (m'est avis que ça dois pas changer grand chose)

n°749368
yawen
Posté le 02-06-2004 à 19:31:10  profilanswer
 

ben le problème c'est que HandleC n'a aucun lien avec ContainerP, enfin aucune n'est dérivée de l'autre... c'est quoi, les classes amies ?

n°749371
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:32:28  profilanswer
 

Ce que tu as fais est correct. Tous tes objets dérives d'une classe (plus ou moins) abstraite n'est ce pas ?


---------------
Cordialement, Xterm-in'Hate...
n°749374
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:33:16  profilanswer
 

Ah pardon, je croyais que HandleC dérivait de ContainerP... ca se complique un peu la ;)


---------------
Cordialement, Xterm-in'Hate...
n°749375
yawen
Posté le 02-06-2004 à 19:33:22  profilanswer
 

oui, c'est exactement ça, pour le coup de la dérivation de la classe plus ou moins abstraite


Message édité par yawen le 02-06-2004 à 19:34:05
n°749379
yawen
Posté le 02-06-2004 à 19:35:21  profilanswer
 

en fait le seul lien que HandleC a avec ContainerP, c'est le pointeur ContainerP<T1> *owner; qui permet de savoir dans quel tableau est stocké l'objet

n°749381
yawen
Posté le 02-06-2004 à 19:37:06  profilanswer
 

et je voudrais justement que par l'intermédiaire de ce pointeur, il puisse demander au tableau de supprimer l'objet (quand on détruit l'instance de HandleC), mais par le biais d'une fonction spéciale (DeleteH) qu'il est le seul à pouvoir employer

n°749387
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:42:44  profilanswer
 

Tu as essayé de faire un diagramme de l'architecture de ton programme (classes, héritages, ...etc ?).
 
Ps: J'ai du mal a reflechir quand j'ai faim, désolé :)


---------------
Cordialement, Xterm-in'Hate...
n°749388
yawen
Posté le 02-06-2004 à 19:42:47  profilanswer
 

le truc, c que dans le tableau, les objets peuvent être créés de deux moyens : par un objet HandleC, ou alors directement. et quand je détruit le tableau, je voudrais m'assurer que tous les objets créer par le biais de HandleC ont déjà été détruits (pour être sûr qu'il n'y a pas de soucis de mémoire). de plus, il ne faut pas qu'on puisse directement détruire un objet qui a été créé par le biais de HandleC, car sinon, HandleC aurait une référence sur un objet détruit... bref, mon problème est que plusieurs objets ont des pointeurs sur un même objet, et qu'il faut qu'ils soient tous synchronisés : il ne faut surtout pas que l'un d'eux pointent sur un objet détruit...

n°749392
yawen
Posté le 02-06-2004 à 19:44:34  profilanswer
 

mdr, euh ben de toute façon, moi aussi j'ai faim, et de plus ma copine (qui a finis ses partiels aujourd'hui) organise un apéro avec des potes (je viens de m'en souvenir, ou plutot elle viens de m'en souvenir en m'appelant), donc faut que j'y aille... j'ai jamais essayé de faire un diagramme, mais même si j'en fais un, j'aurais du mal à l'envoyer sur internet, nan ? bon, ben je reviens pas avant demain, alors...

n°749394
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:45:30  profilanswer
 

Pourquoi tu voudrais detruire ce tableau... ++


Message édité par xterminhate le 02-06-2004 à 19:46:03

---------------
Cordialement, Xterm-in'Hate...
n°749398
yawen
Posté le 02-06-2004 à 19:46:13  profilanswer
 

ben quand on quitte le programme... juste histoire de vérifier qu'il n'y a eu aucun soucis tout au long de l'éxécution...

n°749399
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-06-2004 à 19:46:37  profilanswer
 

et bien on revient sur l'idée du singleton...


---------------
Cordialement, Xterm-in'Hate...
n°750139
yawen
Posté le 03-06-2004 à 09:32:31  profilanswer
 

ouais, sauf que je ne sais toujours pas ce que c'est qu'un singleton...

n°750167
Joel F
Real men use unique_ptr
Posté le 03-06-2004 à 09:51:57  profilanswer
 

un singleton est un objet à instance unique.
Son principe repose sur le controle du nbre d'instance de la classe
en rendant private les constructeurs de la classe.
Un exemple simple :
 

Code :
  1. class Singleton
  2. {
  3.   public :
  4.    static Singleton*  GetInstance()
  5.    {
  6.        if( !Instance ) Instance = new Singleton;
  7.        return Instance;
  8.    }
  9.    static Singleton*  ReleaseInstance()
  10.    {
  11.        if( Instance ) delete Instance;
  12.    }
  13.    // D'autres méthodes non statiques
  14.    void f();
  15.    void g();
  16.    private :
  17.   Singleton() {}
  18.   Singleton( const Singleton& ) {}
  19.   ~Singleton() {}
  20.   static Singleton* Instance
  21. };
  22. Singleton* Singleton::Instance = NULL;


 
 
L'accés se fait ensuite via :
 

Code :
  1. #include "singleton.h"
  2. void toto()
  3. {
  4.      Singleton* sg = Singleton::getInstance();
  5.      sg->g();
  6. }
  7. int main( int,char**)
  8. {
  9.      Singleton* sg = Singleton::getInstance();
  10.      sg->f();
  11.     toto();
  12.  
  13.     return 0;
  14. )


Message édité par Joel F le 03-06-2004 à 10:29:45
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Des conseils sur mon programme, SVP

 

Sujets relatifs
crontab : programme javaAfficher un programme C++ Win32 sur le bureau, comment faire ?
Comment optimiser proprement et inteligement un programme NPetite vérif sur mon script de session, svp ?
Programme pour faire du C++ (code + design)Besoin d informations sur les DLL SVP
execution de programmeprogramme qui donne les nombres parfaits
Peut on lancer une commande shell unix apartir d'un programme Adaprogramme C# erreur :Unable to connect to any hosts....
Plus de sujets relatifs à : Des conseils sur mon programme, SVP


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR