récupérer le nom d'une liste

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

récupérer le nom d'une liste

Message par blendman »

Salut

Dans un de mes programmes j'utilise plusieurs listes pour afficher certains sprites (c'est un éditeur de map, pour mon jeu 3Arks).
Je peux donc ajouter des sprites dans certaines listes, en fonctions d'une variable globale nommée "type".
Si type = 0 ->j'ajoute des sols donc je travaille sur la liste sol()
si type = 1 -> j'ajoute des décors, donc je travaille sur la liste decor()
etc..

Donc, je voudrais connaitre le nom de la liste afin de la modifier, sans devoir faire un select/case avec la variable type comme paramètre.
Car j'ai beaucoup de fonction de modification en fonction de ces listes, et ça me fait beaucoup de select/case :).

J'aimerai donc faire quelque chose comme :

Code : Tout sélectionner

NewList sol()
NewList decor()

type.b = 1

Select type
Case 0
  AddElement(sol())
  currentlist = sol()
Case 1
  AddElement(decor())
  currentlist = decor()
EndSelect

; puis plus tard
Debug ListSize(currentlist)
clearlist(currentlist)
Évidemment, là, ça ne marche pas. Mais ce que j'essaie de faire c'est de récupérer le nom de la liste, son identifitant ou quelque chose qui me permette de connaitre la liste courante (qui change en fonction de la variable "type").

Je ne sais pas si c'est faisable.

Merci de vos informations.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: récupérer le nom d'une liste

Message par Backup »

chaque "element" en purebasic dispose d'une adresse

un ordinateur fonctionne (enfin la Ram) ,avec des numéros d'adresse
la pile aussi
donc, chaque "chose" est référencé par une adresse

d’où l'utilisation du caractère "@" qui retourne l'adresse

par exemple d'un variable

par exemple :

Toto.s="coucou"

ici l'adresse de Toto.s sera égale a debug @toto.s

et pour connaitre le contenu de Toto.s soit ("coucou")
il faudra faire
debug PeekS(@toto.s)

pourquoi je parle de ça ?

ben pour te dire que les "list" n’échappent pas a ce fonctionnement :)

Code : Tout sélectionner

NewList Toto()

AddElement(Toto())
toto() = 1

resetlist( toto())
FirstElement(toto())


debug  "le contenu de toto est :"+ str(toto())

debug "l'adresse de la list est :"+str(@toto()) +" c'est une adresse unique , qui n'appartient qu'a elle !"
adresse_identifiant_la_liste.l=@toto()
debug "le contenu du premier element est :"+str( peekl(adresse_identifiant_la_liste.l))

; EPB

tout dans purebasic est "indexé" par une adresse mémoire
cette adresse reste attribuée a chaque chose , jusqu’à la fin du programme

donc si tu met dans une variable l'adresse de ta liste A , tu pourra facilement
savoir de quelle liste il s'agit :)
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: récupérer le nom d'une liste

Message par Ar-S »

j'ai essayé de partir sur des structures .. j'ai foiré ^^
Les peek paraissent effectivement appropriés
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: récupérer le nom d'une liste

Message par blendman »

Merci pour l'explication :).
Je comprends comment cela marche. On peut donc avoir facilement accès aux informations de la liste.
Mais pour la modifier, j'imagine que ce n'est pas possible si ?
Car j'ai essayé du coup avec un peekL de modifier une liste(), mais je n'ai pas réussi.

j'imagine qu'il n'est pas possible de faire des choses comme :
clearlist(), addelement() ou listesize() à partir de l'adresse mémoire de "adresse_identifiant_la_liste" ?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: récupérer le nom d'une liste

Message par Backup »

blendman a écrit : Mais pour la modifier, j'imagine que ce n'est pas possible si ?
Car j'ai essayé du coup avec un peekL de modifier une liste(), mais je n'ai pas réussi.
pour ecrire en memoire, c'est les fonctions PokeL etc... (voir librairie Memory dans la doc)
j'imagine qu'il n'est pas possible de faire des choses comme :
clearlist(), addelement() ou listesize() à partir de l'adresse mémoire de "adresse_identifiant_la_liste" ?
ben si !
rien ne t'empeche d'utiliser les fonctions existantes

regarde ceci :

Code : Tout sélectionner

NewList Toto()

AddElement(Toto())
toto() = 1

resetlist( toto())
FirstElement(toto())


