IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MVC Discussion :

[MVC] Ca doit marcher autrement non?


Sujet :

MVC

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Points : 170
    Points
    170
    Par défaut [MVC] Ca doit marcher autrement non?
    Bonjour à tous,

    Afin d'appliquer un peu les design patterns, je viens de réaliser un casse brique basique (pas d'intro, d'ennemis, d'effets, etc...).

    Comme structure de base, je suis parti d'un MVC. Avec du recul, j'ai la nette impression que toutes les données du modèle(Model) sont dupliquées dans la vue.

    J'ai fait le diagramme de classes pour clarifier un peu mes propos (aprés l'avoir codé, je sais c'est dans l'autre sens normalement ) :

    Il manque pas mal de relations, notamment des liens sujet/observateur un peu partout, mais c'était juste histoire de donner l'archi générale.
    ... Qui doit être assez catastrophique d'ailleurs .

    Je pense que je m'y suis mal pris, et je pense que mon controleur devrait surement être un peu plus impliqué, mais je vois pas comment (la il gère les actions de la souris, les transistions entre les états début/en cours/pause/fin et les initialisation/sortie du jeu).

    Un des intérêts de MVC étant de pouvoir changer de vue "comme de chemise", je m'étais mis en tête de pouvoir faire une vue 2D puis une vue 3D sans changer le modèle.
    Mais je ne vois pas comment faire ça sans faire cette duplication modele/vue

    Donc les questions (finalement ):
    Est ce que MVC est destiné à "dupliquer" tous ces objets?
    Est ce que ma représentation de MVC est fausse (plus que probable) et dans ce cas comment la rectifier?
    Est ce que MVC n'est pas indiqué pour cette appli (ça serait étonnant mais pourquoi pas) ou peut être y a t-il un modèle plus approprié?

    Merci d'avance!

    PS: Je précise au cas où que c'est pour du C++

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 44
    Points : 52
    Points
    52
    Par défaut
    salut,

    je vais essayer de t'éclairer un peu bien que je ne sois pas un expert du design pattern MVC

    Est ce que MVC est destiné à "dupliquer" tous ces objets?
    Non du tout, il sert simplement à changer "de vue comme de chemise" comme tu l'as dit

    Est ce que ma représentation de MVC est fausse (plus que probable) et dans ce cas comment la rectifier?
    En tout cas il y a un gros problème dans ton diagramme, le mvc a pour but de séparer complètement le modèle de la vue. Or Tu as une laison directe entre tes classes Model et View ce qui n'est pas normal.

    Est ce que MVC n'est pas indiqué pour cette appli (ça serait étonnant mais pourquoi pas) ou peut être y a t-il un modèle plus approprié?
    A mon avis un des seuls cas où le mvc est inapplicable c'est quand il n'y a pas d'ihm tout simplement.

    D'aprés ton diagramme, je pense que tu n'as pas bien compris le but du controlleur. Il est juste sensé "piloter" ton modèle c'est à dire que tes classes vues passe par lui pour obtenir les services du modèle. Par exemple le contrôle de la souris n'a rien à faire au niveau du controlleur, il doit être dans la vue.
    De plus le controlleur ne se limite pas forcément à une seule classe, tu devrais avoir une classe controlleur par couple acteur-cas identifié d'aprés tes diagrammes de cas d'utilisation.


    Voilà j'espère que tu y vois un peu plus clair
    ben

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 55
    Points : 60
    Points
    60
    Par défaut
    Citation Envoyé par benohite
    salut,

    je vais essayer de t'éclairer un peu bien que je ne sois pas un expert du design pattern MVC


    Non du tout, il sert simplement à changer "de vue comme de chemise" comme tu l'as dit


    En tout cas il y a un gros problème dans ton diagramme, le mvc a pour but de séparer complètement le modèle de la vue. Or Tu as une laison directe entre tes classes Model et View ce qui n'est pas normal.


    A mon avis un des seuls cas où le mvc est inapplicable c'est quand il n'y a pas d'ihm tout simplement.

    D'aprés ton diagramme, je pense que tu n'as pas bien compris le but du controlleur. Il est juste sensé "piloter" ton modèle c'est à dire que tes classes vues passe par lui pour obtenir les services du modèle. Par exemple le contrôle de la souris n'a rien à faire au niveau du controlleur, il doit être dans la vue.
    De plus le controlleur ne se limite pas forcément à une seule classe, tu devrais avoir une classe controlleur par couple acteur-cas identifié d'aprés tes diagrammes de cas d'utilisation.


    Voilà j'espère que tu y vois un peu plus clair
    ben
    Bonjour,

    j'aurais deux remarques à faire:

    1) D'une part, il est vrai que le paradigme MVC à pour but de rendre les objets de la vue et du modèle mutuellement indépendants. Cependant en pratique, je pense qu'on gagne à ne pas casser la dépendance de la vue vers le modèle dans certains cas particuliers. Typiquement, le développement d'une interface de client riche peut à mon avis violer cette règle si les 3 couches MVC sont déployées sur la même machine et ne sont pas destinées à être distribué dans le futur. En effet, pour qu'une vue ne dépende plus de son modèle il faut passer par certains design pattern (ex. DTO) dont la mise en place peut s'avérer couteuse en terme de développement, bien que je la préconise fortement dans le cadre d' applications distribuées (le risque des DTO est de transformer votre application en jeu de piste). Dans le cas, d'une application déployée à 100% sur une machine cliente, dans la mesure où les objets du modèle sont passés à la vue par référence et non par valeur, on ne perd quasi rien en performance, et on gagne fortement en temps de développement, donc je pense qu'il n'y a pas de politique réellement efficace pour cette gestion de la dépendance entre les vues et leur modèle.

    2) d'autre part, concernant le rôle du contrôleur, encore une fois je pense que les deux approches sont pratiquées et justes. Dans une approche orienté composant, on définit un seul et même objet qui est responsable de la vue et de la capture des évènements utilisateurs (objet "boundaries" de Jacobson) et personnellement je suis entierement favorable à cette approche (c'est d'ailleurs l'approche que j'utilise dans nos projets via l'utilisation de système RAD avec le framework des JSF). ensuite il y l'approche classique du MVC, où il me semble que en plus de la gestion du flux de l'application, un contrôleur a aussi la responsabilité de capturer les évènements utilisateurs, donc le schéma présenté ne me semble pas erroné sur ce plan.

    bon courage à vous,
    à bientot.

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Points : 170
    Points
    170
    Par défaut
    Bonjour,

    D'abord merci beaucoup d'avoir décortiqué mon diagramme et pris le temps de m'apporter ces précisions!

    Je m'aperçois que j'étais quand même très à l'ouest

    En fait dans mon livre sur les design patterns (qui ne décrit malheureusement MVC que dans les grandes lignes), il est indiqué que la relation vue - controleur est un pattern strategie.
    Dans mon esprit je pensais qu'une vue était une statégie d'affichage pour un controleur. Si j'ai bien compris vos messages, ce serait plutot le controleur qui implémenterait plusieurs stratégies (des sous classes en l'occurence) de réponse pour la vue?



    En revanche je suis un peu perdu sur deux points:

    1)Par qui sont gérées les modifications du modele?
    • Est ce que le modèle définit lui même toutes les règles de modification, auquel cas le controleur ne serait qu'un traducteur des requètes pour la vue
    • Est ce que le controleur gère la logique de fonctionnement de l'application, ne laissant au modèle "que" le role de base de données "statique"


    2)Dans le cas où les évenements utilisateurs sont gérées par la vue (qui semble être le meilleur choix), où se situe la liaison avec la boucle principale du programme?
    Typiquement pour un casse brique, lorsque l'utilisateur est inactif, la balle bouge quand même, il faut bien que l'un des blocs modele/vue/controleur indique cette incrémentation temporelle quelque part?
    • Est ce que c'est considéré comme une action utilisateur (auquel cas gérée par la vue)?
    • Est ce qu'il faut gérer ça par le controleur ou le modèle?
    • Est ce que ces modifs sont toutes gérées par la boucle principale qui indique à chacun cette incrémentation?
    • Est ce que je suis en Alaska avec mes propositions (c-a-d encore plus à l'ouest qu'avant )?



    Bon ces questions se situent peut être un peu trop au niveau programmation et pas assez au niveau conception pour cette catégorie du forum, mais j'avoue que j'ai un peu de mal à bien comprendre la logique de MVC à un niveau plus abstrait

    Merci encore pour vos réponses.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 44
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par tristan_m
    1)Par qui sont gérées les modifications du modele?
    • Est ce que le modèle définit lui même toutes les règles de modification, auquel cas le controleur ne serait qu'un traducteur des requètes pour la vue
    • Est ce que le controleur gère la logique de fonctionnement de l'application, ne laissant au modèle "que" le role de base de données "statique"
    Le modèle définit effectivement lui-même les règles de modification, il n'empeche que tu peux les paramètrées. Ex: la vitesse de balle, saisie via la vue et transmise au modèle grace au controleur
    Je ne suis pas sur d'avoir bien saisi le 2e point, mais pour moi le controleur ne gère pas la logique de fonctionnement, c'est le modèle qui offre les "services" et donc qui en assure le déroulement. Aprés si tu veux dire qu'il faut cliquer sur le bouton démarrer avant de pouvoir jouer par ex, la je dirais plutôt que c'est la vue. Le controleur ne servant que de passerelle entre vue et modèle.


    Citation Envoyé par tristan_m
    2)Dans le cas où les évenements utilisateurs sont gérées par la vue (qui semble être le meilleur choix), où se situe la liaison avec la boucle principale du programme?
    Typiquement pour un casse brique, lorsque l'utilisateur est inactif, la balle bouge quand même, il faut bien que l'un des blocs modele/vue/controleur indique cette incrémentation temporelle quelque part?
    • Est ce que c'est considéré comme une action utilisateur (auquel cas gérée par la vue)?
    • Est ce qu'il faut gérer ça par le controleur ou le modèle?
    • Est ce que ces modifs sont toutes gérées par la boucle principale qui indique à chacun cette incrémentation?
    • Est ce que je suis en Alaska avec mes propositions (c-a-d encore plus à l'ouest qu'avant )?
    L'incrémentation comme tu le dis se trouve au niveau du modèle puisque c'est lui qui implémente le comportement de l'application. La vue peut demander (via le controleur) par exemple un démarrage ou un arrêt.
    Selon moi l'incrémentation n'est pas considérée comme une action utilisateur, elle fait partie intégrante du modèle.
    Pour implémenter cette incrémentation, le plus simple est d'utiliser un timer qui se reveillera à un intervalle de temps donné et tu n'auras plus qu'a redessiner le plateau de jeu. En principe ce timer est executé dans un thread distinct.

    Je dirais pas que tu es aussi loin que l'Alaska, plutôt l'Angleterre (humour)....

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 55
    Points : 60
    Points
    60
    Par défaut
    Citation Envoyé par tristan_m

    En revanche je suis un peu perdu sur deux points:

    1)Par qui sont gérées les modifications du modele?
    • Est ce que le modèle définit lui même toutes les règles de modification, auquel cas le controleur ne serait qu'un traducteur des requètes pour la vue
    • Est ce que le controleur gère la logique de fonctionnement de l'application, ne laissant au modèle "que" le role de base de données "statique"
    Salut,

    la logique de ton application doit être compris dans ton modèle. Par contre, le flux de l'application, cad les comportements de ton application suivant les actions de l'utilisateur sont gérés par le contrôleur, qui délèguera au bon service du modèle. Dans une modélisation objet, quand tu attribues les responsabilités à tes objets suivant GRASP, tu constates que le seul moyen de conserver un faible couplage et une haute cohésion dans un graphe objet, c'est dans ton cas, d'attribuer les comportement métier aux objets métier eux-même (cad les objets du modèle).

    Citation Envoyé par tristan_m
    2)Dans le cas où les évenements utilisateurs sont gérées par la vue (qui semble être le meilleur choix), où se situe la liaison avec la boucle principale du programme?
    Typiquement pour un casse brique, lorsque l'utilisateur est inactif, la balle bouge quand même, il faut bien que l'un des blocs modele/vue/controleur indique cette incrémentation temporelle quelque part?
    • Est ce que c'est considéré comme une action utilisateur (auquel cas gérée par la vue)?
    • Est ce qu'il faut gérer ça par le controleur ou le modèle?
    • Est ce que ces modifs sont toutes gérées par la boucle principale qui indique à chacun cette incrémentation?
    • Est ce que je suis en Alaska avec mes propositions (c-a-d encore plus à l'ouest qu'avant )?


    Bon ces questions se situent peut être un peu trop au niveau programmation et pas assez au niveau conception pour cette catégorie du forum, mais j'avoue que j'ai un peu de mal à bien comprendre la logique de MVC à un niveau plus abstrait

    Merci encore pour vos réponses.
    Je suis du même avis que benohite: dans ce cas, c'est ton modèle qui doit gérer l'incrémentation par exemple par la mise en place d'un timer. Dans ce cas et typiquement il est judicieux d'implémenter le design pattern "observer/Observable", c'est un design pattern qui permet au modèle de notifier à toutes ses vues qu'il à changé (suite à un évènement qui ne parvient pas forcément du contrôleur , comme des évènement asynchrones par ex.) afin qu'elles se rafraichissent, sans pour autant que le modèle n'ai de dépendance envers ses vues (c'est magique!), c'est un pattern très puissant ou le polymorphisme objet prend tout son sens!

    Sinon, Alaska ou pas, je trouve que tu poses les bonnes questions, les questions qu'on se pose quand on cherche à faire au mieux avec ce qu'on a, c'est à dire un (ou des) bouquins d'UML / UP d'un coté et un ordi avec une console de l'autre, bref la jonction entre la théorie et la pratique n'est pas évidente mais on y gagne beaucoup à la travailler.

    bon courage.

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Points : 170
    Points
    170
    Par défaut
    Bonjour,

    Encore une fois merci énormément d'aider le petit scarabée que je suis!

    Je me suis un peu renseigné sur GRASP (je ne connaissais pas), et ça m'a permis de bien conforter ma compréhension des concepts que vous m'avez expliqué.
    Notamment le pattern controller évidemment.
    Au passage, au cours de mes recherches je suis tombé sur cette page :
    http://fr.wikipedia.org/wiki/Anti-patron
    qui décrit les anti pattern (fautes de conception dans un design pattern) et qui me semble assez intéressante pour ceux qui comme moi ont un petit manque d'expérience dans ce domaine (on va appeler ça comme ça )


    Par contre je vais encore faire mon boulet sur des questions qui ne concernent plus trop MVC, ou au plus de façon indirecte...

    Au sujet du timer, ça m'embête un peu qu'il soit dans le modèle, même si je comprends -maintenant- -Merci à vous- tout à fait le principe.
    Ce qui me pose problème c'est que dans la plupart des jeux temps réel (c'est un peu pompeux pour un casse brique mais bon ), c'est l'affichage le goulot d'étranglement.
    Donc le timer c'est plus la carte graphique, a fortiori gérée par la vue, qui indique une fois l'affichage terminé que les données peuvent/doivent être mises à jour.
    C'est pourquoi le principe d'action utilisateur me plaisait bien, mais cette désignation cache peut être une dépendance du modèle vis-à-vis de la vue...

    A l'heure actuelle, mon programme étant à thread unique et non distribué, il suffirait que je fasse ainsi (désolé j'ai encore un peu de mal avec les diagrammes de séquence...):

    1 - Traitement des interactions (clavier, souris, messages de l'OS, etc...)
    2 - Mise à jour des données par le modèle.
    3 - Notification vers la vue.
    4 - Acquisition des nouvelles données par la vue,
    4 bis - Réaffichage du plateau de jeu.
    5 - Retour en 1.

    Dit comme ça, la vue n'aurait même rien à envoyer au controleur (à ce niveau là), donc apparemment pas de dépendance, mais j'ai l'impression que cela ne marche que grace au cas particulier thread unique/non distribué.
    • Est ce qu'il s'agirait d'une erreur de conception?
    • Est ce que les cas multithread et/ou distribué répondent à d'autres modèles de conception?


    Pfiou j'ai fait long, j'espère que c'est clair au moins (c'est pas gagné)?



    Autre question à propos du pattern observer.
    Mon modèle possède beaucoup d'objets, mais dans 99% des cas, seule la balle est vraiment modifiée. Dans ma précédente implémentation, j'avais des relations sujet -> observateur entre toutes les entités quasiment (non représentées sur le diagramme) :
    ball -> graphicBall
    paddle -> graphicPaddle
    etc...
    • Est ce que c'est la bonne façon de faire (évitant les requêtes/mises à jour inutiles)?
    • Est ce qu'il vaut mieux faire une seule notification via le modèle et de faire passer toutes les requêtes d'acquisition des nouvelles données via la vue (simplifiant l'architecture)?
    • Est ce qu'il y a une toute autre façon de faire?



    Désolé pour toutes ces questions (mes messages sont de plus en plus longs...) j'essaie de les présenter clairement à défaut de faire concis...

    En tout cas mille mercis pour votre aide et vos encouragements!!!
    D'ailleurs je pensais être beaucoup plus loin que l'Angleterre, genre perdu en plein milieu de l'Atlantique

    Merci encore

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 44
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par tristan_m
    • Est ce qu'il s'agirait d'une erreur de conception?
    • Est ce que les cas multithread et/ou distribué répondent à d'autres modèles de conception?
    Bien sur tu peux aussi mettre le timer dans la vue, il s'agit là d'un choix de conception, sachant que le fonctionnement de l'application sera trés différent suivant le cas. Il apparait que le fait de mettre le timer dans la vue faciliterait le codage mais il faut pousser les choses plus en profondeur pour réellement s'en assurer. C'est tout l'intérêt de la phase de conception

    Pour ton déroulement, j'apporterai juste 1 ou 2 précisions:

    - récupération des interractions: mouvement de souris, clic timer (au niveau de la vue)
    - transmission au modèle (via controleur)
    - calcul et mise a jour du plateau de jeu (au niveau du modèle)
    - transmission à la vue (via controleur)
    - affichage du nouveau plateau (au niveau de la vue)

    On voit facilement un "problème" apparaître, quand le joueur va jouer, on va avoir quasi simultanément un évènement souris et un évènement timer (suivant le réglage du timer). Donc le modèle risque de travailler 1x pour rien, l'idéal je pense pour ce soucis de surcharge serait de se limiter au timer avec un temps de reaction assez bas (pour un humain du moins) et de passer les corrdonnées souris à chaque clic, que le modèle puisse faire ses calculs correctement.

    Citation Envoyé par tristan_m
    Autre question à propos du pattern observer.
    Mon modèle possède beaucoup d'objets, mais dans 99% des cas, seule la balle est vraiment modifiée. Dans ma précédente implémentation, j'avais des relations sujet -> observateur entre toutes les entités quasiment (non représentées sur le diagramme) :
    ball -> graphicBall
    paddle -> graphicPaddle
    etc...
    • Est ce que c'est la bonne façon de faire (évitant les requêtes/mises à jour inutiles)?
    • Est ce qu'il vaut mieux faire une seule notification via le modèle et de faire passer toutes les requêtes d'acquisition des nouvelles données via la vue (simplifiant l'architecture)?
    • Est ce qu'il y a une toute autre façon de faire?
    Ce qui me gène un peu avec le pattern observer, c'est que par définition, il court-circuite ton pattern MVC en se passant du controleur. De plus je ne pense pas que tu en ai besoin puisque que c'est ton modèle qui fait tous les calculs et renvoi une image buffurisée qui sera simplement affichée par ta vue. Enfin c'est ce qui me parait le plus simple/efficace.

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Points : 170
    Points
    170
    Par défaut
    Bonjour,

    Merci d'avoir pris le temps de lire mon long message!

    Citation Envoyé par benohite
    Bien sur tu peux aussi mettre le timer dans la vue, il s'agit là d'un choix de conception, sachant que le fonctionnement de l'application sera trés différent suivant le cas. Il apparait que le fait de mettre le timer dans la vue faciliterait le codage mais il faut pousser les choses plus en profondeur pour réellement s'en assurer. C'est tout l'intérêt de la phase de conception
    Cool je pensais être carrément HS avec mes questions, j'avais peur qu'il ne s'agisse de problèmes d'implémentation plutôt que de conception

    Citation Envoyé par benohite
    Pour ton déroulement, j'apporterai juste 1 ou 2 précisions:

    - récupération des interractions: mouvement de souris, clic timer (au niveau de la vue)
    - transmission au modèle (via controleur)
    - calcul et mise a jour du plateau de jeu (au niveau du modèle)
    - transmission à la vue (via controleur)
    - affichage du nouveau plateau (au niveau de la vue)

    On voit facilement un "problème" apparaître, quand le joueur va jouer, on va avoir quasi simultanément un évènement souris et un évènement timer (suivant le réglage du timer). Donc le modèle risque de travailler 1x pour rien, l'idéal je pense pour ce soucis de surcharge serait de se limiter au timer avec un temps de reaction assez bas (pour un humain du moins) et de passer les corrdonnées souris à chaque clic, que le modèle puisse faire ses calculs correctement.
    En fait, le système actuel (qui marche mais dont je me rend compte maintenant que l'architecture est ...) fonctionne "sans" timer. Le moment de l'affichage EST l'indicateur de temps. Le modèle met à jour ses données en mesurant l'intervalle de temps depuis sa précédente mise à jour.
    Donc si ça ne pose pas trop de problème que ce soit la vue qui fasse la requete de mise à jour du modèle (sans timer, donc à intervalle de temps potentiellement irrégulier en l'occurence), le problème est réglé.
    A moins qu'il n'y ait un horrible problème que je n'ai pas soulevé?

    Citation Envoyé par benohite
    Ce qui me gène un peu avec le pattern observer, c'est que par définition, il court-circuite ton pattern MVC en se passant du controleur. De plus je ne pense pas que tu en ai besoin puisque que c'est ton modèle qui fait tous les calculs et renvoi une image buffurisée qui sera simplement affichée par ta vue. Enfin c'est ce qui me parait le plus simple/efficace.
    Effectivement, je n'avais pas fais attention au problème de court-circuitage du controleur.
    Mais après quelques recherches et quelques réflexions, il me semble que le pattern Observer a sa place dans MVC.
    Dans mon livre (traduction de 'design patterns' du Gang-of-Four), ils indiquent que la relation modele -> vue est une relation sujet -> observateur (resp.), qui permet de notifier un changement du modèle aux vues tout en gardant un découplage entre ces deux entités (comme l'a indiqué TonioLeRital).
    Aprés comme l'a également dit TonioLeRital, il s'agit de la théorie, et la jonction avec la pratique n'est pas simple (pour moi en tout cas ). Mais personellement, si je comprend pourquoi la vue doit passer par le controleur pour indiquer les évenements au modèle, je ne comprends pas bien pourquoi le modèle devrait passer par le controleur pour envoyer l'état de ses données?
    N'est ce pas la vue qui définit les données qu'elle affiche et la façon dont elle le fait?
    En somme, moi je pensais que le modèle avait des restrictions d'accés en écriture (gérées par le controleur), mais que l'accés en lecture était libre (L'envoie des données étant à l'initiative du modèle et non résultant d'une requete directe de la vue).


    Sinon par "renvoi [d']une image bufferisée" tu veux dire que le modèle doit envoyer toutes les données (mises à jour ou non) en un seul envoi?
    A moins que tu parles d'une image au sens propre du terme (auquel cas je ne comprendrais pas du tout comment le modèle pourrait construire une telle image )?


    Merci encore de m'aider dans cette quête!

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 44
    Points : 52
    Points
    52
    Par défaut
    Salut,

    Désolé de répondre si tard mais je n'ai pas eu beaucoup de temps libre cette dernière semaine.

    Citation Envoyé par tristan_m
    En fait, le système actuel (qui marche mais dont je me rend compte maintenant que l'architecture est ...) fonctionne "sans" timer. Le moment de l'affichage EST l'indicateur de temps. Le modèle met à jour ses données en mesurant l'intervalle de temps depuis sa précédente mise à jour.
    Donc si ça ne pose pas trop de problème que ce soit la vue qui fasse la requete de mise à jour du modèle (sans timer, donc à intervalle de temps potentiellement irrégulier en l'occurence), le problème est réglé.
    A moins qu'il n'y ait un horrible problème que je n'ai pas soulevé?
    Si j'ai bien saisi, tu te sers de l'évènement souris pour redessiner ton plateau ? Le seul petit problème que je vois serait le cas où le joueur arrête brièvement de bouger la souris, tu aurais alors un phénomène de lag dans ton jeu.


    Citation Envoyé par tristan_m
    Mais personellement, si je comprend pourquoi la vue doit passer par le controleur pour indiquer les évenements au modèle, je ne comprends pas bien pourquoi le modèle devrait passer par le controleur pour envoyer l'état de ses données?
    N'est ce pas la vue qui définit les données qu'elle affiche et la façon dont elle le fait?
    En somme, moi je pensais que le modèle avait des restrictions d'accés en écriture (gérées par le controleur), mais que l'accés en lecture était libre (L'envoie des données étant à l'initiative du modèle et non résultant d'une requete directe de la vue).
    Ton modèle ne doit faire que ce qu'on lui demande, il est donc normal qu'il ne renvoi ses résultats que lors de requêtes venant du contrôleur. Bien sur il peut avoir des réponses asynchrones (ie qui ne sont pas le retour direct d'un fonction). C'est je pense le seul cas où le modèle appelle "de lui même" le contrôleur. Encore qu'il soit possible de se passer d'un contrôleur dans ce cas grâce au pattern Observer comme tu l'as indiqué (ce qui est sans doute préférable).

    Citation Envoyé par tristan_m
    Sinon par "renvoi [d']une image bufferisée" tu veux dire que le modèle doit envoyer toutes les données (mises à jour ou non) en un seul envoi?
    A moins que tu parles d'une image au sens propre du terme (auquel cas je ne comprendrais pas du tout comment le modèle pourrait construire une telle image )?
    Un image buffurisée est une représentation mémoire de ce qui sera affiché à l'écran. Ce principe permet d'accélérer l'affichage, en préparant le contenu en mémoire puis en l'affichant d'un seul coup. Pour être plus clair, voici comment je vois les choses. Ton modèle dessine l'intégralité du plateau (à un instant donné) dans une image buffurisée et la transmet à la vue qui l'affiche d'un seul bloc.

  11. #11
    Membre confirmé Avatar de ypicot
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    412
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 412
    Points : 579
    Points
    579
    Par défaut
    Citation Envoyé par tristan_m
    Mais personellement, si je comprend pourquoi la vue doit passer par le controleur pour indiquer les évenements au modèle, je ne comprends pas bien pourquoi le modèle devrait passer par le controleur pour envoyer l'état de ses données?
    Il peut tout à fait y avoir un lien entre la vue et le modèle sans passer par le contrôleur. Dans ton cas, le modèle peut très bien signaler à la vue que son état a été modifié, et que la vue peut se mettre à jour.
    On pert un chouilla en découplage, mais on peut raisonnablement penser que les msg echangés entre ces deux entités (vue et modèle) seront les mêmes, qu'on soit en 2D ou en 3D.

    En fait, le contrôleur sert plutot à contrôler (gag) les modifs demandées par l'utilisateur via la vue, et donc les changement d'état.

    Par ailleurs, je ne vois pas pourquoi le timer devrait impérativement être dans la vue. C'est même plutôt le contraire.
    Dans ton cas, j'imagine le scénario suivant :
    - l'image précédente est affichée
    - est-ce qu'on a eu un ou plusiuers évènements timer dans le modèle ?
    - non : on attend l'évènement timer en question
    - oui : on calcule l'image en tenant compte qu'il faut un déplacement plus grand de la balle (il faut une vitesse de jeu constante, quelle que soit la vitesse de la machine), et éventuellement redemander au contrôleur la position actualisée de la raquette du joueur

    D'une manière générale, la vitesse d'affichage est un paramètre qui doit rester le plus neutre possible, surtout dans la partie "logique" les jeux.

    Yvan
    Une solution n'est valable que dans un contexte donné

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Points : 170
    Points
    170
    Par défaut
    Bonjour,

    Benohite, nul besoin d'être désolé, chacun son emploi du temps, je suis déjà content que tu m'apportes ton aide!

    Concernant ce fameux timer, je crois que j'ai du trés mal m'expliquer.

    En fait ma façon de voir est -grossièrement- comme ceci :

    (mesure_temps() donne "l'heure")

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Model->tempsActuel = mesure_temps();
    while(1) {
    
    S'il y a des évènements (souris, clavier, etc...) {
    Réception des évenements Envoi des requetes au modèle via le controleur
    } nouveauTempsActuel = mesure_temps() tempsEcoulé = nouveauTempsActuel - Model->tempsActuel Mise à jour du modele (en fonction des requetes et de tempsEcoulé) Model->tempsActuel = nouveauTempsActuel Notification de mise à jour par le modèle à la vue Réception des nouvelles données du modèle par la vue Affichage par la vue
    }

    Donc il n'y a pas vraiment de timer. L'affichage ne dépend pas d'un évènement. On affiche une nouvelle image dés qu'on peut.
    La vitesse du jeu est la même quelle que soit la puissance de la machine puisque chaque élément du jeu est modifié en fonction du temps écoulé (ils ont chacun une vitesse en unité de distance/seconde).

    Aprés pour limiter le nombre d'image par seconde (j'arrivais à plus de 1200 images/sec, c'était un peu inutile), c'est la carte graphique qui s'en occupe (enfin avec DirectX il y a une variable à modifier pour activer la synchronisation avec l'écran, donc 60 images/sec dans mon cas).
    Donc s'il y a un timer c'est celui-ci.


    Moi ce qui me posait problème c'était l'emplacement de cette boucle.
    Dans la vue? Dans le modèle? Dans le contrôleur? Ailleurs???



    Aprés j'ai quelques interrogations concernant à vos remarques :
    1)
    Citation Envoyé par ypicot
    redemander au contrôleur la position actualisée de la raquette du joueur
    Sur une page de SUN à propos de MVC sur laquelle je suis tombé récemment , on voit ce schéma :

    (C'est certes sur du J2EE, mais je pense que c'est indépendant du langage?)
    La relation vue<->modèle est clairement un pattern observateur, par contre il n'y a pas de relation modèle -> controleur. Est ce que ce n'est qu'un schéma théorique?

    2)
    Citation Envoyé par benohite
    Ton modèle dessine l'intégralité du plateau (à un instant donné) dans une image buffurisée et la transmet à la vue qui l'affiche d'un seul bloc.
    Là je ne comprends vraiment pas comment le modèle est en mesure de dessiner. Est ce que tu parles du système de backbuffer (effectuer le dessin de la nouvelle image dans un buffer et non pas directement à l'écran, puis switcher)? Si c'est ça, seule la vue peut en être capable non (Le modèle n'est pas censé savoir où et comment va être affiché tel ou tel élément il me semble)?

    3)
    Citation Envoyé par ypicot
    Par ailleurs, je ne vois pas pourquoi le timer devrait impérativement être dans la vue. C'est même plutôt le contraire.
    [...]
    D'une manière générale, la vitesse d'affichage est un paramètre qui doit rester le plus neutre possible, surtout dans la partie "logique" les jeux.
    Au départ ces deux phrases me semblaient contradictoires, étant donné que selon ma vision des choses (que j'explique plus haut), le timer indique l'instant d'affichage, et non pas l'instant de mise à jour du modèle.
    Les deux points de vue sont valables non?



    En tout cas merci encore de vous être penchés sur le problème!
    J'espère que j'ai su clarifier un peu mes idées...

  13. #13
    Membre confirmé Avatar de ypicot
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    412
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 412
    Points : 579
    Points
    579
    Par défaut
    Citation Envoyé par tristan_m
    Sur une page de SUN à propos de MVC sur laquelle je suis tombé récemment , on voit ce schéma :

    (C'est certes sur du J2EE, mais je pense que c'est indépendant du langage?)
    La relation vue<->modèle est clairement un pattern observateur, par contre il n'y a pas de relation modèle -> controleur. Est ce que ce n'est qu'un schéma théorique?
    Non, c'est le bon shéma, c'est moi qui me suis (très) mal exprimé.

    Citation Envoyé par tristan_m
    Au départ ces deux phrases me semblaient contradictoires, étant donné que selon ma vision des choses (que j'explique plus haut), le timer indique l'instant d'affichage, et non pas l'instant de mise à jour du modèle.
    Les deux points de vue sont valables non?
    Je te suggère de réfléchir à ce pb de vitesse constante dans le cas d'une machine très lente ou d'un jeu ayant de grandes variations dans la vitesse d'affichage (images 3D dont la complexité est variable). Que se passe-t-il si tu "sautes" ta synchro écran ?

    Yvan
    Une solution n'est valable que dans un contexte donné

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 44
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par tristan_m
    Bonjour,

    Là je ne comprends vraiment pas comment le modèle est en mesure de dessiner. Est ce que tu parles du système de backbuffer (effectuer le dessin de la nouvelle image dans un buffer et non pas directement à l'écran, puis switcher)? Si c'est ça, seule la vue peut en être capable non (Le modèle n'est pas censé savoir où et comment va être affiché tel ou tel élément il me semble)?
    En effet je parlais d'un système de backbuffer, même si je le connaissais pas sous ce nom. Je me suis basé sur le système java qui te permet de transmettre à tes objets un contexte graphique et donc de dessiner dedans. Aprés reflexion, il y a en effet un problème si ce système est intégré au modèle, on "viole" purement le mvc, vue que le dessin reste figé au contexte utilisé par le modèle (ex on ne peux passer en 3d simplement sans toucher au modèle). Il faut donc comme tu le dis limiter le modèle au simple calcul des "coordonnées".

    En ce qui concerne le timer, je comprends mieux maintenant l'idée, c'est plutôt astucieux. Je pense même que tu peux descendre à 25 images par secondes, l'oeil humain n'étant pas capable à partir de cette fréquence de voir l'enchainnement d'image.
    Cependant j'ai une petite question. Tu dis que directx permet de régler la synchronisation carte graphique/écran. Cela veut-il dire qu'il limite les rafraichissements à la fréquence donnée ?
    Auquel cas, ton modèle risque de faire beacoup de calculs pour rien car le résultat ne sera pas afficher. Je m'explique, bloquer le rafraichissement, selon moi ne veut pas dire bloquer le calcul, mais juste afficher le résultat à une cadence fixe et donc ne prendre les valeurs qu'à certains moments, faisan l'impasse sur d'autres.

    Dans ce sens, tu devrais plutôt te baser sur ta variable temps_écoulé pour bloquer les calculs en la modulant d'une période de 40ms par ex (25 images / sec). L'affichage importe alors peu puisqu'il n'y a pas de calcul.

    Pour ce qui est du schéma du MVC, il m'apparait normal de ne pas avoir de relation modèle -> controleur, ton modèle est sensé être indépendant de la vue et donc "autonome" dans son fonctionnement. Le seul cas ou l'on peut avoir une communication modèle -> controleur, est le cas d'un résultat envoyé par le modèle, mais ce résultat est un retour de fonction suite à une demande du controleur, il ne s'agit donc pas vraiment d'une communication modèle -> controleur

    Enfin pour la boucle, le choix apparait délicat, la casser (calculs temps dans le modèle, evènements dans la vue), l'implémenter totalement dans le modèle, ou dans le vue. Je ne vois pas trop quelle serait la meilleure solution, il faut y réfléchir d'avantage

  15. #15
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Points : 170
    Points
    170
    Par défaut
    Bonjour,

    Merci de vos réponses!

    Citation Envoyé par ypicot
    Je te suggère de réfléchir à ce pb de vitesse constante dans le cas d'une machine très lente ou d'un jeu ayant de grandes variations dans la vitesse d'affichage (images 3D dont la complexité est variable). Que se passe-t-il si tu "sautes" ta synchro écran ?
    Effectivement ce sont des questions trés intéressantes que je ne m'étais pas posées.
    Mais j'avoue que ça ne m'aide pas trop à comprendre la nécessité d'un timer dans le modèle. J'ai fait ce schéma histoire d'y voir un peu plus clair sur ces points que tu soulignes:


    J'ai supposé que le timer fonctionnait à 60Hz (indiqué par les barres verticales)
    Ce que j'appelle traitement, c'est tout ce qui n'est pas l'affichage en fait
    En gros on pourrait résumer à : bleu<=>vue et orange<=>modele

    Donc pour les machines lentes, j'avoue que je ne sais pas trop comment marche DirectX, donc j'ai mis les deux possibilités que je voyais. Donc dans ce cas, c'est évident que cela va "ramer", car il va manquer des images. Par contre je n'ai pas l'impression que ca change la vitesse du jeu.

    En revanche il est clair que la vitesse du jeu va être variable si la vitesse d'affichage est variable, étant donné que les données ne vont pas être mises à jour à intervalles réguliers (contrairement à l'affichage).
    Mais là je ne vois pas non plus l'avantage d'un timer dans le modèle, puisque cette fois-ci c'est un affichage irrégulier qui affiche un modèle "régulier".

    Aprés peut-être que les mises à jour de données ne sont jamais de durée variable? ou de façon beaucoup moins fréquente?
    On est pas sur non plus que le timer du modèle soit synchronisé avec l'écran, il y aurait donc également quelques variations de la vitesse de jeu a priori (enfin visuellement bien sur)
    Mais peut être que je passe à côté de quelquechose ou que mon schéma est trop simpliste voire faux?



    Citation Envoyé par benohite
    Cependant j'ai une petite question. Tu dis que directx permet de régler la synchronisation carte graphique/écran. Cela veut-il dire qu'il limite les rafraichissements à la fréquence donnée ?
    Je ne connais pas le fonctionnement interne de la gestion de la synchro écran. Je dirais que ça fait une sorte de sleep() dès qu'il prend la main, et ne rend la main que lorsque l'image est envoyée à l'écran (en synchro avec l'écran donc).
    Ce qui me fait dire ça c'est que je mesure le nombre d'images par seconde en incrémentant à chaque appel de la fonction d'affichage. Ce nombre est effectivement à 60. Donc à priori il y a autant de mise à jour du modèle que d'image affichées.

    L'idée de benohite de moduler le temps écoulé par une durée fixe pour mettre à jour les données est peut être la meilleure solution s'il y a moyen de connaître la fréquence d'affichage de l'écran. Dans ce cas là il y aurait une synchro "hardware" de l'affichage et une synchro "software" des mises à jour du modèle. Par contre il y a sûrement des effets de bords quelque part, il faudra que je creuse ça.



    Citation Envoyé par benohite
    Je pense même que tu peux descendre à 25 images par secondes, l'oeil humain n'étant pas capable à partir de cette fréquence de voir l'enchainnement d'image.
    Je ne saurais pas trop t'expliquer pourquoi, mais dans certaines conditions, directX rate un peu sa synchro avec l'écran et fait descendre le nombre d'image par seconde autour de 40-45, et ça affiche un comportement bizarre (visuellement).
    Mais peut être que le nombre d'img était irrégulier au sein d'une même seconde (genre les 30 première lors de la première 1/2 seconde et les 15 autres dans la deuxième 1/2 seconde), je ne peux pas te dire.

    Aprés il y a aussi le fait que les écrans cathodiques affichent des images entrelacées (affichage des lignes paires / impaires alternativement) ce qui nécessiterait d'envoyer 50 img/s pour obtenir effectivement du 25 img/s. Mais je dis ptet n'importe quoi là .
    Enfin mon écran est LCD donc ce n'est en tout cas pas ça qui pourrait expliquer les comportement bizarres.



    Citation Envoyé par benohite
    En ce qui concerne le timer, je comprends mieux maintenant l'idée, c'est plutôt astucieux.
    En fait tous les exemples du SDK de directX fonctionnent sur ce principe (mais de manière procédurale et non objet), moi je me suis contenté de reprendre le principe . La difficulté est de savoir si c'est applicable dans le cas d'un MVC, ou si c'est une logique purement procédurale...




    Voila, merci encore pour le temps que vous consacrez à ce sujet!


  16. #16
    Membre confirmé Avatar de ypicot
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    412
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 412
    Points : 579
    Points
    579
    Par défaut
    Citation Envoyé par tristan_m
    L'idée de benohite de moduler le temps écoulé par une durée fixe pour mettre à jour les données est peut être la meilleure solution s'il y a moyen de connaître la fréquence d'affichage de l'écran. Dans ce cas là il y aurait une synchro "hardware" de l'affichage et une synchro "software" des mises à jour du modèle.
    Je reviens avec mes gros sabots... et mon timer dans le modèle.
    Ton timer-modèle permet justement de te dire combien de temps s'est écoulé entre deux affichages, et donc d'ajuster le calcul de position suivant.

    Je ne saurais pas trop t'expliquer pourquoi, mais dans certaines conditions, directX rate un peu sa synchro avec l'écran et fait descendre le nombre d'image par seconde autour de 40-45, et ça affiche un comportement bizarre (visuellement).
    Et ca ne te fait pas réfléchir à la solution ci-dessus ?

    Voila, merci encore pour le temps que vous consacrez à ce sujet!
    Un pb de modèlisation mérite souvent un petit détour. Et honnêtement, ça change agréablement de "comant je fé ma rekete access" ou de "pourquoi mon prg il conpile pa"

    Yvan
    Une solution n'est valable que dans un contexte donné

  17. #17
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Points : 170
    Points
    170
    Par défaut
    Bonjour,

    Désolé de répondre si tardivement.

    J'ai fait pas mal de recherche sur ce problème de synchro affichage / maj des données.

    Je passe les détails d'implémentation, mais il semble en effet que si une synchronisation est effectuée, elle doit être faite sur la modification des données et non sur l'affichage.
    Les différentes solutions que j'ai trouvé sur le net parlent éventuellement d'une interpolation des trajectoires par la vue pour rendre les déplacement plus fluides lorsque la carte graphique le permet.

    Je pense que rien n'empêche de rajouter à ça le fait de limiter le nombre d'image affichées par seconde à la fréquence de rafraichissement de l'écran.

    Citation Envoyé par ypicot
    Et ca ne te fait pas réfléchir à la solution ci-dessus ?
    J'avoue que je n'arrive pas à bien distinguer s'il s'agit d'une vitesse non constante ou si c'est juste que le nombre d'img/s est insuffisant pour rendre l'affichage fluide.
    Enfin je serai fixé en synchronisant sur le modèle .



    Sinon je reviens un peu sur le sujet de départ, ça me semble bizarre d'avoir pour chaque objet une classe dans le modèle et sa classe correspondante dans la vue.
    Exemple sur mon schéma : Ball -> GraphicBall, Paddle->GraphicPaddle, etc...

    Il y a certes des différences entre les classes :
    • Les classes de la vue n'ont aucune notion de vitesse
    • Les positions dans le modèle et dans la vue sont dans des repères différents : modèle : unité de distances arbitraires, vue : coordonnées en pixels dans la fenêtre.
    • Surement d'autres trucs dont je me rappelle pas à l'instant.


    Mais ça me laisse quand même l'impression de multiplier le nombre de classe par 2, donc le nombre de fichiers d'autant...

    Il y a peut être une autre façon de faire?

    Merci d'avance!

  18. #18
    Membre confirmé Avatar de ypicot
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    412
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 412
    Points : 579
    Points
    579
    Par défaut
    Citation Envoyé par tristan_m
    Sinon je reviens un peu sur le sujet de départ, ça me semble bizarre d'avoir pour chaque objet une classe dans le modèle et sa classe correspondante dans la vue.
    Exemple sur mon schéma : Ball -> GraphicBall, Paddle->GraphicPaddle, etc...
    C'est souvent le cas, et c'est le résultat du découplage entre la logique (Ball) et l'affichage (GraphicBall). Imagine que tu doives à un moment ou à un autre changer ton interface (remplacer cela par des LED, par ex). Toute la logique "métier" (Ball) ne bougera pas.
    N'oublie pas qu'un des aspects fondamentaux des DP est la maitrise du changement. Dans une première version, les DP imposent beaucoup de code supplémentaire à écrire. L'utilité de ce code apparait notamment quand il faut modifier l'appli.

    Le "pb" est que ton projet est tout petit. En fait, tu es dans le cas que qqu'un qui, pour maitriser la conduite, veut prendre la voiture pour aller chercher le pain, à 50m de chez lui. Du fait des difficultés pour se garer, de la distance du parking, etc... il a l'impression (parfois exacte) qu'il marche plus quand il prend sa voiture, ce qui lui semble paradoxal.

    DesignPatternment,

    Yvan
    Une solution n'est valable que dans un contexte donné

  19. #19
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Points : 170
    Points
    170
    Par défaut
    Bonjour,

    Ca me rassure, car c'est vrai que j'avais un peu l'impression de mal m'y prendre (sans vraiment voir d'autre solution).

    Merci beaucoup à tous de m'avoir aidé!

    Maintenant il n'y a plus qu'à

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 28/11/2011, 17h44
  2. Réponses: 2
    Dernier message: 17/11/2007, 16h23
  3. Réponses: 11
    Dernier message: 28/08/2007, 12h06
  4. Réponses: 16
    Dernier message: 10/07/2007, 09h12
  5. Réponses: 2
    Dernier message: 04/05/2006, 23h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo