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

Développement 2D, 3D et Jeux Discussion :

Implémenter un graphe de scène en Javascript


Sujet :

Développement 2D, 3D et Jeux

  1. #1
    Nouveau membre du Club Avatar de sylvain230
    Homme Profil pro
    Orléans
    Inscrit en
    Mai 2008
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Orléans
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 234
    Points : 30
    Points
    30
    Par défaut Implémenter un graphe de scène en Javascript
    Bonjour,

    Je cherche à implémenter un graphe de scène en Javascript mais j'ai du mal à trouver une bonne définition, savoir ce qu'il y a dans geode, node ...

    Je ne sais pas non plus si c'est possible en Javascript !

    Pourriez vous m'aider ? Merci

  2. #2
    Membre confirmé

    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 311
    Points : 545
    Points
    545
    Par défaut
    Salut,

    Créer un arbre en JavaScript est tout à fait possible, le plus simple est d’ajouter une propriétée Childs et Parent a un objet pour l’insérer dans un arbre
    un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    function Attach(parent,child)
    {
        if(parent.Childs==undefined)
            parent.Childs = [ child ];
        else
           parent.Childs.push(child);
     
        child.Parent = parent;
    }
     
    var earth = 
    {   Name : "Earth",
        Matrix : [ 1, 0, 0, 0,
                   0, 1, 0, 0,
                   0, 0, 1, 0,
                   0, 0, 0, 1],
    };
    var moon =
    {   Name : "Moon",
        Matrix : [ 1, 0, 0, 384467,
                   0, 1, 0, 0,
                   0, 0, 1, 0,
                   0, 0, 0, 1],
    };
     
    Attach(earth,moon);
     
    alert(earth.Childs[0].Name); //"Moon"
    alert(moon.Parent.Name); // "Earth"
    Si tu cherche à étudier l’architecture d’un excellent moteur 3D en Javascript, je te conseil de jeter un œil a O3D de google

  3. #3
    Nouveau membre du Club Avatar de sylvain230
    Homme Profil pro
    Orléans
    Inscrit en
    Mai 2008
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Orléans
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 234
    Points : 30
    Points
    30
    Par défaut
    En effet, O3D a l'air d'être pas mal foutu. Je vais essayer de comprendre un peu les détails et "mettre les mains dans le cambouis" lol pour développer mon propre moteur.

  4. #4
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Faire un moteur de type scénographe est évidemment tout à fait possible en Javascript ; je me suis d'ailleurs amusé à en faire un pour développer des jeux sur la freebox (cf. ma signature).

    Les quelques idées de base:

    - si tu est un minimum familier avec d'autres langages orientés objet (genre C++, Java), je te conseille de passer par une librairie additionnelle pour te donner un moyen d'écrire du code 'simple et limpide' (pour qui a déjà touché aux langages sus-cités) avec les principales fonctionnalités 'objet' à portée de main: constructeurs, héritage, ... Perso je me suis tourné vers Base.js.

    - l'architecture des classes est assez simple au premier abord. Exemple:

    * un singleton qui va s'occuper de tout ce qui concerne le contexte (chargement, canvas, gestion du temps, ...). Appelons le 'Stage'.

    * un singleton pour gérer tout ce qui touche aux inputs (clavier, souris, ...).

    * une classe 'Scene' qui sera la classe de base qui contient le graphe de scène et les animations en cours dans la scène. Le Stage exécute et affiche une et une seule scène à la fois.

    * une classe générique représentant un élément dans le graphe (noeud ou feuille) avec les caractéristiques qui y sont rattachées, genre: position, taille, visibilité, alpha. Appelons là 'Node'.

    * une classe dérivant de 'Node' qui représente un noeud dans le graphe, et qui est donc capable de contenir des enfants (typiquement avec une liste chainées). Appelons la 'GroupNode'.

    * des classes dérivant de 'Node' qui représentent les feuilles de ton graphe et qui -elles- sont capables de se dessiner: une BitmapNode, TextNode, RectangleNode, LineNode, ... ; chacune a en plus des propriétés communes (position, taille, ...) des paramètres spécifiques (url de l'image, couleur du rectangle, ...).

    Voilà pour la partie 'graphe de scène' ; tu poruras ensuite raffiner:

    - avec des objets graphiques plus complexes, par exemple une classe 'Button' qui dérive de GroupNode et qui est composé d'une image de fond (le bouton), et d'une texte par au dessus (le label).

    - avec la gestion des animations et des événements dans le temps.

    - etc...

    Mais comme le dit p3ga5e, il est plus qu'opportun de s'inspirer des libs existantes, de s'en faire deux ou trois pour comprendre leur fonctionnement et leur architecture interne. Ca permet non seulement de voir ce qui est commun à toutes les libs et ce qui peut être amené à varier en fonction des sensibilités propres et des besoins de leurs auteurs.

    Perso si tu connais un peu Java, je te conseille de jeter un oeil du côté de la façon dont est organisée la lib PulpCore que j'ai un peu pratiqué et dont je me suis directement inspiré pour ma propre lib JS. Pour moi, elle a une approche extrêmement intéressante pour abstraire la notion de 'propriété' associées aux sprites (couleur, alpha, position, visibilité, ...) pour ensuite pouvoir les réutiliser de façon très élégante et générique dans les animations.

    My 2 cents.

  5. #5
    Nouveau membre du Club Avatar de sylvain230
    Homme Profil pro
    Orléans
    Inscrit en
    Mai 2008
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Orléans
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 234
    Points : 30
    Points
    30
    Par défaut
    Merci pour toutes ces informations.

    Pour l'instant, j'ai créé 3 classes :

    - WebGL_Node qui va plutôt gérer tout ce qui est arbre. J'ai pensé que dans un noeud, un a un objet et une transformation( 1 matrice). Chaque noeud possède 1 identifiant.
    Au début, je pensais à grouper Node et GroupNode mais je ne sais pas si c'est une bonne idée. De plus, est ce que seul les feuilles sont capable de dessiner ? Si c'est le cas ma structure ne va pas.

    - WebGL_Context qui serait la classe singleton dont tu parles. Elle spécifie la taille du canvas et le navigateur a utilisé ainsi que le contexte selon le navigateur

    - WebGL_Object qui implémenterait les fonctionnalités de base. Construire un cube, une sphère ...

    Je ne comprend pas trop l'utilisation de Base.js. En effet,dans les classes par prototypage, toutes les méthodes sont séparées et forment plusieurs blocks alors que dans l'autre méthode tout est réunit dans un seul block.

    Du coup, cela serait plus lourd dans des appels de fonction de toujours appeler toute la classe alors que avec prototype on appele juste la méthode de la classe qui nous intéresse non ?

  6. #6
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par sylvain230 Voir le message
    Au début, je pensais à grouper Node et GroupNode mais je ne sais pas si c'est une bonne idée. De plus, est ce que seul les feuilles sont capable de dessiner ? Si c'est le cas ma structure ne va pas.
    C'est sujet à débat ; pour moi le groupe et les feuilles sont des fonctionalités séparées. Mais ça peut se discuter.

    toutes les méthodes sont séparées et forment plusieurs blocks alors que dans l'autre méthode tout est réunit dans un seul block
    C'est juste que les blocs distincts sont passés à Base.js au moment de la définition de la classe en les regroupant dans une collection de blocs pour ne faire qu'un appel à 'extend' pour que le code soit plus joli. Ca n'empêche que le résultat est le même.

    Du coup, cela serait plus lourd dans des appels de fonction de toujours appeler toute la classe alors que avec prototype on appele juste la méthode de la classe qui nous intéresse non ?
    Non, c'est juste une couche syntaxique ; au niveau perfs pour les accès aux méthodes / fonctions c'est totalement équivalent.

    Il y a (peut-être) juste une légère perte pour deux opérations beaucoup moins récurrentes: l'instanciation (new) et la conso mémoire ; à vérifier mais pour moi c'est plutôt négligeable,alors que je suis pourtant dans un environnement extrêmement contraint (un MIPS à 200MHz et quelques dizaines de Mo de RAM pour faire tourner l'ensemble du système).

    Après, comme dit précédemment je partage juste cette lib qui m'a plu parce qu'elle correspondait bien à mon approche du JS: une grosse expérience en C++ et Java et très peu en JS. Mais c'est pas pour ça que tu dois te sentir obligé de l'utiliser (et ce n'est sûrement pas la seule qui existe non plus).

  7. #7
    Nouveau membre du Club Avatar de sylvain230
    Homme Profil pro
    Orléans
    Inscrit en
    Mai 2008
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Orléans
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 234
    Points : 30
    Points
    30
    Par défaut
    J'ai fait la classe GroupNode. J'aimerai te demander ton avis, si c'est un "truc" comme ca qu'il faut que je fasse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    /**
     * @author sylvain
     */
    var WebGL_GroupNode = Base.extend({
     
    ////////////////////////////////////////////////////////////////////
    //	Constructeur de la classe Node
    //
    //
    //
    ////////////////////////////////////////////////////////////////////    
    	constructor : function() {
     
     
    		this.children = [];
     
    	},
     
    ////////////////////////////////////////////////////////////////////
    //	Méthode pour ajouter un objet à la liste chainée GroupNode
    //	du node correspondant
    //	Entrée : l'enfant
    //	Sortie : le GroupNode mis à jour
    ////////////////////////////////////////////////////////////////////    
    	addChild : function(child) {
     
    		var c = this.children.push(child);
                    return c;
     
    	},
     
    ////////////////////////////////////////////////////////////////////
    //      Méthode pour supprimer un élément d'enfant
    //
    //
    //
    ////////////////////////////////////////////////////////////////////
    	removeChildren : function() {
     
    		var children = this.children;
                    if(children.length !=0) {                   
                        this.children.length = 0;
                    }
     
    	},
     
     
            removeChild : function(child) {
     
                for(var i = 0  ; i < this.children.length ; i++) {
                    if(this.children[i]=== child) {
                        this.children.splice(i,1);
                    }
                }
     
            },
     
    ////////////////////////////////////////////////////////////////////
    //      Méthode pour supprimer un enfant
    //
    //
    //
    ////////////////////////////////////////////////////////////////////
    	indexOfChild : function(id) {
     
                this.children.split(id,1);
     
    	}
     
     
     
    });
    tu en penses quoi ?

  8. #8
    Membre confirmé

    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 311
    Points : 545
    Points
    545
    Par défaut
    Je ne suis pas tout a fait d’accord avec l’approche POO quant on travaille sur une platform JavaScript, car tous ces héritages et polymorphisme a un cout, sur la maintenance du code, la flexibilité et peut être aussi sur les performances.

    De ce que j’ai constaté, en Javascript la reflexivité ne coute rien contrairement a des langages comme C#. n'est pas plus rapide que Il existe une autre approche, en utilisant le prototypage pour construire un abre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Object.prototype.AddAsChild = function(child)
    {
        if(this.Children==undefined)
            this.Children = [ child ];
        else
           this.Children.push(child);
     
        child.Parent = this;
    };
    Cela a l’avantage d’ajouter n’importe quel type d’objet en tant que nœud ou feuille d’un arbre, même des objets WebGL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var root = "Hello !";
    var child = [  1, 0, 0, 0,
                   0, 1, 0, 0,
                   0, 0, 1, 0,
                   0, 0, 0, 1]; 
     
     
    root.AddAsChild(child);
    alert(child.Parent) // "Hello !"
    Ensuite il est intéressant de pouvoir déterminer si un objet implémente une interface, pour cela pas besoin de d’une mécanique d’héritage lourde, la réflexivité est largement suffisante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    /***
     * return true if this object implements the interface 
     */
    Object.prototype.Implements = function(interface)
    { 
        for(var property in interface)
        {
            if( typeof interface[property] != "string")
                continue;
     
            if(this[property]==undefined || typeof this[property] != interface[property] )
                return false;
        }
        return true;
    };
     
    /**
     * Interface IRender
     */
    var IRender = 
    {
         Matrix : "object",
         Render : "function"
    };
     
    var Shape = 
    {   Name : "House",
        Matrix : [ 1, 0, 0, 0,
                   0, 1, 0, 0,
                   0, 0, 1, 0,
                   0, 0, 0, 1],
     
    };
     
    alert(Shape.Implements(IRender));// false : il manque la methode Render!
    Shape.Render = function()
    {
      alert('Rendering ' + this.Name);
    };
     
    alert(Shape.Implements(IRender)); // true
    Voila c’été juste pour dire que l’on se passe tres bien d’une approche POO en JavaScript.

  9. #9
    screetch
    Invité(e)
    Par défaut
    Nouknouk: pourquoi deux singletons?

  10. #10
    Nouveau membre du Club Avatar de sylvain230
    Homme Profil pro
    Orléans
    Inscrit en
    Mai 2008
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Orléans
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 234
    Points : 30
    Points
    30
    Par défaut
    Je suis embêté là.
    Quelle est la meilleure méthode d'implémentation en Javascript ?

    Voici une autre idée d'implémentation en utilisant Prototype.js

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    /**
     * @author sylvain
     */
     
    ////////////////////////////////////////////////////////////////////
    //	Constructeur de la classe Node
    //
    //
    //
    ////////////////////////////////////////////////////////////////////    
    var WebGL_GroupNode = Class.create( WebGL_Node, {
     
     
     
     
     
        ////////////////////////////////////////////////////////////////////
        //	Méthode pour ajouter un objet à la liste chainée GroupNode
        //	du node correspondant
        //	Entrée : l'enfant
        //	Sortie : le GroupNode mis à jour
        ////////////////////////////////////////////////////////////////////
        addChild : function(child) {
     
            var c = this.children.push(child);
            return c;
     
        },
     
        ////////////////////////////////////////////////////////////////////
        //      Méthode pour supprimer un élément d'enfant
        //
        //
        //
        ////////////////////////////////////////////////////////////////////
        removeChildren : function() {
     
            var children = this.children;
            if(children.length != 0) {
                this.children.length = 0;
            }
     
        },
     
     
        removeChild : function(child) {
     
            for(var i = 0  ; i < this.children.length ; i++) {
                if(this.children[i]=== child) {
                    this.children.splice(i,1);
                }
            }
     
        },
     
        ////////////////////////////////////////////////////////////////////
        //      Méthode pour supprimer un enfant
        //
        //
        //
        ////////////////////////////////////////////////////////////////////
        indexOfChild : function(id) {
     
            this.children.split(id,1);
     
        }
     
     
     
    });

  11. #11
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    tous ces héritages et polymorphisme a un cout, sur la maintenance du code, la flexibilité et peut être aussi sur les performances.
    Tout comme devoir prendre du temps pour apprendre une nouvelle syntaxe, approche, façon de faire, etc...

    Question perfs, ça n'a pas réellement d'incidence car les appels aux fonctions une fois l'objet créé sont totalement identiques en interne. A nouveau, la seule différence concerne la surcharge uniquement au moment de l'instanciation. Donc quand tu fais ton 'new MonObjet(params)'. Rien d'autre. Base ne fait que fournir une surcouche pour transformer le code écrit sous 'sa syntaxe' vers le Javascript 'normal'.

    Quant à l'approche POO non flexible et maintenable, je te laisse la responsabilité de ces allégations.

    Citation Envoyé par p3ga5e Voir le message
    Voila c’été juste pour dire que l’on se passe tres bien d’une approche POO en JavaScript.
    On dévie du débat initial et j'ai peur qu'on pourrisse le topic de ce pauvre Sylvain.

    Pour conclure là-dessus en un mot comme en 100: je n'ai jamais dit que c'était la solution idéale et encore moins universelle. Juste qu'elle pouvait éventuellement convenir pour qui est habitué à une approche POO (par exemple du fait d'une pratique antérieure de Java ou C++). Rien de plus.

  12. #12
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par sylvain230 Voir le message
    this.children = [];
    Pars plutôt sur une collection implémentée au moyen d'une liste chaînée plutôt qu'un tableau.

    Les tableaux sont uniquement intéressants quand on doit accéder à un élément par son index, mais vont être peu performants quand on va vouloir enlever un élément au milieu du tableau.

  13. #13
    Nouveau membre du Club Avatar de sylvain230
    Homme Profil pro
    Orléans
    Inscrit en
    Mai 2008
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Orléans
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 234
    Points : 30
    Points
    30
    Par défaut
    Pourtant l'objet Array de Javascript possède une méthode slice avec en paramètre l'identifiant et le nombre de cases à supprimer pour éviter les trous.

    En fait depuis tout à l'heure je cherche à faire une liste chainée en Javascript mais comme il n'y a pas de pointeurs je ne vois pas trop comment faire. Je cherchais une alternative.
    La librairie osg de Cédric Pinson et o3d n'utilisent pas de liste chainée mais après je ne sais pas si les algorithmes sont efficace.

  14. #14
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par sylvain230 Voir le message
    Pourtant l'objet Array de Javascript possède une méthode slice
    C'est pas parce qu'une méthode toute faite existe qu'elle rend l'utilisation des tableaux la solution la plus efficace.

    En fait depuis tout à l'heure je cherche à faire une liste chainée en Javascript mais comme il n'y a pas de pointeurs je ne vois pas trop comment faire. Je cherchais une alternative.
    Un code brut de mon crû ; probablement très loin d'être parfait, mais ça te donne une idée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
     
    ListImpl = {
        constructor: function(itPrevNextPrefix) {
            this.prefix = itPrevNextPrefix;
            this.prefixNext = this.prefix+"_next";
            this.prefixPrev = this.prefix+"_prev";
            this.first = null;
            this.last = null;
        },
     
        append: function(obj) {
            if (obj[this.prefixNext] || obj[this.prefixPrev]) {
                return null;
            }
     
            obj[this.prefixNext] = null;
            obj[this.prefixPrev] = this.last;
            if (this.last != null) {
                this.last[this.prefixNext] = obj;
                obj[this.prefixPrev] = this.last;
            }
            if (this.first == null) {
                this.first = obj;
            }
            this.last = obj;
            return obj;
        },
        prepend: function(obj) {
            if (obj[this.prefixNext] || obj[this.prefixPrev]) {
                return null;
            }
     
            obj[this.prefixPrev] = null;
            obj[this.prefixNext] = this.first;
            if (this.first != null) {
                this.first[this.prefixPrev] = obj;
            }
            if (this.last == null) {
                this.last = obj;
            }
            this.first = obj;
            return obj;
        },
        remove: function(obj) {
            if (obj[this.prefixNext] != null) {
                obj[this.prefixNext][this.prefixPrev] = obj[this.prefixPrev];
            }
            else {
                this.last = obj[this.prefixPrev];
            }
            if (obj[this.prefixPrev] != null) {
                obj[this.prefixPrev][this.prefixNext] = obj[this.prefixNext];
            }
            else {
                this.first = obj[this.prefixNext];
            }
            obj[this.prefixPrev] = null;
            obj[this.prefixNext] = null;
            return obj;
        },
        clear: function() {
          while ( ! this.isEmpty()) {
              this.takeFirst();
          }
        },
        takeFirst: function() {
            if (this.first == null) {
                return null;
            }
            else if (this.first[this.prefixNext] == null) {
                var obj = this.first;
                this.first = null;
                this.last = null;
                return obj;
            }
            else {
                var obj = this.first;
                obj[this.prefixNext][this.prefixPrev] = null;
                this.first = obj[this.prefixNext];
                obj[this.prefixNext] = null;
                return obj;
            }
        },
        takeLast: function() {
            if (this.last == null) {
                return null;
            }
            else if (this.last[this.prefixPrev] == null) {
                var obj = this.last;
                this.first = null;
                this.last = null;
                return obj;
            }
            else {
                var obj = this.last;
                obj[this.prefixPrev][this.prefixNext] = null;
                this.last = obj[this.prefixPrev];
                obj[this.prefixPrev] = null;
                return obj;
            }
        },
        size: function(obj) {
            var i = 0;
            var it = this.first;
            while (it != null) {
                i++;
                it = it[this.prefixNext];
            }
            return i;
        },
        contains: function(obj) {
            var it = this.first;
            while (it != null) {
                if (it == obj) {
                    return true;
                }
                it = it[this.prefixNext];
            }
            return false;
        },
        isEmpty: function(obj) {
            return (this.first == null);
        },
        previous: function(obj) {
            return obj[this.prefixPrev];
        },
        next: function(obj) {
            return (obj) ? obj[this.prefixNext] : this.first;
        },
    };
     
    List = Base.extend(ListImpl);
    Et son emploi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    var l = new List("nomListe");
    l.append("monObjet");
    l.prepend("monAutreObjet");
     
    for (var it = l.first ; it != null ; it = l.next(it)) {
        alert(it);
    }
    "nomListe" permet d'avoir des objets qui appartiennent à plusieurs listes en même temps. Chaque liste doit avoir un nom unique.

  15. #15
    Nouveau membre du Club Avatar de sylvain230
    Homme Profil pro
    Orléans
    Inscrit en
    Mai 2008
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Orléans
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 234
    Points : 30
    Points
    30
    Par défaut
    oui il est bien ton algo je comprend le principe.
    Il y a un truc qui me gène.

    Que veut dire cette ligne ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    obj[this.prefixNext][this.prefixPrev] = obj[this.prefixPrev];

  16. #16
    screetch
    Invité(e)
    Par défaut
    si l'ordre n'est pas important un array est beaucoup plus efficace qu'une liste chainée.
    Pour effacer au milieu, il suffit dans ce cas d'echanger l'objet a enlever avec celui a la fin, puis de retirer la fin.

    sinon, nouknouk, pourquoi des singletons?

  17. #17
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par sylvain230 Voir le message
    Que veut dire cette ligne ?
    - "this.prefixNext" est une chaine de caractère qui représente le nom de l'attribut de obj qui contient une référence vers l'objet suivant.

    - même chose pour "this.prefixPrev" sauf qu'il est le nom de l'attribut qui pointe sur l'élément précédent.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    obj[this.prefixNext][this.prefixPrev] = obj[this.prefixPrev];
    Est donc équivalent à quelque chose comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    obj.suivant.precedent = objet.precedent
    Sauf que dans mon implémentation les noms des attributs 'suivant' et 'precedent' sont pas fixes, mais dynmaiques et choisi de façon unique pour chaque liste (le fameux "nomListe" du post précédent) ; cela permet que deux listes qui contiennent un même objet aillent pas trifouiller dans les 'suivant' et 'precedent' de l'autre.

  18. #18
    Nouveau membre du Club Avatar de sylvain230
    Homme Profil pro
    Orléans
    Inscrit en
    Mai 2008
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Orléans
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 234
    Points : 30
    Points
    30
    Par défaut
    Mais l'ordre est important ici.
    On ne peut pas afficher un objet dans la scène avant d'avoir fait les bonnes transformations.

  19. #19
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    C'est une implémentation d'une liste chaînée ; l'ordre est respecté (et heureusement: je me sers de ces itérateurs pour des listes d'objets 2D dans les GroupNodes pour lesquels l'ordre d'affichage est tout aussi important).

    Concrètement c'est une partie de l'opération de suppression d'un élément d'une liste (méthode remove): (voir image en pj)

    La suppression consiste à mettre à jour ce qui est en rouge dans le schéma. Il y a deux pointeurs à mettre à jour et la ligne de code que tu as donnée correspond à la moitié du boulot, ie. la flêche rouge qui part de 8 et va vers 3.

    Concrètement, cette ligne dit: obj étant 15, il dit à 8 que son nouveau précédent n'est plus obj (15), mais le précédent de obj, à savoir 3.
    Images attachées Images attachées  

  20. #20
    Membre confirmé

    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 311
    Points : 545
    Points
    545
    Par défaut
    Désolé d'avance pour le hors sujet ^^
    Tout comme devoir prendre du temps pour apprendre une nouvelle syntaxe, approche, façon de faire, etc...
    pour moi prendre le temps d'apprendre les spécificités d'un language n'est pas une perte de temps mais un investissement !

    C'est juste que les developpeurs semble sous-estimer la liberté qu'offre le faite de s'affranchir de la declaration des meta-données (je parle de notion de class).

    je rencontre ce probleme avec tous mes stagiaires Développeurs, ils semblent formatés pour appliquer des design-paterns apprit par coeurs de maniere mecanique ... c'est juste que cela me désole ...

    Pour en revenir au sujet de la discutions , je tient a préciser que le type tableau en javascript est un gros FAKE !
    en realité un tableau est un objet javascript comme un autre !
    pour preuve
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typeof [] == "object" // true
    en realité un type Array est une specialisation d'object :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var tab = [ 0 ,1, 2, 3];
     for(var property in tab)
     {
    	alert(property == tab[property]);
     }
    il n'existe aucune difference entre les indices d'un tableau et les proprietés d'un objet !

    C'est pourquoi j'insiste sur le fait d'apprendre les notions d'un langage, un tableau en javascript ne permet aucune optimisation !
    ne croyez pas alligner vos données en memoire en utilisant un tableau en Javascript.

    tous fois l'approche liste chainées sur les fils d'un noeud peut apporter un gain de performance,car un parcour itératif semble plus performant qu'un parcours recursif en javasprtipt ( cela est difficelement mesurable ) !

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Graphe de scène Javascript
    Par sylvain230 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 17/05/2011, 17h18
  2. Réponses: 0
    Dernier message: 18/09/2009, 12h43
  3. Type d'algorithme dans un graphe de scène
    Par FunkyTech dans le forum Moteurs 3D
    Réponses: 1
    Dernier message: 27/01/2008, 02h20
  4. [Débutant] Implémentation de graphe
    Par nanath02 dans le forum Langage
    Réponses: 4
    Dernier message: 17/04/2007, 17h17
  5. Implémenter une succession de scènes
    Par alex6891 dans le forum Développement 2D, 3D et Jeux
    Réponses: 17
    Dernier message: 16/05/2006, 16h13

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