Worldedit
  Worldedit
Le site sur l'éditeur de warcraft 3 !
 
  FAQFAQ   RechercherRechercher   Liste des MembresListe des Membres    Groupes d'utilisateursGroupes d'utilisateurs   medals.php?sid=24b954589690eb631a11a9d212fe9834Médailles   S'enregistrerS'enregistrer 
 ProfilProfil   Se connecter pour vérifier ses messages privésSe connecter pour vérifier ses messages privés   ConnexionConnexion 
  FAQFAQ World Editor   UploadUploader une map ou une image    UploadAjouter sa map à l'annuaire   UploadConsulter l'annuaire

Problème avec instances de struct

 
Poster un nouveau sujet   Répondre au sujet    Worldedit Index du Forum -> Aide sur les déclencheurs
Voir le sujet précédent :: Voir le sujet suivant  
Auteur Message
 Ectelion
Membre reconnu


Inscrit le: 12 Nov 2011
Messages: 1062
Sujets: 107
Spécialité en worldedit: Inactif(Enfin presque)
Médailles: 1 (En savoir plus...)
Créateur d'unité (Quantité : 1)

MessagePosté le: 17/05/15 17:58    Sujet du message: Problème avec instances de struct Citer

Pour ceux qui veulent la petite histoire:
Secret:

Voilà, y'a un petit moment que je me suis remis au (*à l'apprentissage du*) vJASS, ayant quelques problèmes avec les stacks/queue malgré l'aide que m'a apporté Troll-Brain sur le sujet, j'avais du mal à réaliser des trucs MUI, donc j'ai décidé d'essayer avec un dot tout simple (mais tout de même un peu configurable) et là c'est le drame:


Lorsque la première instance de la struct est créée, ben j'ai droit à au moins 40 "Attempt to destroy a null instance of struct : MyStruct " mais l'effet indiquant que l'unité est censée subir est dot est bien présent.
Sauf qu'après, il se passe rien, et l'effet ne disparais jamais, ensuite, lorsque je relance la création d'une instance, j'ai pas de message autre que celui que j'ai mis qui indique les caractéristiques de la création et l'effet apparaît bien. Et il se passe rien quand j'attend. Donc j'ai besoin d'aide pour comprendre où ça bloque.

Le code:

Secret:

Jass:
library Structmultiinstancestest

    globals
        private boolean testmode = TRUE
        private integer Count = -1
        private timer Time = CreateTimer(  )
        private MyStruct array Instance
    endglobals
   
    struct MyStruct
        real damage
        real interval
        real lasting
        real cinterval
        effect model
        unit target
        unit caster
        integer count
       
        static method create takes unit t, unit c, real l, real i, real d, string m, string a returns MyStruct
            set Count = Count + 1
            set Instance[Count] = MyStruct.allocate()
            set Instance[Count].lasting = l
            set Instance[Count].caster = c
            set Instance[Count].damage = d
            set Instance[Count].interval = i
            set Instance[Count].cinterval = i
            set Instance[Count].target = t
            set Instance[Count].count = Count
            set Instance[Count].model = AddSpecialEffectTarget( m, t, a)
            if testmode == true then
                call BJDebugMsg("An Instance of Struct was created with the following parameters: |c00FF0000Target|r: " + GetUnitName(t) + " |c00FF0000Caster|r: " + GetUnitName(c) + " |c00FF0000Damage|r: " + R2S(d) + " |c00FF0000Duration|r: " + R2S(l) + " |c00FF0000Interval|r: " + R2S(i) )
            endif
            if Count == 0 then
                call TimerStart( Time, 0.03, TRUE, function MyStruct.Loop )
            endif
            return Instance[Count]
        endmethod
       
       
       
       private method action takes nothing returns nothing
            set this.cinterval = this.cinterval - 0.03
            if this.cinterval <= 0.00 then
                call UnitDamageTarget( this.caster, this.target, this.damage, FALSE, TRUE, ATTACK_TYPE_HERO, DAMAGE_TYPE_UNKNOWN, WEAPON_TYPE_WHOKNOWS )
                set this.cinterval = this.interval
            endif
            set this.lasting = this.lasting - 0.03
            if this.lasting <= 0.00 then
                call this.destroy()
            endif
        endmethod
       
       private static method Loop takes nothing returns nothing
            local integer i = -1
            loop
                exitwhen i == Count
                call Instance[i].action()
                set i = i + 1
            endloop
        endmethod
       
       private method destroy takes nothing returns nothing
            local integer i = 0
            local integer j = 0
            call DestroyEffect( this.model )
            set j = this.count + 1
            set this.target = null
            set this.caster = null
            set this.model = null
            call this.deallocate()
            if Count > 0 then
                set i = Count
                loop
                    exitwhen j == i
                        set Instance[j] = Instance[j + 1]
                        if testmode == TRUE then
                            call BJDebugMsg( "Instance n°|c00FF0000" + I2S(j+1) + " |rstored in Instance n°|c00FF0000" + I2S(j) )
                        endif
                        set j = j + 1
                endloop
            endif
            call Instance[Count].deallocate()
            set Count = Count - 1
            if Count == -1 then
                call PauseTimer( Time )
            endif
        endmethod
       
    endstruct