debug  "le contenu de toto est :"+ str(toto())

debug "l'adresse de la list est :"+str(@toto()) +" c'est une adresse unique , qui n'appartient qu'a elle !"
adresse_identifiant_la_liste.l=@toto()
debug "le contenu du premier element est :"+str( peekl(adresse_identifiant_la_liste.l))

; on va changer le contenu de la list

pokeL(adresse_identifiant_la_liste.l,255)

debug "le contenu du premier element  (que nous venons de changer.) est :"+str( peekl(adresse_identifiant_la_liste.l))

; autre façon de verifier
FirstElement(toto())
debug toto()

; EPB




peek et poke permettent respectivement de lire et d'ecrire a un emplacement memoire
cette emplacement peut etre l'adresse de la liste
mais rien ne t'mpeche d'utiliser les fonction standards

d'ailleurs le fonctions standards comme
"Previouselement()" ,"nextelement"
renvoie une valeur de retour

cette valeur est justement l'adresse memoire ou se situe l'element en question

la doc dit :
Valeur de retour

La valeur renvoyée par cette commande peut être utilisée pour déterminer si l'élément précédent existe ou pas (il n'existera pas si vous êtes au début de la liste). Si l'élément précédent existe, cette commande renvoie une valeur différente de zéro. Si l'élément précédent n'existe pas alors la valeur renvoyée sera zéro. Pour programmeurs expérimentés:
La valeur renvoyée par cette commande est un pointeur vers les données de l'élément précédent ou zéro si l'élément précédent n'existe pas.

kwandjeen
Messages : 204
Inscription : dim. 16/juil./2006 21:44

Re: récupérer le nom d'une liste

Message par kwandjeen »

Tu peux utiliser les pointeurs

Code : Tout sélectionner

Structure valeur
  val.l
EndStructure

NewList ma_liste.l()

AddElement(ma_liste())
ma_liste() = 1

AddElement(ma_liste())
ma_liste() = 23

AddElement(ma_liste())
ma_liste() = 453

ResetList(ma_liste())
FirstElement(ma_liste())

*origin = @ma_liste() ; on récupère le premier élément de la liste

*adresse_element.valeur=*origin
Debug *adresse_element\val

*adresse_element\val = 47 ; on modifie le premier élément
Debug *adresse_element\val

index = 1 ; on sélectionne le deuxième élément
*adresse_element.valeur = *origin + (32*index)
Debug *adresse_element\val

index = 2 ;on sélectionne le troisième élément
*adresse_element.valeur = *origin + (32*index)
Debug *adresse_element\val

ForEach(ma_liste())
  Debug ma_liste()  
Next
Par contre pour le clearlist() et addelement() faut voir avec un programmeur un peu plus chevronné, moi je vois pas.

Sinon pourquoi tu ne passes ton sélect en macro

Code : Tout sélectionner

NewList sol()
NewList decor()
#sol=0
#decor=1

Macro mod_liste(type,valeur)
  Select type
    Case #sol
      AddElement(sol())
      sol() = valeur
    Case #decor
      AddElement(decor())
      decor() = valeur
  EndSelect
EndMacro