endlibrary


_________________
Inactif(Enfn presque)
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Tirlititi



Inscrit le: 21 Fév 2010
Messages: 1785
Sujets: 22
Spécialité en worldedit: La modestie
Médailles: 1 (En savoir plus...)
Grand mage créateur de sort (Quantité : 1)

MessagePosté le: 17/05/15 19:14    Sujet du message: Citer

Dans ta Loop, tu commences à -1 au lieu de commencer à 0. Normal que ça fasse un peu n'importe quoi.

Sinon, mets ce 0.03 dans une constante. C'est quand même pas terrible de le garder partout dans le code.
_________________
Warcraft III, c'était mieux avant. Y'avait des purs chefs-d'oeuvres du mapping !
Road Of Glory (par moi)
Casse-briques (par moi)
Temple de Glace (par moi)
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Ectelion
Membre reconnu


Inscrit le: 12 Nov 2011
Messages: 1062
Sujets: 107
Spécialité en worldedit: Inactif(Enfin presque)
Médailles: 1 (En savoir plus...)
Créateur d'unité (Quantité : 1)

MessagePosté le: 18/05/15 18:26    Sujet du message: Citer

J'ai fait quelques modifications et ça fonctionne sur une seule cible, sur plusieurs, le plus souvent ça marche, des fois y'en a une ou deux pour qui ça arrête de fonctionner (surement un problème dû à la réattribution des instances pour éviter les vides dans les boucles qui pompent de la mémoire.)

Pour ce qui est du debugging Le message qui dit que l'instance X + 1 est déplacée à l'instance X monte jusqu'à 766 alors que je fais généralement des tests avec 6 lancements simultanés tout au plus.
_________________
Inactif(Enfn presque)
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7143
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1) Grand mage créateur de sort (Quantité : 1)

MessagePosté le: 19/05/15 19:50    Sujet du message: Citer

Et il est où ce sujet déjà ?

Parce que visiblement tu n'as pas compris comment faire un tableau dynamique "simple" (on ne préserve pas l'ordre relatif des instances)
Y'a peut être des tutos sur le net si je n'arrive pas à me faire comprendre. (mais je veux bien réessayer)
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Ectelion
Membre reconnu


Inscrit le: 12 Nov 2011
Messages: 1062
Sujets: 107
Spécialité en worldedit: Inactif(Enfin presque)
Médailles: 1 (En savoir plus...)
Créateur d'unité (Quantité : 1)

MessagePosté le: 20/05/15 16:30    Sujet du message: Citer

Secret:

Troll-Brain a écrit:
Le plus simple et efficace je dirais serait d'utiliser une structure de donnée adaptée tel qu'une pile (stack) ou file d'attente (queue).
Structure qui doit être mise à jour au moment de la création/destruction d'une instance.
C'est relativement facile à implanter une fois le principe simple (sisi) compris.

Voici le principe :

Jass:

// variables globales nécessaires :

Spell array Stack
integer N = 0

struct Spell

   static method create takes nothing returns nothing
      local thistype this = thistype.allocate()

      set Stack[N] = this
      set N = N+1
   endmethod

   method loop takes nothing returns nothing
      ...
      local integer i = N
      local thistype instance

      loop
      exitwhen i == 0
      set i = i-1
         set instance = Stack[i]
         // si on doit détruire l'instance, réorganiser la pile :
         set N = N-1
         set Stack[i] = Stack[N]
         set Stack[N] = 0 // pas nécessaire, mais bon c'est pour le principe ...
      endloop

   endmethod

...

endstruct


Idéalement Stack et N devraient être des membres de la struct Spell, mais je n'ai pas voulu t'embrouiller avec une syntaxe différente (mais résultat en jass similaire).

Si tu veux comprendre comment réaliser une pile avec un tableau dynamique, je t'invite à le faire sur papier (le pseudo code que j'ai écrit).
Personnellement c'est comme cela que j'ai compris et surtout retenu le fonctionnement.
Ça et puis une recherche sur le net à ce sujet bien entendu.

EDIT : Au fait, même si cette structure au départ est une pile, ca ne le reste pas forcément.
Étant donné que l'on ne conserve pas l'ordre des éléments lors de la destruction d'un élément, mais ici on s'en carre l'oignon, de l'ordre relatif des instances.
Si on voudrait conserver l'ordre, une liste chaînée (linked list) serait plus appropriée.
Mais ceci est une autre histoire qui vous sera (peut être) contée une autre fois.

EDIT 2 : Hmm nan on ne peut pas utiliser ce type de structure donnée en exemple de la sorte.
On ne peut pas à la fois boucler et détruire un élément de la sorte.
Il manque quelque chose, j'y réfléchirai tout à l'heure à tête reposée, je vais au dodo.