;on modifie le sol par exemple
mod_liste(#sol,253)

Debug sol()
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: récupérer le nom d'une liste

Message par graph100 »

non mais si j'ai bien compris les posts de BlendMan, ce qu'il veux faire, c'est gérer plusieurs listes différentes avec un seul pointeur

du genre :

Code : Tout sélectionner

NewList Test()
AddElement(Test())
Test() = 50

NewList AutreTest()
AddElement(AutreTest())
AutreTest() = 25
AddElement(AutreTest())
AutreTest() = 12

Define *pointeur.Long

a = #True

If a = #True
  *pointeur = @Test()
Else
  *pointeur = @AutreTest()
EndIf

Debug ListSize(*pointeur)
Ça ne marchera pas car le paramètre attendu est une liste.
Le seul moyen d'accéder à des propriétés de liste à partir de l'adresse d'un élément de la liste est de lire la mémoire la ou sont stockées les infos de la liste.
Mais c'est foireux car bien sur, on a pas les spécif de PB pour ses listes !!

Hier j'ai cherché à trouver ou sont stockés les 1er, dernier élément ainsi que l'élément courant, ça se trouve, mais on ne peux pas les modifier sans risque de problème dans le fonctionnement de la liste.

Pour ce que tu veux faire BlendMan, je te conseille de choisir une autre méthode. Je ne sais pas trop comment tu gère ton système derrière le bout de code que tu nous a montré, mais si tu peux parcourir les éléments un à un (si il n'y en a pas trop) tu peux tout mettre dans la même liste par exemple, et avec une structure, tu met un champ de structure pour le type de l'élément.

Ce que tu seras obligé de faire, c'est de diviser ton code en 2 partie, une pour chaque type (pour chaque liste)

sinon voila des macro qui ne servent pas bien à grand chose :

Code : Tout sélectionner

#OFFSET_DATA = - 3 * SizeOf(Integer)
#OFFSET_ADRESSESTOCKEE =  - 2 * SizeOf(Integer)
#OFFSET_LASTELEMENT =  - 39 * SizeOf(Integer)

; obj est l'adresse d'un élément d'une liste
; ces macro retournent les adresses mémoire du premier, dernier élément, et de l'élément courant

Macro GetFirstElement_EX(obj)
	PeekI(PeekI(obj + #OFFSET_DATA) - 40 * SizeOf(Integer)) + 2 * SizeOf(Integer)
EndMacro

Macro GetLastElement_EX(obj)
	PeekI(PeekI(obj + #OFFSET_DATA) - 39 * SizeOf(Integer)) + 2 * SizeOf(Integer)
EndMacro

Macro GetCurrentElement_EX(obj)
	PeekI(PeekI(obj + #OFFSET_DATA) - 38 * SizeOf(Integer)) + 2 * SizeOf(Integer)
EndMacro
Et faut faire gaffe avec ça. Je n'ai pas encore testé avec des listes structurée ou des listes dans des structures (apparemment il y a un problème pour les listes dans les structures ;'(
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: récupérer le nom d'une liste

Message par blendman »

Dobro : merci pour les infos, ça pourrait m'être utile ;)

kwandjeen : en fait, mon select est déjà en procédure. Mais je voulais éviter la répétition des cases :

Code : Tout sélectionner

Select type
  Case #sol
    AddElement(sol())
    sol() = valeur
  Case #decor
    AddElement(decor())
    decor() = valeur
  Case #pnj
    AddElement(pnj())
    pnj() = valeur
  Case #fx
    ;....
  Case #fleur
    ; ....
EndSelect
Comme j'utilise une procédure pour addelement(), clearlist, et aussi sur les modifs des elements, je voulais trouver une méthode pour éviter d'avoir pleind e select/case pour chaque transformation de list.
non mais si j'ai bien compris les posts de BlendMan, ce qu'il veux faire, c'est gérer plusieurs listes différentes avec un seul pointeur
oui, en fait c'est à peu près ça : gérer environ 6 ou 7 listes, avec 3 ou 4 procédures, mais éviter si possible les select /case pour le choix de la liste (et donc de l'objet sélectionné).

Mais bon, peut être que finalement il vaut mieux utiliser le select/case, c'est beaucoup plus simple :D.

Merci pour vos réponses.
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Re: récupérer le nom d'une liste

Message par GeBonet »

Salut,
Pourquoi pas utiliser un tableau ??? Avec les noms associé aux pointeurs

Code : Tout sélectionner

Dim MesListe.s(10)

Dim sol.s(10)
Dim Terre.s(10)
Dim Decor.s(10)
Dim Objet.s(10)
Dim Maison.s(10)

Dim Table.s(10)

MesListe(1)=Str(@sol.s())+"Sol()"
MesListe(2)=Str(@Terre())+"Terre()"
MesListe(3)=Str(@Decor())+"Decor()"
MesListe(4)=Str(@Objet())+"Objet()"
MesListe(5)=Str(@Maison())+"Maison()"

Terre(1)="Venus"
Terre(2)="Terre"
Terre(3)="Mars"


Sol(1)="Soleil"
Sol(2)="Sirius"
Sol(3)="Polaire"

Decor(1)="Cuisine"
Decor(2)="Salon"
Decor(3)="Chambre"

; MesListe(6)=..."Jardin()"
; MesListe(7)=..."
; MesListe(8)=..."
; MesListe(9)=..."
; Etc... jusque ???
;MesListes(900)="LesAutres()"
;
; Activer un des choix pour l'exemple...  
;
; MonChoix$="Decor()"
MonChoix$="Sol()"
; MonChoix$="Terre()"
;
;  Puis une simple boucle ... 
;
For i=1 To 5
  If FindString(MesListe(i),MonChoix$,2)
    Select i
       Case i      ; Ou case se transforme en "on i"
        *pointeur=Val(MesListe(i))
        Dim Table.s(10)   ; Nettoyage de la liste...
       ;
        ; Ici Table devient le tableau dépendant de i c'est a dire de la ma liste. 
        Table()=*pointeur ; Ou une table unique qui prend l'identité de celle pointé par "i"
        OK=1:Break 
    EndSelect
  EndIf
Next i
If OK=1            ;      Trouvé alors la "Table()" devient celle choisie....
  Debug @Table(1)
  Debug Table(1)
  Debug Table(2)
  Debug Table(3)
EndIf
Voilà, une solution ??? Mais bon, ce n'est qu'une idée... :wink:
Gerhard
Windows 7 et Windows 8.1 Pb 5.0 jusque 5.24 Lts 64 et 5.3 (64)/b]
“Ceux qui rêvent éveillés ont conscience de mille choses qui échappent à ceux qui ne rêvent qu’endormis.”
-Edgar Allan Poe-
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: récupérer le nom d'une liste

Message par graph100 »

^^ bonne idée :)

une petite amélioration ( Il ne faut pas oublier que le type de tout les tableaux doit être le même ) :

Code : Tout sélectionner

Global NewMap MesListe()
Global Dim Table.s(0)

Procedure AssignTable(MonChoix$)
	If FindMapElement(MesListe(), MonChoix$)
		*pointeur = MesListe()
		
		Taille_tableau = PeekL(*pointeur - 2 * SizeOf(Integer)) - 1 ; on lit la taille de la table avec son adresse
		Dim Table.s(Taille_tableau)   ; Nettoyage de la liste...
		
		; Ici Table devient le tableau dépendant de ma liste. 
		Table() = *pointeur ; Ou une table unique qui prend l'identité de celle pointé par "i"
		
		ProcedureReturn #True
	EndIf
	
	ProcedureReturn #False
EndProcedure


Dim sol.s(10)
Dim Terre.s(10)
Dim Decor.s(10)
Dim Objet.s(10)
Dim Maison.s(10)

MesListe("Sol") = @sol()
MesListe("Terre") = @Terre()
MesListe("Decor") = @Decor()
MesListe("Objet") = @Objet()
MesListe("Maison") = @Maison()


Terre(1)="Venus"
Terre(2)="Terre"
Terre(3)="Mars"
Terre(4)="Pluton"


Sol(1)="Soleil"
Sol(2)="Sirius"
Sol(3)="Polaire"

Decor(1)="Cuisine"
Decor(2)="Salon"
Decor(3)="Chambre"


; Activer un des choix pour l'exemple...  


If AssignTable("Sol")
	Debug Table(1)
	Debug Table(2)
	Debug Table(3)
	Debug ""
EndIf

If AssignTable("Terre")
	Debug Table(1)
	Debug Table(2)
	Debug Table(3)
	Debug Table(4)
	Debug ""
EndIf

If AssignTable("Decor")
	Debug Table(1)
	Debug Table(2)
	Debug Table(3)
	Debug Table(4)
	Debug ""
EndIf
J'ai utilisé une procedure car je voulais une valeur de retour, mais avec une macro ça marche aussi, et ce doit être plus rapide.
Enfin, c'est une commande qui n'est pas appelée souvent normalement !
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Re: récupérer le nom d'une liste

Message par GeBonet »

Très bien pour l'amélioration... :lol:
Et bien sur aussi que NewMap est un plus.
L'utilisation des adresses directement... Bref plus efficace !

Moi, c'était juste pour l'idée générale...
Je n'ai pas spécialement cherché à optimiser :wink:
Merci,
Windows 7 et Windows 8.1 Pb 5.0 jusque 5.24 Lts 64 et 5.3 (64)/b]
“Ceux qui rêvent éveillés ont conscience de mille choses qui échappent à ceux qui ne rêvent qu’endormis.”
-Edgar Allan Poe-
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: récupérer le nom d'une liste

Message par graph100 »

dommage qu'on ne puisse pas faire d'alias de liste !!! et de map et d'array (tableau).
Je veux dire de vrai alias ! comme avec les variables
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Répondre