EDITH PIAF : Ça devrait être bon, j'avais simplement fait une erreur, je décrémentais N trop tard.



C'est vrai qu'il est pas question de conserver l'ordre dans ce que tu dis :/ mais la grosse différence vient du fait que moi je préferais décrémenter dans la méthode destroy plutôt que dans le loop. Après, j'ai pas trouvé de tutos sur les linked lists sur THW ni sur Wc3c, donc faudrait que je voie sur Thehelper. Et sinon, j'imagine que je peux aussi demander ici Razz .
_________________
Inactif(Enfn presque)
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7143
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Grand mage créateur de sort (Quantité : 1) Rédacteur de tuto #3 (Quantité : 1)

MessagePosté le: 20/05/15 17:33    Sujet du message: Citer

Citation:
C'est vrai qu'il est pas question de conserver l'ordre dans ce que tu dis :/


En quoi est ce un problème ici ?!

Citation:
mais la grosse différence vient du fait que moi je préferais décrémenter dans la méthode destroy plutôt que dans le loop.


T'es sérieux là ?!
Si vraiment tu veux le faire, rien ne t'empêche de créer une method destroy qui fait la décrémentation (faudrait que i soit accessible ou passé en argument de destroy, mais je ne sais plus si une method destroy peut avoir des arguments ou non)

Citation:
Après, j'ai pas trouvé de tutos sur les linked lists sur THW ni sur Wc3c, donc faudrait que je voie sur Thehelper. Et sinon, j'imagine que je peux aussi demander ici Razz .


Oui je suppose.
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Ectelion
Membre reconnu


Inscrit le: 12 Nov 2011
Messages: 1062
Sujets: 107
Spécialité en worldedit: Inactif(Enfin presque)
Médailles: 1 (En savoir plus...)
Créateur d'unité (Quantité : 1)

MessagePosté le: 20/05/15 18:55    Sujet du message: Citer

J'ai vérifié et destroy n'a pas le droit de prendre des arguments.
Donc faut que je le fasse dans le loop. Du coup c'est plus tellement une question de choix.
Sauf si n'importe quelle method qui contient un deallocate peut être considérée comme un équivalent à destroy.
_________________
Inactif(Enfn presque)
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7143
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1) Grand mage créateur de sort (Quantité : 1)

MessagePosté le: 20/05/15 19:23    Sujet du message: Citer

Si tu ne déclares pas de method destroy, elle est tout de même créée et appelle la method deallocate.
Donc même si tu ne créés pas de method destroy tu peux appeler cette method.
Mais le réel intérêt est de pouvoir réécrire destroy, sinon deallocate fait le job.

Quand je parlais de rendre i accessible, c'était une histoire de portée, il ne faut pas que ca soit une variable local quoi, tu peux aussi passer par une method/function intermédiaire.
Ou juste gérer la destruction dans la loop Razz
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 kungfu-sheep
Anomalie floodiforme


Inscrit le: 14 Avr 2011
Messages: 1846
Sujets: 119
Spécialité en worldedit: fonctions paramétriques, équation de mouvement.


MessagePosté le: 09/07/15 15:44    Sujet du message: Citer

Sinon rien ne t'empeche de creer une methode orderDestroy, lui mettre des attribus et en faire ce que tu veux (et appeler deallocate ou destroy dedans).

Tu peux meme creer une library List et te faire toute une API de gestion de liste comme en C Smile (et la publier tant qu'a faire, mais je suis sur que ca existe deja)
_________________
22:27:43<Seiraw> Bah y a deux genre de personnes
22:27:57<Seiraw> les soumis et les soumises
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé Envoyer l'e-mail
 Sapeur-Goblin
Floodeur prématuré


Inscrit le: 14 Oct 2009
Messages: 719
Sujets: 40
Spécialité en worldedit: Les bugs
Médailles: 1 (En savoir plus...)
Créateur d'unité (Quantité : 1)

MessagePosté le: 09/07/15 21:43    Sujet du message: Citer

OH MON DIEU !!!
Fulldragon est toujours parmi nous !!!!
Hey broo Smile
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 kungfu-sheep
Anomalie floodiforme


Inscrit le: 14 Avr 2011
Messages: 1846
Sujets: 119
Spécialité en worldedit: fonctions paramétriques, équation de mouvement.


MessagePosté le: 10/07/15 10:02    Sujet du message: Citer

coucou Smile
_________________
22:27:43<Seiraw> Bah y a deux genre de personnes
22:27:57<Seiraw> les soumis et les soumises
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé Envoyer l'e-mail
Montrer les messages depuis:   
Poster un nouveau sujet   Répondre au sujet    Worldedit Index du Forum -> Aide sur les déclencheurs Toutes les heures sont au format GMT + 1 Heure
Page 1 sur 1

 
Sauter vers:  
Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum


Powered by phpBB © 2001, 2005 phpBB Group
Traduction par : phpBB-fr.com